Home | History | Annotate | Download | only in encoding
      1 <html>
      2 <head>
      3 <link rel="stylesheet" href="../js/resources/js-test-style.css">
      4 <script src="../js/resources/js-test-pre.js"></script>
      5 </head>
      6 <body>
      7 <p id="description"></p>
      8 <div id="console"></div>
      9 <script>
     10 
     11 function testIDNEncode(charCode)
     12 {
     13     var str = String.fromCharCode(charCode);
     14     str = layoutTestController.encodeHostName(str);
     15     if (str.substr(0, 4) == "xn--")
     16         return "punycode";
     17     return escape(str);
     18 }
     19 
     20 function testIDNEncodeNotFirstCharacter(charCode)
     21 {
     22     var str = String.fromCharCode(charCode);
     23     str = "a" + str;
     24     str = layoutTestController.encodeHostName(str);
     25     if (str.substr(0, 4) == "xn--")
     26         return "punycode";
     27     if (str.substr(0, 1) == "a")
     28         str = str.substr(1, str.length - 1);
     29     return escape(str);
     30 }
     31 
     32 function testIDNRoundTrip(charCode)
     33 {
     34     var str = String.fromCharCode(charCode);
     35     str = layoutTestController.encodeHostName(str);
     36     str = layoutTestController.decodeHostName(str);
     37     if (str.substr(0, 4) == "xn--")
     38         return "punycode";
     39     return escape(str);
     40 }
     41 
     42 function testIDNRoundTripNotFirstCharacter(charCode)
     43 {
     44     var str = String.fromCharCode(charCode);
     45     str = "a" + str;
     46     str = layoutTestController.encodeHostName(str);
     47     str = layoutTestController.decodeHostName(str);
     48     if (str.substr(0, 4) == "xn--")
     49         return "punycode";
     50     if (str.substr(0, 1) == "a")
     51         str = str.substr(1, str.length - 1);
     52     return escape(str);
     53 }
     54 
     55 function testFunctionName(expected)
     56 {
     57     if (expected == "does not encode")
     58         return "testIDNEncode";
     59     return "testIDNRoundTrip";
     60 }
     61 
     62 function expectedTestResult(charCode, expected)
     63 {
     64     if (expected == "disallowed")
     65         return "'punycode'";
     66     if (expected == "allowed" || expected == "does not encode")
     67         return "'" + escape(String.fromCharCode(charCode)) + "'";
     68     return "'" + expected + "'";
     69 }
     70 
     71 function testIDNCharacter(charCode, expected, expectedNotFirstCharacter)
     72 {
     73     if (expectedNotFirstCharacter == null)
     74         expectedNotFirstCharacter = expected;
     75 
     76     shouldBe(testFunctionName(expected) + "(0x" + charCode.toString(16) + ")",
     77         expectedTestResult(charCode, expected));
     78 
     79     shouldBe(testFunctionName(expectedNotFirstCharacter) + "NotFirstCharacter(0x" + charCode.toString(16) + ")",
     80         expectedTestResult(charCode, expectedNotFirstCharacter));    
     81 }
     82 
     83 function testBecomesSpaceIDNCharacter(charCode)
     84 {
     85     shouldBe("testIDNRoundTrip(0x" + charCode.toString(16) + ")", "'%20'");
     86     shouldBe("testIDNRoundTripFirstCharacter(0x" + charCode.toString(16) + ")", "'%20'");
     87 }
     88 
     89 function testBecomesASCIIIDNCharacter(charCode, expected)
     90 {
     91     shouldBe("testIDNRoundTrip(0x" + charCode.toString(16) + ")", "'" + expected + "'");
     92     shouldBe("testIDNRoundTripFirstCharacter(0x" + charCode.toString(16) + ")", "'" + expected + "'");
     93 }
     94 
     95 function testDisallowedIDNCharacter(charCode)
     96 {
     97     shouldBe("testIDNRoundTrip(0x" + charCode.toString(16) + ")", "'punycode'");
     98     shouldBe("testIDNRoundTripFirstCharacter(0x" + charCode.toString(16) + ")", "'punycode'");
     99 }
    100 
    101 function testAllowedIDNCharacter(charCode)
    102 {
    103     var expected = escape(String.fromCharCode(charCode));
    104     shouldBe("testIDNRoundTrip(0x" + charCode.toString(16) + ")", "'" + expected + "'");
    105     shouldBe("testIDNRoundTripFirstCharacter(0x" + charCode.toString(16) + ")", "'" + expected + "'");
    106 }
    107 
    108 function testDoesNotEncodeIDNCharacter(charCode)
    109 {
    110     var expected = escape(String.fromCharCode(charCode));
    111     shouldBe("testIDNEncode(0x" + charCode.toString(16) + ")", "'" + expected + "'");
    112     shouldBe("testIDNEncodeTripFirstCharacter(0x" + charCode.toString(16) + ")", "'" + expected + "'");
    113 }
    114 
    115 var isOlderICU = testIDNEncode(0x3002) == ".";
    116 
    117 /* Allowed Characters - dot and slash */
    118 testIDNCharacter(".".charCodeAt(0), "allowed");
    119 testIDNCharacter("/".charCodeAt(0), "allowed");
    120 
    121 /* Allowed Characters - one character for each script in the default IDN whitelist*/
    122 testIDNCharacter(0x0061, "allowed");
    123 testIDNCharacter(0x0633, "allowed");
    124 testIDNCharacter(0x0561, "allowed");
    125 testIDNCharacter(0x3105, "allowed");
    126 testIDNCharacter(0x1613, "allowed");
    127 testIDNCharacter(0x0905, "allowed");
    128 testIDNCharacter(0x0A85, "allowed");
    129 testIDNCharacter(0x0A05, "allowed");
    130 testIDNCharacter(0x1115, "allowed");
    131 testIDNCharacter(0x4E2D, "allowed");
    132 testIDNCharacter(0x05D0, "allowed");
    133 testIDNCharacter(0x3041, "allowed");
    134 testIDNCharacter(0x30A1, "allowed");
    135 testIDNCharacter(0x0B94, "allowed");
    136 testIDNCharacter(0x0E01, "allowed");
    137 testIDNCharacter(0xA000, "allowed");
    138 
    139 /* ICU converts these to other allowed characters, so the original character can't be used to get to a phishy domain name */
    140 testIDNCharacter(0x2024, ".");
    141 testIDNCharacter(0xFE52, ".");
    142 testIDNCharacter(0xFF0F, "/");
    143 
    144 /* ICU converts these characters to backslash, so the original character can't be used to get to a phishy domain name */
    145 testIDNCharacter(0xFE68, "%5C");
    146 testIDNCharacter(0xFF3C, "%5C");
    147 
    148 /* ICU converts these characters to space, so the original character can't be used to get to a phishy domain name */
    149 testIDNCharacter(0x00A0, "%20");
    150 testIDNCharacter(0x2000, "%20");
    151 testIDNCharacter(0x2001, "%20");
    152 testIDNCharacter(0x2002, "%20");
    153 testIDNCharacter(0x2003, "%20");
    154 testIDNCharacter(0x2004, "%20");
    155 testIDNCharacter(0x2005, "%20");
    156 testIDNCharacter(0x2006, "%20");
    157 testIDNCharacter(0x2007, "%20");
    158 testIDNCharacter(0x2008, "%20");
    159 testIDNCharacter(0x2009, "%20");
    160 testIDNCharacter(0x200A, "%20");
    161 testIDNCharacter(0x202F, "%20");
    162 testIDNCharacter(0x205F, "%20");
    163 testIDNCharacter(0x3000, "%20");
    164 
    165 /* Disallow these characters.  Some of these are known lookalike characters for dot and slash.  
    166    A lot of these are from Mozilla's blacklist: http://kb.mozillazine.org/Network.IDN.blacklist_chars
    167 */
    168 testIDNCharacter(0x00BC, "disallowed");
    169 testIDNCharacter(0x00BD, "disallowed");
    170 testIDNCharacter(0x00ED, "disallowed");
    171 testIDNCharacter(0x01C3, "disallowed");
    172 testIDNCharacter(0x0251, "disallowed");
    173 testIDNCharacter(0x0261, "disallowed");
    174 testIDNCharacter(0x0337, "disallowed");
    175 testIDNCharacter(0x0337, "disallowed");
    176 testIDNCharacter(0x0338, "disallowed");
    177 testIDNCharacter(0x0338, "disallowed");
    178 testIDNCharacter(0x05B4, "disallowed");
    179 testIDNCharacter(0x05BC, "disallowed");
    180 testIDNCharacter(0x0660, "disallowed");
    181 testIDNCharacter(0x06F0, "disallowed");
    182 testIDNCharacter(0x115F, "disallowed");
    183 testIDNCharacter(0x1160, "disallowed");
    184 testIDNCharacter(0x2027, "disallowed");
    185 testIDNCharacter(0x2039, "disallowed");
    186 testIDNCharacter(0x203A, "disallowed");
    187 testIDNCharacter(0x2044, "disallowed");
    188 testIDNCharacter(0x2044, "disallowed");
    189 testIDNCharacter(0x2154, "disallowed");
    190 testIDNCharacter(0x2155, "disallowed");
    191 testIDNCharacter(0x2156, "disallowed");
    192 testIDNCharacter(0x2159, "disallowed");
    193 testIDNCharacter(0x215A, "disallowed");
    194 testIDNCharacter(0x215B, "disallowed");
    195 testIDNCharacter(0x215F, "disallowed");
    196 testIDNCharacter(0x2215, "disallowed");
    197 testIDNCharacter(0x2216, "disallowed");
    198 testIDNCharacter(0x233F, "disallowed");
    199 testIDNCharacter(0x23AE, "disallowed");
    200 testIDNCharacter(0x244A, "disallowed");
    201 testIDNCharacter(0x2571, "disallowed");
    202 testIDNCharacter(0x2572, "disallowed");
    203 testIDNCharacter(0x29F6, "disallowed");
    204 testIDNCharacter(0x29F8, "disallowed");
    205 testIDNCharacter(0x29F8, "disallowed");
    206 testIDNCharacter(0x2AFB, "disallowed");
    207 testIDNCharacter(0x2AFD, "disallowed");
    208 testIDNCharacter(0x3014, "disallowed");
    209 testIDNCharacter(0x3015, "disallowed");
    210 testIDNCharacter(0x3033, "disallowed");
    211 testIDNCharacter(0x3035, "disallowed");
    212 testIDNCharacter(0x3164, "disallowed");
    213 testIDNCharacter(0x321D, "disallowed");
    214 testIDNCharacter(0x321E, "disallowed");
    215 testIDNCharacter(0x33AE, "disallowed");
    216 testIDNCharacter(0x33AF, "disallowed");
    217 testIDNCharacter(0x33C6, "disallowed");
    218 testIDNCharacter(0x33DF, "disallowed");
    219 testIDNCharacter(0xFE14, "disallowed");
    220 testIDNCharacter(0xFE15, "disallowed");
    221 testIDNCharacter(0xFE3F, "disallowed");
    222 testIDNCharacter(0xFE5D, "disallowed");
    223 testIDNCharacter(0xFE5E, "disallowed");
    224 testIDNCharacter(0xFFA0, "disallowed");
    225 
    226 /* ICU won't encode these characters in IDN, thus we should always get 'host not found'. */
    227 testIDNCharacter(0x2028, "does not encode");
    228 testIDNCharacter(0x2029, "does not encode");
    229 testIDNCharacter(0x2FF0, "does not encode");
    230 testIDNCharacter(0x2FF1, "does not encode");
    231 testIDNCharacter(0x2FF2, "does not encode");
    232 testIDNCharacter(0x2FF3, "does not encode");
    233 testIDNCharacter(0x2FF4, "does not encode");
    234 testIDNCharacter(0x2FF5, "does not encode");
    235 testIDNCharacter(0x2FF6, "does not encode");
    236 testIDNCharacter(0x2FF7, "does not encode");
    237 testIDNCharacter(0x2FF8, "does not encode");
    238 testIDNCharacter(0x2FF9, "does not encode");
    239 testIDNCharacter(0x2FFA, "does not encode");
    240 testIDNCharacter(0x2FFB, "does not encode");
    241 testIDNCharacter(0xFFF9, "does not encode");
    242 testIDNCharacter(0xFFFA, "does not encode");
    243 testIDNCharacter(0xFFFB, "does not encode");
    244 testIDNCharacter(0xFFFC, "does not encode");
    245 testIDNCharacter(0xFFFD, "does not encode");
    246 
    247 /* ICU won't encode these characters if they're not the first character in the host name.  
    248    If the character does get encoded as the first character, then we will disallow it */
    249    
    250 testIDNCharacter(0x05C3, "disallowed", "does not encode");
    251 testIDNCharacter(0x05F4, "disallowed", "does not encode");
    252 testIDNCharacter(0x06D4, "disallowed", "does not encode");
    253 testIDNCharacter(0x0702, "disallowed", "does not encode");
    254 
    255 /* ICU won't encode these characters if they're the first character in the host name.  
    256    If the character does get encoded as the first character, then ICU converts it to another allowed character */
    257 
    258 if (isOlderICU) {
    259     testIDNCharacter(0x200B, "");
    260     testIDNCharacter(0x3002, ".");
    261     testIDNCharacter(0xFF0E, ".");
    262     testIDNCharacter(0xFF61, ".");
    263     testIDNCharacter(0xFEFF, "");
    264 } else {
    265     testIDNCharacter(0x200B, "does not encode", "");
    266     testIDNCharacter(0x3002, "does not encode", ".");
    267     testIDNCharacter(0xFF0E, "does not encode", ".");
    268     testIDNCharacter(0xFF61, "does not encode", ".");
    269     testIDNCharacter(0xFEFF, "does not encode", "");
    270 }
    271 
    272 successfullyParsed = true;
    273 
    274 </script>
    275 </body>
    276 </html>
    277