1 // Test algorithm for unicode display of IDNA URL (bug 722299)
6 // Original Punycode or Expected UTF-8 by profile
7 // URL normalized form ASCII-Only, High, Moderate
10 ["cuillère", "xn--cuillre-6xa", false, true, true],
12 // repeated non-spacing marks
13 ["gruz̀̀ere", "xn--gruzere-ogea", false, false, false],
16 ["I♥NY", "xn--iny-zx5a", false, false, false],
19 Behaviour of this test changed in IDNA2008, replacing the non-XID
20 character with U+FFFD replacement character - when all platforms use
21 IDNA2008 it can be uncommented and the punycode URL changed to
24 // new non-XID character in Unicode 6.3
25 ["حلا\u061cل", "xn--bgbvr6gc", false, false, false],
28 // U+30FB KATAKANA MIDDLE DOT is excluded from non-XID characters (bug 857490)
29 ["乾燥肌・石けん", "xn--08j4gylj12hz80b0uhfup", false, true, true],
32 ["толсто́й", "xn--lsa83dealbred", false, true, true],
34 // Mixed script Cyrillic/Latin
36 "толсто́й-in-Russian",
37 "xn---in-russian-1jg071b0a8bb4cpd",
43 // Mixed script Latin/Cyrillic
44 ["war-and-миръ", "xn--war-and--b9g3b7b3h", false, false, false],
46 // Cherokee (Restricted script)
47 ["ᏣᎳᎩ", "xn--f9dt7l", false, false, false],
49 // Yi (former Aspirational script, now Restricted per Unicode 10.0 update to UAX 31)
50 ["ꆈꌠꁱꂷ", "xn--4o7a6e1x64c", false, false, false],
53 ["πλάτων", "xn--hxa3ahjw4a", false, true, true],
55 // Mixed script Greek/Latin
57 "πλάτωνicrelationship",
58 "xn--icrelationship-96j4t9a3cwe2e",
64 // Mixed script Latin/Greek
65 ["spaceὈδύσσεια", "xn--space-h9dui0b0ga2j1562b", false, false, false],
68 ["मराठी", "xn--d2b1ag0dl", false, true, true],
70 // Devanagari with Armenian
71 ["मराठीՀայաստան", "xn--y9aaa1d0ai1cq964f8dwa2o1a", false, false, false],
73 // Devanagari with common
74 ["मराठी123", "xn--123-mhh3em2hra", false, true, true],
76 // Common with Devanagari
77 ["123मराठी", "xn--123-phh3em2hra", false, true, true],
80 ["chairman毛", "xn--chairman-k65r", false, true, true],
83 ["山葵sauce", "xn--sauce-6j9ii40v", false, true, true],
85 // Latin with Han, Hiragana and Katakana
86 ["van語ではドイ", "xn--van-ub4bpb6w0in486d", false, true, true],
88 // Latin with Han, Katakana and Hiragana
89 ["van語ドイでは", "xn--van-ub4bpb4w0ip486d", false, true, true],
91 // Latin with Hiragana, Han and Katakana
92 ["vanでは語ドイ", "xn--van-ub4bpb6w0ip486d", false, true, true],
94 // Latin with Hiragana, Katakana and Han
95 ["vanではドイ語", "xn--van-ub4bpb6w0ir486d", false, true, true],
97 // Latin with Katakana, Han and Hiragana
98 ["vanドイ語では", "xn--van-ub4bpb4w0ir486d", false, true, true],
100 // Latin with Katakana, Hiragana and Han
101 ["vanドイでは語", "xn--van-ub4bpb4w0it486d", false, true, true],
103 // Han with Latin, Hiragana and Katakana
104 ["語vanではドイ", "xn--van-ub4bpb6w0ik486d", false, true, true],
106 // Han with Latin, Katakana and Hiragana
107 ["語vanドイでは", "xn--van-ub4bpb4w0im486d", false, true, true],
109 // Han with Hiragana, Latin and Katakana
110 ["語ではvanドイ", "xn--van-rb4bpb9w0ik486d", false, true, true],
112 // Han with Hiragana, Katakana and Latin
113 ["語ではドイvan", "xn--van-rb4bpb6w0in486d", false, true, true],
115 // Han with Katakana, Latin and Hiragana
116 ["語ドイvanでは", "xn--van-ub4bpb1w0ip486d", false, true, true],
118 // Han with Katakana, Hiragana and Latin
119 ["語ドイではvan", "xn--van-rb4bpb4w0ip486d", false, true, true],
121 // Hiragana with Latin, Han and Katakana
122 ["イツvan語ではド", "xn--van-ub4bpb1wvhsbx330n", false, true, true],
124 // Hiragana with Latin, Katakana and Han
125 ["ではvanドイ語", "xn--van-rb4bpb9w0ir486d", false, true, true],
127 // Hiragana with Han, Latin and Katakana
128 ["では語vanドイ", "xn--van-rb4bpb9w0im486d", false, true, true],
130 // Hiragana with Han, Katakana and Latin
131 ["では語ドイvan", "xn--van-rb4bpb6w0ip486d", false, true, true],
133 // Hiragana with Katakana, Latin and Han
134 ["ではドイvan語", "xn--van-rb4bpb6w0iu486d", false, true, true],
136 // Hiragana with Katakana, Han and Latin
137 ["ではドイ語van", "xn--van-rb4bpb6w0ir486d", false, true, true],
139 // Katakana with Latin, Han and Hiragana
140 ["ドイvan語では", "xn--van-ub4bpb1w0iu486d", false, true, true],
142 // Katakana with Latin, Hiragana and Han
143 ["ドイvanでは語", "xn--van-ub4bpb1w0iw486d", false, true, true],
145 // Katakana with Han, Latin and Hiragana
146 ["ドイ語vanでは", "xn--van-ub4bpb1w0ir486d", false, true, true],
148 // Katakana with Han, Hiragana and Latin
149 ["ドイ語ではvan", "xn--van-rb4bpb4w0ir486d", false, true, true],
151 // Katakana with Hiragana, Latin and Han
152 ["ドイではvan語", "xn--van-rb4bpb4w0iw486d", false, true, true],
154 // Katakana with Hiragana, Han and Latin
155 ["ドイでは語van", "xn--van-rb4bpb4w0it486d", false, true, true],
158 ["中国123", "xn--123-u68dy61b", false, true, true],
161 ["123中国", "xn--123-x68dy61b", false, true, true],
163 // Characters that normalize to permitted characters
164 // (also tests Plane 1 supplementary characters)
165 ["super𝟖", "super8", true, true, true],
168 ["𠀀𠀁𠀂", "xn--j50icd", false, true, true],
170 // Han from Plane 2 with js (UTF-16) escapes
171 ["\uD840\uDC00\uD840\uDC01\uD840\uDC02", "xn--j50icd", false, true, true],
173 // Same with a lone high surrogate at the end
174 ["\uD840\uDC00\uD840\uDC01\uD840", "xn--zn7c0336bda", false, false, false],
176 // Latin text and Bengali digits
177 ["super৪", "xn--super-k2l", false, false, true],
179 // Bengali digits and Latin text
180 ["৫ab", "xn--ab-x5f", false, false, true],
182 // Bengali text and Latin digits
183 ["অঙ্কুর8", "xn--8-70d2cp0j6dtd", false, true, true],
185 // Latin digits and Bengali text
186 ["5াব", "xn--5-h3d7c", false, true, true],
188 // Mixed numbering systems
189 ["٢٠۰٠", "xn--8hbae38c", false, false, false],
191 // Traditional Chinese
192 ["萬城", "xn--uis754h", false, true, true],
194 // Simplified Chinese
195 ["万城", "xn--chq31v", false, true, true],
197 // Simplified-only and Traditional-only Chinese in the same label
198 ["万萬城", "xn--chq31vsl1b", false, true, true],
200 // Traditional-only and Simplified-only Chinese in the same label
201 ["萬万城", "xn--chq31vrl1b", false, true, true],
203 // Han and Latin and Bopomofo
206 "xn--bopomofo-hj5gkalm1637i876cuw0brk5f",
212 // Han, bopomofo, Latin
215 "xn--bopomofo-8i5gkalm9637i876cuw0brk5f",
221 // Latin, Han, Bopomofo
224 "xn--bopomofo-hj5gkalm9637i876cuw0brk5f",
230 // Latin, Bopomofo, Han
233 "xn--bopomofo-hj5gkalm3737i876cuw0brk5f",
239 // Bopomofo, Han, Latin
242 "xn--bopomofo-8i5gkalm3737i876cuw0brk5f",
248 // Bopomofo, Latin, Han
251 "xn--bopomofo-8i5gkalm1837i876cuw0brk5f",
257 // Han, bopomofo and katakana
260 "xn--jckteuaez1shij0450gylvccz9asi4e",
266 // Han, katakana, bopomofo
269 "xn--jckteuaez6shij5350gylvccz9asi4e",
275 // bopomofo, han, katakana
278 "xn--jckteuaez1shij4450gylvccz9asi4e",
284 // bopomofo, katakana, han
287 "xn--jckteuaez1shij9450gylvccz9asi4e",
293 // katakana, Han, bopomofo
296 "xn--jckteuaez6shij0450gylvccz9asi4e",
302 // katakana, bopomofo, Han
305 "xn--jckteuaez6shij4450gylvccz9asi4e",
311 // Han, Hangul and Latin
312 ["韓한글hangul", "xn--hangul-2m5ti09k79ze", false, true, true],
314 // Han, Latin and Hangul
315 ["韓hangul한글", "xn--hangul-2m5to09k79ze", false, true, true],
317 // Hangul, Han and Latin
318 ["한글韓hangul", "xn--hangul-2m5th09k79ze", false, true, true],
320 // Hangul, Latin and Han
321 ["한글hangul韓", "xn--hangul-8m5t898k79ze", false, true, true],
323 // Latin, Han and Hangul
324 ["hangul韓한글", "xn--hangul-8m5ti09k79ze", false, true, true],
326 // Latin, Hangul and Han
327 ["hangul한글韓", "xn--hangul-8m5th09k79ze", false, true, true],
329 // Hangul and katakana
330 ["한글ハングル", "xn--qck1c2d4a9266lkmzb", false, false, false],
332 // Katakana and Hangul
333 ["ハングル한글", "xn--qck1c2d4a2366lkmzb", false, false, false],
335 // Thai (also tests that node with over 63 UTF-8 octets doesn't fail)
337 "เครื่องทําน้ําทําน้ําแข็ง",
338 "xn--22cdjb2fanb9fyepcbbb9dwh4a3igze4fdcd",
344 // Effect of adding valid or invalid subdomains (bug 1399540)
345 ["䕮䕵䕶䕱.ascii", "xn--google.ascii", false, true, true],
346 ["ascii.䕮䕵䕶䕱", "ascii.xn--google", false, true, true],
347 ["中国123.䕮䕵䕶䕱", "xn--123-u68dy61b.xn--google", false, true, true],
348 ["䕮䕵䕶䕱.中国123", "xn--google.xn--123-u68dy61b", false, true, true],
350 "xn--accountlogin.䕮䕵䕶䕱",
351 "xn--accountlogin.xn--google",
357 "䕮䕵䕶䕱.xn--accountlogin",
358 "xn--google.xn--accountlogin",
364 // Arabic diacritic not allowed in Latin text (bug 1370497)
365 ["goo\u0650gle", "xn--google-yri", false, false, false],
366 // ...but Arabic diacritics are allowed on Arabic text
367 ["العَرَبِي", "xn--mgbc0a5a6cxbzabt", false, true, true],
369 // Hebrew diacritic also not allowed in Latin text (bug 1404349)
370 ["goo\u05b4gle", "xn--google-rvh", false, false, false],
372 // Accents above dotless-i are not allowed
373 ["na\u0131\u0308ve", "xn--nave-mza04z", false, false, false],
374 ["d\u0131\u0302ner", "xn--dner-lza40z", false, false, false],
375 // but the corresponding accented-i (based on dotted i) is OK
376 ["na\u00efve.com", "xn--nave-6pa.com", false, true, true],
377 ["d\u00eener.com", "xn--dner-0pa.com", false, true, true],
380 const profiles = ["ASCII", "high", "moderate"];
382 function run_test() {
383 var pbi = Services.prefs;
384 var oldProfile = pbi.getCharPref(
385 "network.IDN.restriction_profile",
388 var idnService = Cc["@mozilla.org/network/idn-service;1"].getService(
392 for (var i = 0; i < profiles.length; ++i) {
393 pbi.setCharPref("network.IDN.restriction_profile", profiles[i]);
395 dump("testing " + profiles[i] + " profile");
397 for (var j = 0; j < testcases.length; ++j) {
398 var test = testcases[j];
399 var URL = test[0] + ".com";
400 var punycodeURL = test[1] + ".com";
401 var expectedUnicode = test[2 + i];
406 result = idnService.convertToDisplayIDN(URL, isASCII);
411 punycodeURL.substr(0, 4) == "xn--" ||
412 punycodeURL.indexOf(".xn--") > 0
414 // test convertToDisplayIDN with a Unicode URL and with a
415 // Punycode URL if we have one
418 expectedUnicode ? escape(URL) : escape(punycodeURL)
421 result = idnService.convertToDisplayIDN(punycodeURL, isASCII);
424 expectedUnicode ? escape(URL) : escape(punycodeURL)
427 // The "punycode" URL isn't punycode. This happens in testcases
428 // where the Unicode URL has become normalized to an ASCII URL,
429 // so, even though expectedUnicode is true, the expected result
430 // is equal to punycodeURL
431 Assert.equal(escape(result), escape(punycodeURL));
435 pbi.setCharPref("network.IDN.restriction_profile", oldProfile);