diff options
5 files changed, 60 insertions, 6 deletions
diff --git a/files/ant/build.xml b/files/ant/build.xml index b65be95..9f413d1 100644 --- a/files/ant/build.xml +++ b/files/ant/build.xml @@ -1265,7 +1265,7 @@ </extra-instrument-args> </run-tests-helper> - <echo level="info">Settting permission to download the coverage file...</echo> + <echo level="info">Setting permission to download the coverage file...</echo> <exec executable="${adb}" failonerror="true"> <arg line="${adb.device.arg}" /> <arg value="shell" /> diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/StringFormatDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/StringFormatDetector.java index 90ae0cf..670f095 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/StringFormatDetector.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/StringFormatDetector.java @@ -156,11 +156,17 @@ public class StringFormatDetector extends ResourceXmlDetector implements Detecto private Map<String, List<Pair<Handle, String>>> mFormatStrings; /** - * List of strings that contain percents that aren't formatting strings; these + * Map of strings that contain percents that aren't formatting strings; these * should not be passed to String.format. */ private Map<String, Handle> mNotFormatStrings = new HashMap<String, Handle>(); + /** + * Set of strings that have an unknown format such as date formatting; we should not + * flag these as invalid when used from a String#format call + */ + private Set<String> mIgnoreStrings; + /** Constructs a new {@link StringFormatDetector} check */ public StringFormatDetector() { } @@ -275,11 +281,11 @@ public class StringFormatDetector extends ResourceXmlDetector implements Detecto String conversion = matcher.group(6); int conversionClass = getConversionClass(conversion.charAt(0)); if (conversionClass == CONVERSION_CLASS_UNKNOWN || matcher.group(5) != null) { - if (!mNotFormatStrings.containsKey(name)) { - Handle handle = context.parser.createLocationHandle(context, element); - handle.setClientData(element); - mNotFormatStrings.put(name, handle); + if (mIgnoreStrings == null) { + mIgnoreStrings = new HashSet<String>(); } + mIgnoreStrings.add(name); + // Don't process any other strings here; some of them could // accidentally look like a string, e.g. "%H" is a hash code conversion // in String.format (and hour in Time formatting). @@ -287,6 +293,7 @@ public class StringFormatDetector extends ResourceXmlDetector implements Detecto } found = true; + j++; // Ensure that when we process a "%%" we don't separately check the second % } } @@ -730,6 +737,10 @@ public class StringFormatDetector extends ResourceXmlDetector implements Detecto int max = 0; while (true) { if (matcher.find(index)) { + if ("%".equals(matcher.group(6))) { //$NON-NLS-1$ + index = matcher.end(); + continue; + } int matchStart = matcher.start(); // Make sure this is not an escaped '%' for (; prevIndex < matchStart; prevIndex++) { @@ -899,6 +910,10 @@ public class StringFormatDetector extends ResourceXmlDetector implements Detecto return; } + if (mIgnoreStrings != null && mIgnoreStrings.contains(name)) { + return; + } + if (mNotFormatStrings.containsKey(name)) { Handle handle = mNotFormatStrings.get(name); Object clientData = handle.getClientData(); diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/StringFormatDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/StringFormatDetectorTest.java index 5995a8c..a49955b 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/StringFormatDetectorTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/StringFormatDetectorTest.java @@ -154,6 +154,15 @@ public class StringFormatDetectorTest extends AbstractCheckTest { lintProject("res/values/formatstrings3.xml")); } + public void testIssue39758() throws Exception { + assertEquals( + "No warnings.", + + lintProject( + "res/values/formatstrings4.xml", + "src/test/pkg/StringFormatActivity2.java.txt=>src/test/pkg/StringFormatActivity2.java")); + } + public void testIsLocaleSpecific() throws Exception { assertFalse(isLocaleSpecific("")); assertFalse(isLocaleSpecific("Hello World!")); diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values/formatstrings4.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values/formatstrings4.xml new file mode 100644 index 0000000..c4e245e --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values/formatstrings4.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="formattest1">"%1$s, %2$tF %3$tR"</string> + <string name="formattest2">%1$s, %2$tF %3$tR</string> + <string name="formattest3">"Note: Start point RPM differs by %d%%.\n\n"</string> + <string name="formattest4">Note: Start point RPM differs by %d%%.\n\n</string> + <string name="formattest5">%s%% c</string> + <string name="formattest6">%s%% </string> + <string name="formattest7">%1$s%%</string> +</resources> diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/src/test/pkg/StringFormatActivity2.java.txt b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/src/test/pkg/StringFormatActivity2.java.txt new file mode 100644 index 0000000..c039dce --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/src/test/pkg/StringFormatActivity2.java.txt @@ -0,0 +1,20 @@ +package test.pkg; + +import android.app.Activity; +import android.os.Bundle; + +public class StringFormatActivity2 extends Activity { + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + String target = "World"; + getResources().getString(R.string.formattest1, "hello"); + getResources().getString(R.string.formattest2, "hello"); + getResources().getString(R.string.formattest3, 42); + getResources().getString(R.string.formattest4, 42); + getResources().getString(R.string.formattest5, "hello"); + getResources().getString(R.string.formattest6, "hello"); + getResources().getString(R.string.formattest7, "hello"); + } +} |