Bug 1509493 - Fix markup generation for nested email addresses r=BenB
☠☠ backed out by a0e0ae690520 ☠ ☠
authorFabian Henneke <fabian@henneke.me>
Thu, 29 Nov 2018 15:49:29 +0000
changeset 505183 05562b7d3effc75bba30fb7f02175162f1484816
parent 505182 6498765e1d6544fc962945e2f0873356434f4bd9
child 505184 88ca4ffc6f68dc0134cfdda117d1c56caa4b7789
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBenB
bugs1509493
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1509493 - Fix markup generation for nested email addresses r=BenB In mozTXTToHTMLConv, FindURL is not able to correctly calculate replaceBefore for nested email addresses/URLs such as john@doe.org}john@doe.org. As a workaround, we keep track of the end of the last URL HTML markup in the output string and skip any subsequent URLs whose replaceBefore would cut into this markup. Differential Revision: https://phabricator.services.mozilla.com/D13391
netwerk/streamconv/converters/mozTXTToHTMLConv.cpp
netwerk/test/unit/test_mozTXTToHTMLConv.js
--- a/netwerk/streamconv/converters/mozTXTToHTMLConv.cpp
+++ b/netwerk/streamconv/converters/mozTXTToHTMLConv.cpp
@@ -1081,16 +1081,18 @@ mozTXTToHTMLConv::ScanTXT(const char16_t
   bool doGlyphSubstitution = 0 != (whattodo & kGlyphSubstitution);
   bool doStructPhrase = 0 != (whattodo & kStructPhrase);
 
   uint32_t structPhrase_strong = 0;  // Number of currently open tags
   uint32_t structPhrase_underline = 0;
   uint32_t structPhrase_italic = 0;
   uint32_t structPhrase_code = 0;
 
+  uint32_t endOfLastURLOutput = 0;
+
   nsAutoString outputHTML;  // moved here for performance increase
 
   for(uint32_t i = 0; int32_t(i) < aInStringLength;)
   {
     if (doGlyphSubstitution)
     {
       int32_t glyphTextLen;
       if (GlyphHit(&aInString[i], aInStringLength - i, i == 0, aOutString, glyphTextLen))
@@ -1168,18 +1170,23 @@ mozTXTToHTMLConv::ScanTXT(const char16_t
           int32_t replaceBefore;
           int32_t replaceAfter;
           if (FindURL(aInString, aInStringLength, i, whattodo,
                       outputHTML, replaceBefore, replaceAfter)
                   && structPhrase_strong + structPhrase_italic +
                        structPhrase_underline + structPhrase_code == 0
                        /* workaround for bug #19445 */ )
           {
+            // Don't cut into previously inserted HTML (bug 1509493)
+            if (aOutString.Length() - replaceBefore < endOfLastURLOutput) {
+              break;
+            }
             aOutString.Cut(aOutString.Length() - replaceBefore, replaceBefore);
             aOutString += outputHTML;
+            endOfLastURLOutput = aOutString.Length();
             i += replaceAfter + 1;
             continue;
           }
         }
         break;
       } //switch
     }
 
--- a/netwerk/test/unit/test_mozTXTToHTMLConv.js
+++ b/netwerk/test/unit/test_mozTXTToHTMLConv.js
@@ -143,16 +143,26 @@ function run_test() {
     },
     {
       input: "ipv6 parenthesis port: (http://[2001:db8::1]:80/) test",
       url: "http://[2001:db8::1]:80/"
     },
     {
       input: "test http://www.map.com/map.php?t=Nova_Scotia&markers=//Not_a_survey||description=plm2 test",
       url: "http://www.map.com/map.php?t=Nova_Scotia&amp;markers=//Not_a_survey||description=plm2"
+    },
+    {
+      input: "bug#1509493 (john@mozilla.org)john@mozilla.org test",
+      url: "mailto:john@mozilla.org",
+      text: "john@mozilla.org"
+    },
+    {
+      input: "bug#1509493 {john@mozilla.org}john@mozilla.org test",
+      url: "mailto:john@mozilla.org",
+      text: "john@mozilla.org"
     }
   ];
 
   const scanHTMLtests = [
     {
       input: "http://foo.example.com",
       shouldChange: true
     },
@@ -205,23 +215,33 @@ function run_test() {
       shouldChange: false
     },
   ];
 
   function hrefLink(url) {
     return ' href="' + url + '"';
   }
 
+  function linkText(plaintext) {
+    return '>' + plaintext + '</a>';
+  }
+
   for (let i = 0; i < scanTXTtests.length; i++) {
     let t = scanTXTtests[i];
     let output = converter.scanTXT(t.input, Ci.mozITXTToHTMLConv.kURLs);
     let link = hrefLink(t.url);
+    let text;
+    if (t.text)
+      text = linkText(t.text);
     if (!output.includes(link))
       do_throw("Unexpected conversion by scanTXT: input=" + t.input +
                ", output=" + output + ", link=" + link);
+    if (text && !output.includes(text))
+      do_throw("Unexpected conversion by scanTXT: input=" + t.input +
+               ", output=" + output + ", text=" + text);
   }
 
   for (let i = 0; i < scanHTMLtests.length; i++) {
     let t = scanHTMLtests[i];
     let output = converter.scanHTML(t.input, Ci.mozITXTToHTMLConv.kURLs);
     let changed = (t.input != output);
     if (changed != t.shouldChange) {
       do_throw("Unexpected change by scanHTML: changed=" + changed +