From e4ff7d9bb96ec8d840144288c801841ab4a78016 Mon Sep 17 00:00:00 2001 From: Sean Owen Date: Wed, 30 Jul 2014 12:18:04 +0100 Subject: [PATCH] Issue #197 : handle escaped backslash preceding terminator --- .../zxing/client/result/ResultParser.java | 20 +++++++++++++++---- .../result/WifiParsedResultTestCase.java | 5 +++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/google/zxing/client/result/ResultParser.java b/core/src/main/java/com/google/zxing/client/result/ResultParser.java index 7cc1d4862..c86f1f7fc 100644 --- a/core/src/main/java/com/google/zxing/client/result/ResultParser.java +++ b/core/src/main/java/com/google/zxing/client/result/ResultParser.java @@ -116,7 +116,7 @@ public abstract class ResultParser { } protected static String unescapeBackslash(String escaped) { - int backslash = escaped.indexOf((int) '\\'); + int backslash = escaped.indexOf('\\'); if (backslash < 0) { return escaped; } @@ -208,13 +208,13 @@ public abstract class ResultParser { int start = i; // Found the start of a match here boolean more = true; while (more) { - i = rawText.indexOf((int) endChar, i); + i = rawText.indexOf(endChar, i); if (i < 0) { // No terminating end character? uh, done. Set i such that loop terminates and break i = rawText.length(); more = false; - } else if (rawText.charAt(i - 1) == '\\') { - // semicolon was escaped so continue + } else if (countPrecedingBackslashes(rawText, i) % 2 != 0) { + // semicolon was escaped (odd count of preceding backslashes) so continue i++; } else { // found a match @@ -239,6 +239,18 @@ public abstract class ResultParser { return matches.toArray(new String[matches.size()]); } + private static int countPrecedingBackslashes(CharSequence s, int pos) { + int count = 0; + for (int i = pos - 1; i >= 0; i--) { + if (s.charAt(i) == '\\') { + count++; + } else { + break; + } + } + return count; + } + static String matchSinglePrefixedField(String prefix, String rawText, char endChar, boolean trim) { String[] matches = matchPrefixedField(prefix, rawText, endChar, trim); return matches == null ? null : matches[0]; diff --git a/core/src/test/java/com/google/zxing/client/result/WifiParsedResultTestCase.java b/core/src/test/java/com/google/zxing/client/result/WifiParsedResultTestCase.java index bfad97102..43fc2540f 100644 --- a/core/src/test/java/com/google/zxing/client/result/WifiParsedResultTestCase.java +++ b/core/src/test/java/com/google/zxing/client/result/WifiParsedResultTestCase.java @@ -64,6 +64,11 @@ public final class WifiParsedResultTestCase extends Assert { doTest("WIFI:S:TenChars;P:hello\\:there;T:WEP;;", "TenChars", "hello:there", "WEP"); } + @Test + public void testEscape() { + doTest("WIFI:T:WPA;S:test;P:my_password\\\\;;", "test", "my_password\\", "WPA"); + } + /** * Given the string contents for the barcode, check that it matches our expectations */