Bug 1130248 - Allow email addresses in address name fields, r=fallen,mkmelin,jorgk
authorR Kent James <rkent@caspia.com>
Fri, 15 May 2015 15:17:20 -0700
changeset 17945 f4fa4a4f96c13c95d95bf7f035b4eb546be1e855
parent 17944 ccba868cf370b2260b2523663449ed272d55a31f
child 17946 fcbd8eb059bead257387c326fea770d7978e4320
push id11032
push userkent@caspia.com
push dateFri, 15 May 2015 22:17:52 +0000
treeherdercomm-central@f4fa4a4f96c1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfallen, mkmelin, jorgk
bugs1130248
Bug 1130248 - Allow email addresses in address name fields, r=fallen,mkmelin,jorgk
mail/base/content/msgHdrViewOverlay.js
mailnews/mime/jsmime/jsmime.js
mailnews/mime/jsmime/test/test_header.js
--- a/mail/base/content/msgHdrViewOverlay.js
+++ b/mail/base/content/msgHdrViewOverlay.js
@@ -1582,17 +1582,19 @@ function EditContact(emailAddressNode)
 function SendMailToNode(addressNode, aEvent)
 {
   let fields = Components.classes["@mozilla.org/messengercompose/composefields;1"]
                          .createInstance(Components.interfaces.nsIMsgCompFields);
   let params = Components.classes["@mozilla.org/messengercompose/composeparams;1"]
                          .createInstance(Components.interfaces.nsIMsgComposeParams);
 
   fields.newsgroups = addressNode.getAttribute("newsgroup");
-  fields.to = addressNode.getAttribute("fullAddress");
+  let addresses = MailServices.headerParser.makeFromDisplayAddress(
+    addressNode.getAttribute("fullAddress"), {});
+  fields.to = MailServices.headerParser.makeMimeHeader(addresses, 1);
 
   params.type = Components.interfaces.nsIMsgCompType.New;
 
   // If aEvent is passed, check if Shift key was pressed for composition in
   // non-default format (HTML vs. plaintext).
   params.format = (aEvent && aEvent.shiftKey) ? 
     Components.interfaces.nsIMsgCompFormat.OppositeOfDefault :
     Components.interfaces.nsIMsgCompFormat.Default;
--- a/mailnews/mime/jsmime/jsmime.js
+++ b/mailnews/mime/jsmime/jsmime.js
@@ -802,17 +802,25 @@ function parseAddressingHeader(header, d
       groupName = name;
       name = '';
       localPart = '';
       // If we had prior email address results, commit them to the top-level.
       if (addrlist.length > 0)
         results = results.concat(addrlist);
       addrlist = [];
     } else if (token === '<') {
-      inAngle = true;
+      if (inAngle) {
+        // Interpret the address we were parsing as a name.
+        if (address.length > 0) {
+          name = address;
+        }
+        localPart = address = '';
+      } else {
+        inAngle = true;
+      }
     } else if (token === '>') {
       inAngle = false;
       // Forget addr-spec comments.
       lastComment = '';
     } else if (token === '(') {
       inComment = true;
       // The needsSpace flag may not always be set even if it should be,
       // e.g. for a comment behind an angle-addr.
--- a/mailnews/mime/jsmime/test/test_header.js
+++ b/mailnews/mime/jsmime/test/test_header.js
@@ -324,16 +324,28 @@ suite('headerparser', function () {
       ["a < <a@b.c>", [{name: "a", email: "a@b.c"}]],
       ["Name <incomplete@email", [{name: "Name", email: "incomplete@email"}]],
       ["Name <space here@email.invalid>",
         [{name: 'Name', email: '"space here"@email.invalid'}]],
       ["Name <not an email>", [{name: "Name", email: "not an email"}]],
       ["=?UTF-8?Q?Simple?= <a@b.c>",
         [{name: "=?UTF-8?Q?Simple?=", email: "a@b.c"}]],
       ["No email address", [{name: "No email address", email: ""}]],
+      // Thought we were parsing an address, but it was a name.
+      ["name@example.com <receiver@example.com>",
+        [{name: "name@example.com", email: "receiver@example.com"}]],
+      ["name@huhu.com <receiver@example.com>",
+        [{name: "name@huhu.com", email: "receiver@example.com"}]],
+      // Some names with quotes.
+      ["\"name@huhu.com\" <receiver@example.com>",
+        [{name: "name@huhu.com", email: "receiver@example.com"}]],
+      ["\"Chaplin, Charlie\" <receiver@example.com>",
+        [{name: "Chaplin, Charlie", email: "receiver@example.com"}]],
+      ["\"name@huhu.com and name@haha.com\" <receiver@example.com>",
+        [{name: "name@huhu.com and name@haha.com", email: "receiver@example.com"}]],
       // Handling of comments and legacy display-names as per RFC 5322 §3.4
       ["(c1)n(c2) <(c3)a(c4)@(c5)b(c6).(c7)d(c8)> (c9(c10)c11)",
         [{name: "(c1) n (c2) (c9(c10)c11)", email: "a@b.d"}]],
       ["<(c3)a(c4)@(c5)b(c6).(c7)d(c8)> (c9(c10)c11)",
         [{name: "(c9(c10)c11)", email: "a@b.d"}]],
       ["(c3)a(c4)@(c5)b(c6).(c7)d(c8)(c9(c10)c11)",
         [{name: "c9(c10)c11", email: "a@b.d"}]],
       ["(c1)n(c2) <(c3)a(c4)@(c5)b(c6).(c7)d(c8)> (c9(c10)c11)(c12)",
@@ -381,16 +393,24 @@ suite('headerparser', function () {
       ["\"=?iso-8859-1?Q?First_Mar=EDa_Furi=F3_Gancho?= mail@yahoo.es "+
         "[BCN-FC]\" <Barcelona-Freecycle-noreply@yahoogroups.com>",
         [{name: "First Mar\u00EDa Furi\u00F3 Gancho mail@yahoo.es [BCN-FC]",
       email: "Barcelona-Freecycle-noreply@yahoogroups.com"}]],
       ["\"=?iso-8859-1?B?U29maWEgQ2FzdGVsbPMgUm9tZXJv?= sonia@example.com "+
         "[BCN-FC]\" <Barcelona-Freecycle-noreply@yahoogroups.com>",
         [{name: "Sofia Castell\u00F3 Romero sonia@example.com [BCN-FC]",
       email: "Barcelona-Freecycle-noreply@yahoogroups.com"}]],
+      ["=?iso-8859-1?Q?Klaus_Eisschl=E4ger_=28k=2Eeisschlaeger=40t-onli?=" +
+        "=?iso-8859-1?Q?ne=2Ede=29?= <k.eisschlaeger@t-online.de>",
+      [{name: "Klaus Eisschläger (k.eisschlaeger@t-online.de)",
+        email: "k.eisschlaeger@t-online.de"}]],
+      ["\"=?UTF-8?Q?=22Claudia_R=C3=B6hschicht=22?= Claudia_Roehschicht@web.de [freecycle-berlin]\" " +
+        "<freecycle-berlin-noreply@yahoogroups.de>",
+      [{name: "\"Claudia Röhschicht\" Claudia_Roehschicht@web.de [freecycle-berlin]",
+        email: "freecycle-berlin-noreply@yahoogroups.de"}]],
     ];
     header_tests.forEach(function (data) {
       arrayTest(data, function () {
         assert.deepEqual(headerparser.parseAddressingHeader(data[0], true),
           data[1]);
       });
     });
   });