github.com/go-enjin/golang-org-x-text@v0.12.1-enjin.2/internal/export/idna/idna10.0.0_test.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build go1.10 6 // +build go1.10 7 8 package idna 9 10 import "testing" 11 12 // TestLabelErrors tests strings returned in case of error. All results should 13 // be identical to the reference implementation and can be verified at 14 // https://unicode.org/cldr/utility/idna.jsp. The reference implementation, 15 // however, seems to not display Bidi and ContextJ errors. 16 // 17 // In some cases the behavior of browsers is added as a comment. In all cases, 18 // whenever a resolve search returns an error here, Chrome will treat the input 19 // string as a search string (including those for Bidi and Context J errors), 20 // unless noted otherwise. 21 func TestLabelErrors(t *testing.T) { 22 encode := func(s string) string { s, _ = encode(acePrefix, s); return s } 23 type kind struct { 24 name string 25 f func(string) (string, error) 26 } 27 punyA := kind{"PunycodeA", punycode.ToASCII} 28 resolve := kind{"ResolveA", Lookup.ToASCII} 29 display := kind{"ToUnicode", Display.ToUnicode} 30 p := New(VerifyDNSLength(true), MapForLookup(), BidiRule()) 31 lengthU := kind{"CheckLengthU", p.ToUnicode} 32 lengthA := kind{"CheckLengthA", p.ToASCII} 33 p = New(MapForLookup(), StrictDomainName(false)) 34 std3 := kind{"STD3", p.ToASCII} 35 p = New(MapForLookup(), CheckHyphens(false)) 36 hyphens := kind{"CheckHyphens", p.ToASCII} 37 p = New(MapForLookup(), Transitional(true)) 38 transitional := kind{"Transitional", p.ToASCII} 39 p = New(MapForLookup(), Transitional(false)) 40 nontransitional := kind{"Nontransitional", p.ToASCII} 41 42 testCases := []struct { 43 kind 44 input string 45 want string 46 wantErr string 47 }{ 48 {lengthU, "", "", "A4"}, // From UTS 46 conformance test. 49 {lengthA, "", "", "A4"}, 50 51 {lengthU, "xn--", "", "A4"}, 52 {lengthU, "foo.xn--", "foo.", "A4"}, // TODO: is dropping xn-- correct? 53 {lengthU, "xn--.foo", ".foo", "A4"}, 54 {lengthU, "foo.xn--.bar", "foo..bar", "A4"}, 55 56 {display, "xn--", "", ""}, 57 {display, "foo.xn--", "foo.", ""}, // TODO: is dropping xn-- correct? 58 {display, "xn--.foo", ".foo", ""}, 59 {display, "foo.xn--.bar", "foo..bar", ""}, 60 61 {lengthA, "a..b", "a..b", "A4"}, 62 {punyA, ".b", ".b", ""}, 63 // For backwards compatibility, the Punycode profile does not map runes. 64 {punyA, "\u3002b", "xn--b-83t", ""}, 65 {punyA, "..b", "..b", ""}, 66 67 {lengthA, ".b", ".b", "A4"}, 68 {lengthA, "\u3002b", ".b", "A4"}, 69 {lengthA, "..b", "..b", "A4"}, 70 {lengthA, "b..", "b..", ""}, 71 72 // Sharpened Bidi rules for Unicode 10.0.0. Apply for ALL labels in ANY 73 // of the labels is RTL. 74 {lengthA, "\ufe05\u3002\u3002\U0002603e\u1ce0", "..xn--t6f5138v", "A4"}, 75 {lengthA, "FAX\u2a77\U0001d186\u3002\U0001e942\U000e0181\u180c", "", "B6"}, 76 77 {resolve, "a..b", "a..b", ""}, 78 // Note that leading dots are not stripped. This is to be consistent 79 // with the Punycode profile as well as the conformance test. 80 {resolve, ".b", ".b", ""}, 81 {resolve, "\u3002b", ".b", ""}, 82 {resolve, "..b", "..b", ""}, 83 {resolve, "b..", "b..", ""}, 84 {resolve, "\xed", "", "P1"}, 85 86 // Raw punycode 87 {punyA, "", "", ""}, 88 {punyA, "*.foo.com", "*.foo.com", ""}, 89 {punyA, "Foo.com", "Foo.com", ""}, 90 91 // STD3 rules 92 {display, "*.foo.com", "*.foo.com", "P1"}, 93 {std3, "*.foo.com", "*.foo.com", ""}, 94 95 // Hyphens 96 {display, "r3---sn-apo3qvuoxuxbt-j5pe.googlevideo.com", "r3---sn-apo3qvuoxuxbt-j5pe.googlevideo.com", "V2"}, 97 {hyphens, "r3---sn-apo3qvuoxuxbt-j5pe.googlevideo.com", "r3---sn-apo3qvuoxuxbt-j5pe.googlevideo.com", ""}, 98 {display, "-label-.com", "-label-.com", "V3"}, 99 {hyphens, "-label-.com", "-label-.com", ""}, 100 101 // Don't map U+2490 (DIGIT NINE FULL STOP). This is the behavior of 102 // Chrome, modern Firefox, Safari, and IE. 103 {resolve, "lab⒐be", "xn--labbe-zh9b", "P1"}, // encode("lab⒐be") 104 {display, "lab⒐be", "lab⒐be", "P1"}, 105 {transitional, "plan⒐faß.de", "xn--planfass-c31e.de", "P1"}, // encode("plan⒐fass") + ".de" 106 {display, "Plan⒐faß.de", "plan⒐faß.de", "P1"}, 107 108 // Transitional vs Nontransitional processing 109 {transitional, "Plan9faß.de", "plan9fass.de", ""}, 110 {nontransitional, "Plan9faß.de", "xn--plan9fa-6va.de", ""}, 111 112 // Chrome 54.0 recognizes the error and treats this input verbatim as a 113 // search string. 114 // Safari 10.0 (non-conform spec) decomposes "⒈" and computes the 115 // punycode on the result using transitional mapping. 116 // Firefox 49.0.1 goes haywire on this string and prints a bunch of what 117 // seems to be nested punycode encodings. 118 {transitional, "日本⒈co.ßßß.de", "xn--co-wuw5954azlb.ssssss.de", "P1"}, 119 {display, "日本⒈co.ßßß.de", "日本⒈co.ßßß.de", "P1"}, 120 121 {transitional, "a\u200Cb", "ab", ""}, 122 {display, "a\u200Cb", "a\u200Cb", "C"}, 123 124 {resolve, encode("a\u200Cb"), encode("a\u200Cb"), "C"}, 125 {display, "a\u200Cb", "a\u200Cb", "C"}, 126 127 {resolve, "grﻋﺮﺑﻲ.de", "xn--gr-gtd9a1b0g.de", "B"}, 128 { 129 // Notice how the string gets transformed, even with an error. 130 // Chrome will use the original string if it finds an error, so not 131 // the transformed one. 132 display, 133 "gr\ufecb\ufeae\ufe91\ufef2.de", 134 "gr\u0639\u0631\u0628\u064a.de", 135 "B", 136 }, 137 138 {resolve, "\u0671.\u03c3\u07dc", "xn--qib.xn--4xa21s", "B"}, // ٱ.σߜ 139 {display, "\u0671.\u03c3\u07dc", "\u0671.\u03c3\u07dc", "B"}, 140 141 // normalize input 142 {resolve, "a\u0323\u0322", "xn--jta191l", ""}, // ạ̢ 143 {display, "a\u0323\u0322", "\u1ea1\u0322", ""}, 144 145 // Non-normalized strings are not normalized when they originate from 146 // punycode. Despite the error, Chrome, Safari and Firefox will attempt 147 // to look up the input punycode. 148 {resolve, encode("a\u0323\u0322") + ".com", "xn--a-tdbc.com", "V1"}, 149 {display, encode("a\u0323\u0322") + ".com", "a\u0323\u0322.com", "V1"}, 150 } 151 152 for _, tc := range testCases { 153 doTest(t, tc.f, tc.name, tc.input, tc.want, tc.wantErr) 154 } 155 } 156 157 func TestTransitionalDefault(t *testing.T) { 158 want := "xn--strae-oqa.de" 159 if transitionalLookup { 160 want = "strasse.de" 161 } 162 doTest(t, Lookup.ToASCII, "Lookup", "straße.de", want, "") 163 }