Loading java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java +44 −26 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ import java.util.Arrays; public class KeySpecParser { private static final boolean DEBUG = LatinImeLogger.sDBG; private static final int MAX_STRING_REFERENCE_INDIRECTION = 10; // Constants for parsing. private static int COMMA = ','; private static final char ESCAPE_CHAR = '\\'; Loading Loading @@ -274,13 +276,23 @@ public class KeySpecParser { return resId; } private static String resolveStringResource(String text, Resources res, int packageNameResId) { private static String resolveStringResource(String rawText, Resources res, int packageNameResId) { int level = 0; String text = rawText; StringBuilder sb; do { level++; if (level >= MAX_STRING_REFERENCE_INDIRECTION) { throw new RuntimeException("too many @string/resource indirection: " + text); } final int size = text.length(); if (size < PREFIX_STRING.length()) { return text; } StringBuilder sb = null; sb = null; for (int pos = 0; pos < size; pos++) { final char c = text.charAt(pos); if (c == PREFIX_AT && text.startsWith(PREFIX_STRING, pos)) { Loading @@ -302,7 +314,13 @@ public class KeySpecParser { sb.append(c); } } return (sb == null) ? text : sb.toString(); if (sb != null) { text = sb.toString(); } } while (sb != null); return text; } private static int searchResourceNameEnd(String text, int start) { Loading tests/res/values/donottranslate.xml +3 −0 Original line number Diff line number Diff line Loading @@ -50,4 +50,7 @@ <string name="multiple_labels_with_escape_surrounded_by_spaces">" \\abc , d\\ef , gh\\i "</string> <string name="multiple_labels_with_comma_and_escape">"ab\\\\,d\\\\\\,,g\\,i"</string> <string name="multiple_labels_with_comma_and_escape_surrounded_by_spaces">" ab\\\\ , d\\\\\\, , g\\,i "</string> <string name="indirect_string">@string/multiple_chars</string> <string name="indirect_string_with_literal">x,@string/multiple_chars,y</string> <string name="infinite_indirection">infinite,@string/infinite_indirection,loop</string> </resources> tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserCsvTests.java +12 −0 Original line number Diff line number Diff line Loading @@ -288,4 +288,16 @@ public class KeySpecParserCsvTests extends AndroidTestCase { "abc@string/multiple_labels", "abcabc", "def", "ghi"); } public void testParseIndirectReference() { assertTextArray("Indirect", "@string/indirect_string", "a", "b", "c"); assertTextArray("Indirect with literal", "1,@string/indirect_string_with_literal,2", "1", "x", "a", "b", "c", "y", "2"); } public void testParseInfiniteIndirectReference() { assertError("Infinite indirection", "1,@string/infinite_indirection,2", "1", "infinite", "<infinite>", "loop", "2"); } } Loading
java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java +44 −26 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ import java.util.Arrays; public class KeySpecParser { private static final boolean DEBUG = LatinImeLogger.sDBG; private static final int MAX_STRING_REFERENCE_INDIRECTION = 10; // Constants for parsing. private static int COMMA = ','; private static final char ESCAPE_CHAR = '\\'; Loading Loading @@ -274,13 +276,23 @@ public class KeySpecParser { return resId; } private static String resolveStringResource(String text, Resources res, int packageNameResId) { private static String resolveStringResource(String rawText, Resources res, int packageNameResId) { int level = 0; String text = rawText; StringBuilder sb; do { level++; if (level >= MAX_STRING_REFERENCE_INDIRECTION) { throw new RuntimeException("too many @string/resource indirection: " + text); } final int size = text.length(); if (size < PREFIX_STRING.length()) { return text; } StringBuilder sb = null; sb = null; for (int pos = 0; pos < size; pos++) { final char c = text.charAt(pos); if (c == PREFIX_AT && text.startsWith(PREFIX_STRING, pos)) { Loading @@ -302,7 +314,13 @@ public class KeySpecParser { sb.append(c); } } return (sb == null) ? text : sb.toString(); if (sb != null) { text = sb.toString(); } } while (sb != null); return text; } private static int searchResourceNameEnd(String text, int start) { Loading
tests/res/values/donottranslate.xml +3 −0 Original line number Diff line number Diff line Loading @@ -50,4 +50,7 @@ <string name="multiple_labels_with_escape_surrounded_by_spaces">" \\abc , d\\ef , gh\\i "</string> <string name="multiple_labels_with_comma_and_escape">"ab\\\\,d\\\\\\,,g\\,i"</string> <string name="multiple_labels_with_comma_and_escape_surrounded_by_spaces">" ab\\\\ , d\\\\\\, , g\\,i "</string> <string name="indirect_string">@string/multiple_chars</string> <string name="indirect_string_with_literal">x,@string/multiple_chars,y</string> <string name="infinite_indirection">infinite,@string/infinite_indirection,loop</string> </resources>
tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserCsvTests.java +12 −0 Original line number Diff line number Diff line Loading @@ -288,4 +288,16 @@ public class KeySpecParserCsvTests extends AndroidTestCase { "abc@string/multiple_labels", "abcabc", "def", "ghi"); } public void testParseIndirectReference() { assertTextArray("Indirect", "@string/indirect_string", "a", "b", "c"); assertTextArray("Indirect with literal", "1,@string/indirect_string_with_literal,2", "1", "x", "a", "b", "c", "y", "2"); } public void testParseInfiniteIndirectReference() { assertError("Infinite indirection", "1,@string/infinite_indirection,2", "1", "infinite", "<infinite>", "loop", "2"); } }