Bug 1629842 - fix some cases of wrong email address parsing. r=pmorris DONTBUILD
authorMagnus Melin <mkmelin+mozilla@iki.fi>
Wed, 22 Apr 2020 13:48:52 +0300
changeset 38905 542fb0021c53f7d462c07f07419d80664c4f0e33
parent 38904 71abc0529d32fe645c1a2299c39c2f4732f76015
child 38906 7e71b9fa21f277a9a50d104010be3c188c69367a
push id401
push userclokep@gmail.com
push dateMon, 01 Jun 2020 20:41:59 +0000
reviewerspmorris
bugs1629842
Bug 1629842 - fix some cases of wrong email address parsing. r=pmorris DONTBUILD
mailnews/mime/src/MimeJSComponents.jsm
mailnews/mime/test/unit/test_nsIMsgHeaderParser4.js
--- a/mailnews/mime/src/MimeJSComponents.jsm
+++ b/mailnews/mime/src/MimeJSComponents.jsm
@@ -432,36 +432,27 @@ MimeAddressParser.prototype = {
    * Construct a single email address from an |name <local@domain>| token.
    * @param {string} aInput - a string to be parsed to a mailbox object.
    * @returns {msgIAddressObject} the mailbox parsed from the input.
    */
   _makeSingleAddress(aInput) {
     // If the whole string is within quotes, unquote it first.
     aInput = aInput.trim().replace(/^"(.*)"$/, "$1");
 
-    if (aInput.includes("<")) {
-      // We don't want to look for the address within quotes.
-      let cleanedInput = aInput.replace(/".+"/g, "").trim();
-      if (!cleanedInput) {
-        // all quoted
-        return this.makeMailboxObject(aInput, "");
-      }
-      if (!/<.+>/.test(cleanedInput)) {
-        // no proper address
-        return this.makeMailboxObject(aInput, "");
-      }
-      let addr = cleanedInput.slice(
-        cleanedInput.indexOf("<") + 1,
-        cleanedInput.indexOf(">")
-      );
+    if (/<.*>/.test(aInput)) {
+      // We don't want to look for the address within quotes, so first remove
+      // all quoted strings containing angle chars.
+      let cleanedInput = aInput.replace(/".*[<>]+.*"/g, "");
+
+      // Extract the address from within the quotes.
+      let addrMatch = cleanedInput.match(/<([^><]*)>/);
+
+      let addr = addrMatch ? addrMatch[1] : "";
       let addrIdx = aInput.indexOf("<" + addr + ">");
-      return this.makeMailboxObject(
-        addrIdx == 0 ? "" : aInput.slice(0, addrIdx).trim(),
-        addr
-      );
+      return this.makeMailboxObject(aInput.slice(0, addrIdx).trim(), addr);
     }
     return this.makeMailboxObject("", aInput);
   },
 
   extractHeaderAddressMailboxes(aLine) {
     return this.parseDecodedHeader(aLine)
       .map(addr => addr.email)
       .join(", ");
--- a/mailnews/mime/test/unit/test_nsIMsgHeaderParser4.js
+++ b/mailnews/mime/test/unit/test_nsIMsgHeaderParser4.js
@@ -1,13 +1,14 @@
 /* -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/*
- * Test suite for nsIMsgHeaderParser::makeFromDisplayAddress
+
+/**
+ * Test suite for nsIMsgHeaderParser::makeFromDisplayAddress.
+ * This is what is used to parse in the user input from addressing fields.
  */
-
 var { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
 
 function run_test() {
   const checks = [
     { displayString: "", addresses: [] },
     {
@@ -130,16 +131,58 @@ function run_test() {
       addresses: [['jay "bad" ass', "name@evil.com"]],
     },
 
     {
       displayString:
         'me "you" (via foo@example.com) <attacker2@example.com> friend@example.com,',
       addresses: [['me "you" (via foo@example.com)', "attacker2@example.com"]],
     },
+
+    // An uncompleted autocomplete...
+    {
+      displayString: "me >> test <joe@examp.com>",
+      addresses: [["me >> test", "joe@examp.com"]],
+    },
+
+    // A mail list.
+    {
+      displayString: "Holmes and Watson <Tenants221B>",
+      addresses: [["Holmes and Watson", "Tenants221B"]],
+    },
+
+    // A mail list with a space in the name.
+    {
+      displayString: 'Watson and Holmes <"Quoted Tenants221B">',
+      addresses: [["Watson and Holmes", '"Quoted Tenants221B"']],
+    },
+
+    // Mail Merge template
+    {
+      displayString: "{{PrimaryEmail}} <>",
+      addresses: [["{{PrimaryEmail}}", ""]],
+    },
+
+    // Quoted heart.
+    {
+      displayString: 'Marge "<3" S <qheart@example.com>',
+      addresses: [['Marge "<3" S', "qheart@example.com"]],
+    },
+
+    // Heart.
+    {
+      displayString: "Maggie <3 S <heart@example.com>",
+      addresses: [["Maggie <3 S", "heart@example.com"]],
+    },
+
+    // Unbalanced quotes.
+    {
+      displayString: 'Homer <3 "B>" "J <unb@example.com>',
+      addresses: [['Homer <3 "B>" "J', "unb@example.com"]],
+    },
   ];
 
   // Test -  strings
 
   for (let i = 0; i < checks.length; ++i) {
     let addrs = MailServices.headerParser.makeFromDisplayAddress(
       checks[i].displayString
     );