Fix #150 again by moving towards a more RFC 2822-compliant definition of valid syntax
[zxing.git] / core / src / com / google / zxing / client / result / EmailDoCoMoResultParser.java
index bfa10c2..b4eb70e 100644 (file)
@@ -23,16 +23,19 @@ import com.google.zxing.Result;
  *
  * Supported keys: TO, SUB, BODY
  *
- * @author srowen@google.com (Sean Owen)
+ * @author Sean Owen
  */
 final class EmailDoCoMoResultParser extends AbstractDoCoMoResultParser {
 
+  private static final char[] ATEXT_SYMBOLS =
+      {'@','.','!','#','$','%','&','\'','*','+','-','/','=','?','^','_','`','{','|','}','~'};
+
   public static EmailAddressParsedResult parse(Result result) {
     String rawText = result.getText();
     if (rawText == null || !rawText.startsWith("MATMSG:")) {
       return null;
     }
-    String[] rawTo = matchDoCoMoPrefixedField("TO:", rawText);
+    String[] rawTo = matchDoCoMoPrefixedField("TO:", rawText, true);
     if (rawTo == null) {
       return null;
     }
@@ -40,23 +43,45 @@ final class EmailDoCoMoResultParser extends AbstractDoCoMoResultParser {
     if (!isBasicallyValidEmailAddress(to)) {
       return null;
     }
-    String subject = matchSingleDoCoMoPrefixedField("SUB:", rawText);
-    String body = matchSingleDoCoMoPrefixedField("BODY:", rawText);
+    String subject = matchSingleDoCoMoPrefixedField("SUB:", rawText, false);
+    String body = matchSingleDoCoMoPrefixedField("BODY:", rawText, false);
     return new EmailAddressParsedResult(to, subject, body, "mailto:" + to);
   }
 
   /**
    * This implements only the most basic checking for an email address's validity -- that it contains
-   * an '@' and a '.' somewhere after that, and that it contains no space.
-   * We want to generally be lenient here since this class is only intended to encapsulate what's
+   * an '@' contains no characters disallowed by RFC 2822. This is an overly lenient definition of
+   * validity. We want to generally be lenient here since this class is only intended to encapsulate what's
    * in a barcode, not "judge" it.
    */
   static boolean isBasicallyValidEmailAddress(String email) {
     if (email == null) {
       return false;
     }
-    int atIndex = email.indexOf('@');
-    return atIndex >= 0 && email.indexOf('.') > atIndex && email.indexOf(' ') < 0;
+    boolean atFound = false;
+    for (int i = 0; i < email.length(); i++) {
+      char c = email.charAt(i);
+      if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9') &&
+          !isAtextSymbol(c)) {
+        return false;
+      }
+      if (c == '@') {
+        if (atFound) {
+          return false;
+        }
+        atFound = true;
+      }
+    }
+    return atFound;
+  }
+
+  private static boolean isAtextSymbol(char c) {
+    for (int i = 0; i < ATEXT_SYMBOLS.length; i++) {
+      if (c == ATEXT_SYMBOLS[i]) {
+        return true;
+      }
+    }
+    return false;
   }
 
 }
\ No newline at end of file