Bug 1509493 - Fix markup generation for nested email addresses r=BenB
authorFabian Henneke <fabian@henneke.me>
Sun, 02 Dec 2018 16:18:29 +0000
changeset 505615 95e75223f6c7dc1bdd13488deb46a18541c00c93
parent 505614 00d7ff2eeb0ad9eaeb2fe79a0c275b305f26f766
child 505616 aa8de096f6dcdadc8186637f6a742dc350d11781
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. Depends on D13645 Differential Revision: https://phabricator.services.mozilla.com/D13646
netwerk/streamconv/converters/mozTXTToHTMLConv.cpp
netwerk/test/unit/test_mozTXTToHTMLConv.js
--- a/netwerk/streamconv/converters/mozTXTToHTMLConv.cpp
+++ b/netwerk/streamconv/converters/mozTXTToHTMLConv.cpp
@@ -944,16 +944,18 @@ mozTXTToHTMLConv::ScanTXT(const nsAStrin
   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
 
   const char16_t* rawInputString = aInString.BeginReading();
 
   for (uint32_t i = 0; i < aInString.Length();) {
     if (doGlyphSubstitution) {
       int32_t glyphTextLen;
       if (GlyphHit(&rawInputString[i], aInString.Length() - i, i == 0,
@@ -1022,19 +1024,24 @@ mozTXTToHTMLConv::ScanTXT(const nsAStrin
             int32_t replaceBefore;
             int32_t replaceAfter;
             if (FindURL(rawInputString, aInString.Length(), 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 scanTXTglyph = [
     // Some "glyph" testing (not exhaustive, the system supports 16 different
     // smiley types).
     {
       input: "this is superscript: x^2",
@@ -266,23 +276,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 < scanTXTglyph.length; i++) {
     let t = scanTXTglyph[i];
     let output = converter.scanTXT(t.input, Ci.mozITXTToHTMLConv.kGlyphSubstitution);
     for (let j = 0; j < t.results.length; j++)
       if (!output.includes(t.results[j]))
         do_throw("Unexpected conversion by scanTXT: input=" + t.input +