Bug 1408782 - Force punycode display for IDNs with a <dotless-i, combining mark above> sequence. r=valentin
authorJonathan Kew <jkew@mozilla.com>
Mon, 16 Oct 2017 10:19:52 +0100
changeset 680877 ee969734750ace337d13515b00c92703f6577550
parent 680876 a52b7ea3d0d4fb3c91bc8d7c3b72d5057fbfb250
child 680878 4fd5250dedfcfb133c244992db3019a432cec203
push id84661
push userbmo:ttromey@mozilla.com
push dateMon, 16 Oct 2017 14:19:39 +0000
reviewersvalentin
bugs1408782
milestone58.0a1
Bug 1408782 - Force punycode display for IDNs with a <dotless-i, combining mark above> sequence. r=valentin
netwerk/dns/nsIDNService.cpp
netwerk/test/unit/test_idn_urls.js
--- a/netwerk/dns/nsIDNService.cpp
+++ b/netwerk/dns/nsIDNService.cpp
@@ -745,16 +745,17 @@ bool nsIDNService::isLabelSafe(const nsA
   }
 
   nsAString::const_iterator current, end;
   label.BeginReading(current);
   label.EndReading(end);
 
   Script lastScript = Script::INVALID;
   uint32_t previousChar = 0;
+  uint32_t baseChar = 0; // last non-diacritic seen (base char for marks)
   uint32_t savedNumberingSystem = 0;
 // Simplified/Traditional Chinese check temporarily disabled -- bug 857481
 #if 0
   HanVariantType savedHanVariant = HVT_NotHan;
 #endif
 
   int32_t savedScript = -1;
 
@@ -825,16 +826,24 @@ bool nsIDNService::isLabelSafe(const nsA
               break;
             }
           }
           if (nScripts == -1) {
             return false;
           }
         }
       }
+      // Check for diacritics on dotless-i, which would be indistinguishable
+      // from normal accented letter i.
+      if (baseChar == 0x0131 &&
+          ((ch >= 0x0300 && ch <= 0x0314) || ch == 0x031a)) {
+        return false;
+      }
+    } else {
+      baseChar = ch;
     }
 
     if (script != Script::COMMON && script != Script::INHERITED) {
       lastScript = script;
     }
 
     // Simplified/Traditional Chinese check temporarily disabled -- bug 857481
 #if 0
--- a/netwerk/test/unit/test_idn_urls.js
+++ b/netwerk/test/unit/test_idn_urls.js
@@ -298,16 +298,23 @@ const testcases = [
 
     // Arabic diacritic not allowed in Latin text (bug 1370497)
     ["goo\u0650gle", "xn--google-yri", false, false, false],
     // ...but Arabic diacritics are allowed on Arabic text
     ["العَرَبِي", "xn--mgbc0a5a6cxbzabt", false, true, true],
 
     // Hebrew diacritic also not allowed in Latin text (bug 1404349)
     ["goo\u05b4gle", "xn--google-rvh", false, false, false],
+
+    // Accents above dotless-i are not allowed
+    ["na\u0131\u0308ve", "xn--nave-mza04z", false, false, false],
+    ["d\u0131\u0302ner", "xn--dner-lza40z", false, false, false],
+    // but the corresponding accented-i (based on dotted i) is OK
+    ["na\u00efve.com", "xn--nave-6pa.com", false, true, true],
+    ["d\u00eener.com", "xn--dner-0pa.com", false, true, true],
 ];
 
 const profiles = ["ASCII", "high", "moderate"];
 
 function run_test() {
     var pbi = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
     var oldProfile = pbi.getCharPref("network.IDN.restriction_profile", "moderate");
     var oldWhitelistCom = pbi.getBoolPref("network.IDN.whitelist.com", false);