All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.android.tools.lint.checks.PropertyFileDetector Maven / Gradle / Ivy

/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.tools.lint.checks;

import static com.android.SdkConstants.DOT_PROPERTIES;

import com.android.annotations.NonNull;
import com.android.tools.lint.detector.api.Category;
import com.android.tools.lint.detector.api.Context;
import com.android.tools.lint.detector.api.Detector;
import com.android.tools.lint.detector.api.Implementation;
import com.android.tools.lint.detector.api.Issue;
import com.android.tools.lint.detector.api.Location;
import com.android.tools.lint.detector.api.Scope;
import com.android.tools.lint.detector.api.Severity;
import com.google.common.base.Splitter;

import java.io.File;
import java.util.Iterator;

/**
 * Check for errors in .property files
 * 

* TODO: Warn about bad paths like sdk properties with ' in the path, or suffix of " " etc */ public class PropertyFileDetector extends Detector { /** Property file not escaped */ public static final Issue ISSUE = Issue.create( "PropertyEscape", //$NON-NLS-1$ "Incorrect property escapes", "Looks for property files with incorrect paths", "All backslashes and colons in .property files must be escaped with " + "a backslash (\\). This means that when writing a Windows path, you " + "must escape the file separators, so the path \\My\\Files should be " + "written as `key=\\\\My\\\\Files.`", Category.CORRECTNESS, 6, Severity.ERROR, new Implementation( PropertyFileDetector.class, Scope.PROPERTY_SCOPE)); /** Constructs a new {@link PropertyFileDetector} */ public PropertyFileDetector() { } @Override public boolean appliesTo(@NonNull Context context, @NonNull File file) { return file.getPath().endsWith(DOT_PROPERTIES); } @Override public void run(@NonNull Context context) { String contents = context.getContents(); if (contents == null) { return; } int offset = 0; Iterator iterator = Splitter.on('\n').split(contents).iterator(); String line; for (; iterator.hasNext(); offset += line.length() + 1) { line = iterator.next(); if (line.startsWith("#") || line.startsWith(" ")) { continue; } if (line.indexOf('\\') == -1) { continue; } int valueStart = line.indexOf('=') + 1; if (valueStart == 0) { continue; } if (line.indexOf('\\') == -1) { continue; } checkLine(context, contents, line, offset, valueStart); } } private static void checkLine(@NonNull Context context, @NonNull String contents, @NonNull String line, int offset, int valueStart) { boolean escaped = false; int hadUnescapedColon = -1; boolean hadNonPathEscape = false; StringBuilder path = new StringBuilder(); for (int i = valueStart; i < line.length(); i++) { char c = line.charAt(i); if (c == '\\') { escaped = !escaped; if (escaped) { path.append(c); } } else { if (escaped) { if (c != ':') { hadNonPathEscape = true; } } else if (c == ':' && hadUnescapedColon == -1) { hadUnescapedColon = i; } escaped = false; path.append(c); } } String pathString = path.toString(); String key = line.substring(0, valueStart); if ((hadNonPathEscape || hadUnescapedColon != -1) && key.endsWith(".dir=") || new File(pathString).exists()) { if (hadNonPathEscape) { String escapedPath = pathString.replace("\\", "\\\\"); String message = "Windows file separators (\\) must be escaped (\\\\); use " + escapedPath; int startOffset = offset + valueStart; int endOffset = offset + line.length(); Location location = Location.create(context.file, contents, startOffset, endOffset); context.report(ISSUE, location, message, null); } if (hadUnescapedColon != -1) { String message = "Colon (:) must be escaped in .property files"; int startOffset = offset + hadUnescapedColon; Location location = Location.create(context.file, contents, startOffset, startOffset + 1); context.report(ISSUE, location, message, null); } } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy