Package: release.debian.org
Severity: normal
User: release.debian....@packages.debian.org
Usertags: unblock
X-Debbugs-Cc: z...@debian.org

Please unblock package golang-golang-x-text

[ Reason ]
New upstream bugfix release, which fixes
1. CVE-2020-28851 In x/text in Go 1.15.4, an "index out of range" panic occurs
   in language.ParseAcceptLanguage while parsing the -u- extension.
   (x/text/language is supposed to be able to parse an HTTP Accept-Language
   header.)
2. x/text: panic in regionGroupDist
   https://github.com/golang/go/issues/43834

The package is key package, thus it needs unblock manually.

[ Impact ]
Security issue is not fixed.

[ Tests ]
Upstream thorough unit tests.

[ Risks ]
The change of the code is complex which I can't fully reviewed, but
since it fixes security problem, it may should be complex.
The code is reviewed by official Go team, and I trust them.

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing

[ Other info ]
There are only three commits between 0.3.5 and 0.3.6
https://github.com/golang/text/compare/v0.3.5...v0.3.6
Two commits fix the issue mentioned above. And another one is code format,
which unfortunately makes the diff quite large.
I will omit the format change in debdiff attached in this request.


unblock golang-golang-x-text/0.3.6-1


diff -Nru golang-golang-x-text-0.3.5/debian/changelog 
golang-golang-x-text-0.3.6/debian/changelog
--- golang-golang-x-text-0.3.5/debian/changelog 2021-01-19 02:11:19.000000000 
+0800
+++ golang-golang-x-text-0.3.6/debian/changelog 2021-04-07 02:18:47.000000000 
+0800
@@ -1,3 +1,10 @@
+golang-golang-x-text (0.3.6-1) unstable; urgency=medium
+
+  * Team upload.
+  * New upstream release v0.3.6 (Closes: #980001, CVE-2020-28851)
+
+ -- Shengjing Zhu <z...@debian.org>  Wed, 07 Apr 2021 02:18:47 +0800
+
 golang-golang-x-text (0.3.5-1) unstable; urgency=medium
 
   * Team upload.
diff -Nru golang-golang-x-text-0.3.5/debian/control 
golang-golang-x-text-0.3.6/debian/control
--- golang-golang-x-text-0.3.5/debian/control   2021-01-19 02:11:19.000000000 
+0800
+++ golang-golang-x-text-0.3.6/debian/control   2021-04-07 02:18:47.000000000 
+0800
@@ -1,13 +1,13 @@
 Source: golang-golang-x-text
 Maintainer: Debian Go Packaging Team <team+pkg...@tracker.debian.org>
 Uploaders: Martín Ferrari <tin...@debian.org>,
-           Anthony Fok <f...@debian.org>
+           Anthony Fok <f...@debian.org>,
 Section: golang
 Testsuite: autopkgtest-pkg-go
 Priority: optional
 Build-Depends: debhelper-compat (= 13),
                dh-golang (>= 1.31~),
-               golang-any (>= 2:1.7~)
+               golang-any (>= 2:1.7~),
 Standards-Version: 4.5.1
 Vcs-Browser: https://salsa.debian.org/go-team/packages/golang-golang-x-text
 Vcs-Git: https://salsa.debian.org/go-team/packages/golang-golang-x-text.git
@@ -18,8 +18,8 @@
 Package: golang-golang-x-text-dev
 Architecture: all
 Multi-Arch: foreign
-Depends: ${shlibs:Depends},
-         ${misc:Depends}
+Depends: ${misc:Depends},
+         ${shlibs:Depends},
 Description: Supplementary Go text-related libraries
  golang.org/x/text is a repository of text-related packages, such as character
  encodings, text transformations, and locale-specific text handling.
diff -Nru golang-golang-x-text-0.3.5/debian/watch 
golang-golang-x-text-0.3.6/debian/watch
--- golang-golang-x-text-0.3.5/debian/watch     2021-01-19 02:11:19.000000000 
+0800
+++ golang-golang-x-text-0.3.6/debian/watch     2021-04-07 02:18:47.000000000 
+0800
@@ -1,4 +1,3 @@
 version=4
-opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%golang-golang-x-text-$1.tar.gz%"
 \
-    https://github.com/golang/text/releases \
-    (?:.*?/)?v?(\d[\d.]*)\.tar\.gz
+opts="mode=git, pgpmode=none" \
+  https://github.com/golang/text refs/tags/v([\d\.]+)
diff -Nru golang-golang-x-text-0.3.5/internal/language/language.go 
golang-golang-x-text-0.3.6/internal/language/language.go
--- golang-golang-x-text-0.3.5/internal/language/language.go    2020-12-08 
08:13:44.000000000 +0800
+++ golang-golang-x-text-0.3.6/internal/language/language.go    2021-03-30 
13:48:03.000000000 +0800
@@ -303,9 +303,17 @@
 // are of the allowed values defined for the Unicode locale extension ('u') in
 // 
https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.
 // TypeForKey will traverse the inheritance chain to get the correct value.
+//
+// If there are multiple types associated with a key, only the first will be
+// returned. If there is no type associated with a key, it returns the empty
+// string.
 func (t Tag) TypeForKey(key string) string {
-       if start, end, _ := t.findTypeForKey(key); end != start {
-               return t.str[start:end]
+       if _, start, end, _ := t.findTypeForKey(key); end != start {
+               s := t.str[start:end]
+               if p := strings.IndexByte(s, '-'); p >= 0 {
+                       s = s[:p]
+               }
+               return s
        }
        return ""
 }
@@ -329,13 +337,13 @@
 
        // Remove the setting if value is "".
        if value == "" {
-               start, end, _ := t.findTypeForKey(key)
-               if start != end {
-                       // Remove key tag and leading '-'.
-                       start -= 4
-
+               start, sep, end, _ := t.findTypeForKey(key)
+               if start != sep {
                        // Remove a possible empty extension.
-                       if (end == len(t.str) || t.str[end+2] == '-') && 
t.str[start-2] == '-' {
+                       switch {
+                       case t.str[start-2] != '-': // has previous elements.
+                       case end == len(t.str), // end of string
+                               end+2 < len(t.str) && t.str[end+2] == '-': // 
end of extension
                                start -= 2
                        }
                        if start == int(t.pVariant) && end == len(t.str) {
@@ -381,14 +389,14 @@
                t.str = string(buf[:uStart+len(b)])
        } else {
                s := t.str
-               start, end, hasExt := t.findTypeForKey(key)
-               if start == end {
+               start, sep, end, hasExt := t.findTypeForKey(key)
+               if start == sep {
                        if hasExt {
                                b = b[2:]
                        }
-                       t.str = fmt.Sprintf("%s-%s%s", s[:start], b, s[end:])
+                       t.str = fmt.Sprintf("%s-%s%s", s[:sep], b, s[end:])
                } else {
-                       t.str = fmt.Sprintf("%s%s%s", s[:start], value, s[end:])
+                       t.str = fmt.Sprintf("%s-%s%s", s[:start+3], value, 
s[end:])
                }
        }
        return t, nil
@@ -399,10 +407,10 @@
 // wasn't found. The hasExt return value reports whether an -u extension was 
present.
 // Note: the extensions are typically very small and are likely to contain
 // only one key-type pair.
-func (t Tag) findTypeForKey(key string) (start, end int, hasExt bool) {
+func (t Tag) findTypeForKey(key string) (start, sep, end int, hasExt bool) {
        p := int(t.pExt)
        if len(key) != 2 || p == len(t.str) || p == 0 {
-               return p, p, false
+               return p, p, p, false
        }
        s := t.str
 
@@ -410,10 +418,10 @@
        for p++; s[p] != 'u'; p++ {
                if s[p] > 'u' {
                        p--
-                       return p, p, false
+                       return p, p, p, false
                }
                if p = nextExtension(s, p); p == len(s) {
-                       return len(s), len(s), false
+                       return len(s), len(s), len(s), false
                }
        }
        // Proceed to the hyphen following the extension name.
@@ -424,40 +432,28 @@
 
        // Iterate over keys until we get the end of a section.
        for {
-               // p points to the hyphen preceding the current token.
-               if p3 := p + 3; s[p3] == '-' {
-                       // Found a key.
-                       // Check whether we just processed the key that was 
requested.
-                       if curKey == key {
-                               return start, p, true
-                       }
-                       // Set to the next key and continue scanning type 
tokens.
-                       curKey = s[p+1 : p3]
-                       if curKey > key {
-                               return p, p, true
-                       }
-                       // Start of the type token sequence.
-                       start = p + 4
-                       // A type is at least 3 characters long.
-                       p += 7 // 4 + 3
-               } else {
-                       // Attribute or type, which is at least 3 characters 
long.
-                       p += 4
+               end = p
+               for p++; p < len(s) && s[p] != '-'; p++ {
                }
-               // p points past the third character of a type or attribute.
-               max := p + 5 // maximum length of token plus hyphen.
-               if len(s) < max {
-                       max = len(s)
-               }
-               for ; p < max && s[p] != '-'; p++ {
-               }
-               // Bail if we have exhausted all tokens or if the next token 
starts
-               // a new extension.
-               if p == len(s) || s[p+2] == '-' {
-                       if curKey == key {
-                               return start, p, true
+               n := p - end - 1
+               if n <= 2 && curKey == key {
+                       if sep < end {
+                               sep++
+                       }
+                       return start, sep, end, true
+               }
+               switch n {
+               case 0, // invalid string
+                       1: // next extension
+                       return end, end, end, true
+               case 2:
+                       // next key
+                       curKey = s[end+1 : p]
+                       if curKey > key {
+                               return end, end, end, true
                        }
-                       return p, p, true
+                       start = end
+                       sep = p
                }
        }
 }
diff -Nru golang-golang-x-text-0.3.5/internal/language/language_test.go 
golang-golang-x-text-0.3.6/internal/language/language_test.go
--- golang-golang-x-text-0.3.5/internal/language/language_test.go       
2020-12-08 08:13:44.000000000 +0800
+++ golang-golang-x-text-0.3.6/internal/language/language_test.go       
2021-03-30 13:48:03.000000000 +0800
@@ -432,7 +432,9 @@
                {"co", "pinyin", "en-u-co-phonebk-cu-xau", 
"en-u-co-pinyin-cu-xau", false},
                {"co", "pinyin", "en-u-co-phonebk-v-xx", "en-u-co-pinyin-v-xx", 
false},
                {"co", "pinyin", "en-u-co-phonebk-x-x", "en-u-co-pinyin-x-x", 
false},
+               {"co", "pinyin", "en-u-co-x-x", "en-u-co-pinyin-x-x", false},
                {"nu", "arabic", "en-u-co-phonebk-nu-vaai", 
"en-u-co-phonebk-nu-arabic", false},
+               {"nu", "arabic", "en-u-co-phonebk-nu", 
"en-u-co-phonebk-nu-arabic", false},
                // add to existing -u extension
                {"co", "pinyin", "en-u-ca-gregory", 
"en-u-ca-gregory-co-pinyin", false},
                {"co", "pinyin", "en-u-ca-gregory-nu-vaai", 
"en-u-ca-gregory-co-pinyin-nu-vaai", false},
@@ -441,8 +443,12 @@
                {"ca", "gregory", "en-u-co-pinyin", 
"en-u-ca-gregory-co-pinyin", false},
                // remove pair
                {"co", "", "en-u-co-phonebk", "en", false},
+               {"co", "", "en-u-co", "en", false},
+               {"co", "", "en-u-co-v", "en", false},
+               {"co", "", "en-u-co-v-", "en", false},
                {"co", "", "en-u-ca-gregory-co-phonebk", "en-u-ca-gregory", 
false},
                {"co", "", "en-u-co-phonebk-nu-arabic", "en-u-nu-arabic", 
false},
+               {"co", "", "en-u-co-nu-arabic", "en-u-nu-arabic", false},
                {"co", "", "en", "en", false},
                // add -u extension
                {"co", "pinyin", "en", "en-u-co-pinyin", false},
@@ -504,6 +510,8 @@
                {"cu", false, "en-a-va-v-va", "en-a-va"},
                {"cu", false, "en-x-a", "en"},
                // Tags with the -u extension.
+               {"nu", true, "en-u-cu-nu", "en-u-cu"},
+               {"cu", true, "en-u-cu-nu", "en-u"},
                {"co", true, "en-u-co-standard", "standard"},
                {"co", true, "yue-u-co-pinyin", "pinyin"},
                {"co", true, "en-u-co-abc", "abc"},
@@ -519,9 +527,9 @@
                {"cu", true, "en-u-co-abc-def-nu-arabic", "en-u-co-abc-def"},
        }
        for i, tt := range tests {
-               start, end, hasExt := Make(tt.in).findTypeForKey(tt.key)
-               if start != end {
-                       res := tt.in[start:end]
+               start, sep, end, hasExt := Make(tt.in).findTypeForKey(tt.key)
+               if sep != end {
+                       res := tt.in[sep:end]
                        if res != tt.out {
                                t.Errorf("%d:%s: was %q; want %q", i, tt.in, 
res, tt.out)
                        }
diff -Nru golang-golang-x-text-0.3.5/internal/language/parse.go 
golang-golang-x-text-0.3.6/internal/language/parse.go
--- golang-golang-x-text-0.3.5/internal/language/parse.go       2020-12-08 
08:13:44.000000000 +0800
+++ golang-golang-x-text-0.3.6/internal/language/parse.go       2021-03-30 
13:48:03.000000000 +0800
@@ -138,7 +138,7 @@
                        b = make([]byte, n)
                        copy(b, s.b[:oldStart])
                } else {
-                       b = s.b[:n:n]
+                       b = s.b[:n]
                }
                copy(b[end:], s.b[oldEnd:])
                s.b = b
@@ -483,7 +483,7 @@
 func parseExtension(scan *scanner) int {
        start, end := scan.start, scan.end
        switch scan.token[0] {
-       case 'u':
+       case 'u': // https://www.ietf.org/rfc/rfc6067.txt
                attrStart := end
                scan.scan()
                for last := []byte{}; len(scan.token) > 2; scan.scan() {
@@ -503,27 +503,29 @@
                        last = scan.token
                        end = scan.end
                }
+               // Scan key-type sequences. A key is of length 2 and may be 
followed
+               // by 0 or more "type" subtags from 3 to the maximum of 8 
letters.
                var last, key []byte
                for attrEnd := end; len(scan.token) == 2; last = key {
                        key = scan.token
-                       keyEnd := scan.end
-                       end = scan.acceptMinSize(3)
+                       end = scan.end
+                       for scan.scan(); end < scan.end && len(scan.token) > 2; 
scan.scan() {
+                               end = scan.end
+                       }
                        // TODO: check key value validity
-                       if keyEnd == end || bytes.Compare(key, last) != 1 {
+                       if bytes.Compare(key, last) != 1 || scan.err != nil {
                                // We have an invalid key or the keys are not 
sorted.
                                // Start scanning keys from scratch and reorder.
                                p := attrEnd + 1
                                scan.next = p
                                keys := [][]byte{}
                                for scan.scan(); len(scan.token) == 2; {
-                                       keyStart, keyEnd := scan.start, scan.end
-                                       end = scan.acceptMinSize(3)
-                                       if keyEnd != end {
-                                               keys = append(keys, 
scan.b[keyStart:end])
-                                       } else {
-                                               scan.setError(ErrSyntax)
-                                               end = keyStart
+                                       keyStart := scan.start
+                                       end = scan.end
+                                       for scan.scan(); end < scan.end && 
len(scan.token) > 2; scan.scan() {
+                                               end = scan.end
                                        }
+                                       keys = append(keys, 
scan.b[keyStart:end])
                                }
                                sort.Stable(bytesSort{keys, 2})
                                if n := len(keys); n > 0 {
@@ -547,7 +549,7 @@
                                break
                        }
                }
-       case 't':
+       case 't': // https://www.ietf.org/rfc/rfc6497.txt
                scan.scan()
                if n := len(scan.token); n >= 2 && n <= 3 && 
isAlpha(scan.token[1]) {
                        _, end = parseTag(scan)
diff -Nru golang-golang-x-text-0.3.5/internal/language/parse_test.go 
golang-golang-x-text-0.3.6/internal/language/parse_test.go
--- golang-golang-x-text-0.3.5/internal/language/parse_test.go  2020-12-08 
08:13:44.000000000 +0800
+++ golang-golang-x-text-0.3.6/internal/language/parse_test.go  2021-03-30 
13:48:03.000000000 +0800
@@ -164,13 +164,13 @@
                {in: "en-9-aa-0-aa-z-bb-x-a", lang: "en", extList: 
[]string{"0-aa", "9-aa", "z-bb", "x-a"}, changed: true},
                {in: "en-u-c", lang: "en", ext: "", invalid: true},
                {in: "en-u-co-phonebk", lang: "en", ext: "u-co-phonebk"},
-               {in: "en-u-co-phonebk-ca", lang: "en", ext: "u-co-phonebk", 
invalid: true},
-               {in: "en-u-nu-arabic-co-phonebk-ca", lang: "en", ext: 
"u-co-phonebk-nu-arabic", invalid: true, changed: true},
-               {in: "en-u-nu-arabic-co-phonebk-ca-x", lang: "en", ext: 
"u-co-phonebk-nu-arabic", invalid: true, changed: true},
-               {in: "en-u-nu-arabic-co-phonebk-ca-s", lang: "en", ext: 
"u-co-phonebk-nu-arabic", invalid: true, changed: true},
-               {in: "en-u-nu-arabic-co-phonebk-ca-a12345678", lang: "en", ext: 
"u-co-phonebk-nu-arabic", invalid: true, changed: true},
-               {in: "en-u-co-phonebook", lang: "en", ext: "", invalid: true},
-               {in: "en-u-co-phonebook-cu-xau", lang: "en", ext: "u-cu-xau", 
invalid: true, changed: true},
+               {in: "en-u-co-phonebk-ca", lang: "en", ext: "u-ca-co-phonebk", 
changed: true},
+               {in: "en-u-nu-arabic-co-phonebk-ca", lang: "en", ext: 
"u-ca-co-phonebk-nu-arabic", changed: true},
+               {in: "en-u-nu-arabic-co-phonebk-ca-x", lang: "en", ext: 
"u-ca-co-phonebk-nu-arabic", invalid: true, changed: true},
+               {in: "en-u-nu-arabic-co-phonebk-ca-s", lang: "en", ext: 
"u-ca-co-phonebk-nu-arabic", invalid: true, changed: true},
+               {in: "en-u-nu-arabic-co-phonebk-ca-a12345678", lang: "en", ext: 
"u-ca-co-phonebk-nu-arabic", invalid: true, changed: true},
+               {in: "en-u-co-phonebook", lang: "en", ext: "u-co", invalid: 
true},
+               {in: "en-u-co-phonebook-cu-xau", lang: "en", ext: 
"u-co-cu-xau", invalid: true, changed: true},
                {in: "en-Cyrl-u-co-phonebk", lang: "en", script: "Cyrl", ext: 
"u-co-phonebk"},
                {in: "en-US-u-co-phonebk", lang: "en", region: "US", ext: 
"u-co-phonebk"},
                {in: "en-US-u-co-phonebk-cu-xau", lang: "en", region: "US", 
ext: "u-co-phonebk-cu-xau"},
@@ -179,9 +179,8 @@
                {in: "en-u-def-abc-cu-xua-co-phonebk", lang: "en", ext: 
"u-abc-def-co-phonebk-cu-xua", changed: true},
                {in: "en-u-def-abc", lang: "en", ext: "u-abc-def", changed: 
true},
                {in: "en-u-cu-xua-co-phonebk-a-cd", lang: "en", extList: 
[]string{"a-cd", "u-co-phonebk-cu-xua"}, changed: true},
-               // Invalid "u" extension. Drop invalid parts.
-               {in: "en-u-cu-co-phonebk", lang: "en", extList: 
[]string{"u-co-phonebk"}, invalid: true, changed: true},
-               {in: "en-u-cu-xau-co", lang: "en", extList: 
[]string{"u-cu-xau"}, invalid: true},
+               {in: "en-u-cu-co-phonebk", lang: "en", extList: 
[]string{"u-co-phonebk-cu"}, changed: true},
+               {in: "en-u-cu-xau-co", lang: "en", extList: 
[]string{"u-co-cu-xau"}, changed: true},
                // LDML spec is not specific about it, but remove duplicates 
and return an error if the values differ.
                {in: "en-u-cu-xau-co-phonebk-cu-xau", lang: "en", ext: 
"u-co-phonebk-cu-xau", changed: true},
                // No change as the result is a substring of the original!
@@ -351,8 +350,8 @@
                {"aa-AB", mkInvalid("AB")},
                // ill-formed wins over invalid.
                {"ac-u", ErrSyntax},
-               {"ac-u-ca", ErrSyntax},
-               {"ac-u-ca-co-pinyin", ErrSyntax},
+               {"ac-u-ca", mkInvalid("ac")},
+               {"ac-u-ca-co-pinyin", mkInvalid("ac")},
                {"noob", ErrSyntax},
        }
        for _, tt := range tests {
diff -Nru golang-golang-x-text-0.3.5/language/language.go 
golang-golang-x-text-0.3.6/language/language.go
--- golang-golang-x-text-0.3.5/language/language.go     2020-12-08 
08:13:44.000000000 +0800
+++ golang-golang-x-text-0.3.6/language/language.go     2021-03-30 
13:48:03.000000000 +0800
@@ -412,6 +412,10 @@
 // are of the allowed values defined for the Unicode locale extension ('u') in
 // 
https://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers.
 // TypeForKey will traverse the inheritance chain to get the correct value.
+//
+// If there are multiple types associated with a key, only the first will be
+// returned. If there is no type associated with a key, it returns the empty
+// string.
 func (t Tag) TypeForKey(key string) string {
        if !compact.Tag(t).MayHaveExtensions() {
                if key != "rg" && key != "va" {
diff -Nru golang-golang-x-text-0.3.5/language/language_test.go 
golang-golang-x-text-0.3.6/language/language_test.go
--- golang-golang-x-text-0.3.5/language/language_test.go        2020-12-08 
08:13:44.000000000 +0800
+++ golang-golang-x-text-0.3.6/language/language_test.go        2021-03-30 
13:48:03.000000000 +0800
@@ -523,6 +523,13 @@
                {"en-GB-u-rg-usz", "en-GB-u-rg-usz", Raw},
                {"en-GB-u-rg-usz-va-posix", "en-GB-u-rg-usz-va-posix", Raw},
                {"en-GB-u-rg-usz-co-phonebk", "en-GB-u-co-phonebk-rg-usz", Raw},
+
+               // CVE-2020-28851
+               // invalid key-value pair of -u- extension.
+               {"ES-u-000-00", "es-u-000-00", Raw},
+               {"ES-u-000-00-v-00", "es-u-000-00-v-00", Raw},
+               // reordered and unknown extension.
+               {"ES-v-00-u-000-00", "es-u-000-00-v-00", Raw},
        }
        for i, tt := range tests {
                in, _ := Raw.Parse(tt.in)
@@ -553,6 +560,12 @@
                {"rg", "en-u-rg-gbzzzz", "gbzzzz"},
                {"nu", "en-u-co-phonebk-nu-arabic", "arabic"},
                {"kc", "cmn-u-co-stroke", ""},
+               {"rg", "cmn-u-rg", ""},
+               {"rg", "cmn-u-rg-co-stroke", ""},
+               {"co", "cmn-u-rg-co-stroke", "stroke"},
+               {"co", "cmn-u-co-rg-gbzzzz", ""},
+               {"rg", "cmn-u-co-rg-gbzzzz", "gbzzzz"},
+               {"rg", "cmn-u-rg-gbzzzz-nlzzzz", "gbzzzz"},
        }
        for _, tt := range tests {
                if v := Make(tt.in).TypeForKey(tt.key); v != tt.out {
diff -Nru golang-golang-x-text-0.3.5/language/match_test.go 
golang-golang-x-text-0.3.6/language/match_test.go
--- golang-golang-x-text-0.3.5/language/match_test.go   2020-12-08 
08:13:44.000000000 +0800
+++ golang-golang-x-text-0.3.6/language/match_test.go   2021-03-30 
13:48:03.000000000 +0800
@@ -224,6 +224,20 @@
        return fmt.Sprintf("%v:%d:%v:%v-%v|%v", t.tag, t.index, t.conf, 
t.maxRegion, t.maxScript, t.altScript)
 }
 
+func TestIssue43834(t *testing.T) {
+       matcher := NewMatcher([]Tag{English})
+
+       // ZZ is the largest region code and should not cause overflow.
+       desired, _, err := ParseAcceptLanguage("en-ZZ")
+       if err != nil {
+               t.Error(err)
+       }
+       _, i, _ := matcher.Match(desired...)
+       if i != 0 {
+               t.Errorf("got %v; want 0", i)
+       }
+}
+
 func TestBestMatchAlloc(t *testing.T) {
        m := NewMatcher(makeTagList("en sr nl"))
        // Go allocates when creating a list of tags from a single tag!
diff -Nru golang-golang-x-text-0.3.5/language/parse_test.go 
golang-golang-x-text-0.3.6/language/parse_test.go
--- golang-golang-x-text-0.3.5/language/parse_test.go   2020-12-08 
08:13:44.000000000 +0800
+++ golang-golang-x-text-0.3.6/language/parse_test.go   2021-03-30 
13:48:03.000000000 +0800
@@ -101,13 +101,13 @@
                {in: "en-9-aa-0-aa-z-bb-x-a", lang: "en", extList: 
[]string{"0-aa", "9-aa", "z-bb", "x-a"}, changed: true},
                {in: "en-u-c", lang: "en", ext: "", invalid: true},
                {in: "en-u-co-phonebk", lang: "en", ext: "u-co-phonebk"},
-               {in: "en-u-co-phonebk-ca", lang: "en", ext: "u-co-phonebk", 
invalid: true},
-               {in: "en-u-nu-arabic-co-phonebk-ca", lang: "en", ext: 
"u-co-phonebk-nu-arabic", invalid: true, changed: true},
-               {in: "en-u-nu-arabic-co-phonebk-ca-x", lang: "en", ext: 
"u-co-phonebk-nu-arabic", invalid: true, changed: true},
-               {in: "en-u-nu-arabic-co-phonebk-ca-s", lang: "en", ext: 
"u-co-phonebk-nu-arabic", invalid: true, changed: true},
-               {in: "en-u-nu-arabic-co-phonebk-ca-a12345678", lang: "en", ext: 
"u-co-phonebk-nu-arabic", invalid: true, changed: true},
-               {in: "en-u-co-phonebook", lang: "en", ext: "", invalid: true},
-               {in: "en-u-co-phonebook-cu-xau", lang: "en", ext: "u-cu-xau", 
invalid: true, changed: true},
+               {in: "en-u-co-phonebk-ca", lang: "en", ext: "u-ca-co-phonebk", 
invalid: true},
+               {in: "en-u-nu-arabic-co-phonebk-ca", lang: "en", ext: 
"u-ca-co-phonebk-nu-arabic", invalid: true, changed: true},
+               {in: "en-u-nu-arabic-co-phonebk-ca-x", lang: "en", ext: 
"u-ca-co-phonebk-nu-arabic", invalid: true, changed: true},
+               {in: "en-u-nu-arabic-co-phonebk-ca-s", lang: "en", ext: 
"u-ca-co-phonebk-nu-arabic", invalid: true, changed: true},
+               {in: "en-u-nu-arabic-co-phonebk-ca-a12345678", lang: "en", ext: 
"u-ca-co-phonebk-nu-arabic", invalid: true, changed: true},
+               {in: "en-u-co-phonebook", lang: "en", ext: "u-co", invalid: 
true},
+               {in: "en-u-co-phonebook-cu-xau", lang: "en", ext: 
"u-co-cu-xau", invalid: true, changed: true},
                {in: "en-Cyrl-u-co-phonebk", lang: "en", script: "Cyrl", ext: 
"u-co-phonebk"},
                {in: "en-US-u-co-phonebk", lang: "en", region: "US", ext: 
"u-co-phonebk"},
                {in: "en-US-u-co-phonebk-cu-xau", lang: "en", region: "US", 
ext: "u-co-phonebk-cu-xau"},
@@ -117,8 +117,8 @@
                {in: "en-u-def-abc", lang: "en", ext: "u-abc-def", changed: 
true},
                {in: "en-u-cu-xua-co-phonebk-a-cd", lang: "en", extList: 
[]string{"a-cd", "u-co-phonebk-cu-xua"}, changed: true},
                // Invalid "u" extension. Drop invalid parts.
-               {in: "en-u-cu-co-phonebk", lang: "en", extList: 
[]string{"u-co-phonebk"}, invalid: true, changed: true},
-               {in: "en-u-cu-xau-co", lang: "en", extList: 
[]string{"u-cu-xau"}, invalid: true},
+               {in: "en-u-cu-co-phonebk", lang: "en", extList: 
[]string{"u-co-phonebk-cu"}, invalid: true, changed: true},
+               {in: "en-u-cu-xau-co", lang: "en", extList: 
[]string{"u-co-cu-xau"}, invalid: true},
                // We allow duplicate keys as the LDML spec does not explicitly 
prohibit it.
                // TODO: Consider eliminating duplicates and returning an error.
                {in: "en-u-cu-xau-co-phonebk-cu-xau", lang: "en", ext: 
"u-co-phonebk-cu-xau", changed: true},
@@ -219,8 +219,8 @@
                {"aa-AB", mkInvalid("AB")},
                // ill-formed wins over invalid.
                {"ac-u", errSyntax},
-               {"ac-u-ca", errSyntax},
-               {"ac-u-ca-co-pinyin", errSyntax},
+               {"ac-u-ca", mkInvalid("ac")},
+               {"ac-u-ca-co-pinyin", mkInvalid("ac")},
                {"noob", errSyntax},
        }
        for _, tt := range tests {
diff -Nru golang-golang-x-text-0.3.5/language/tables.go 
golang-golang-x-text-0.3.6/language/tables.go
--- golang-golang-x-text-0.3.5/language/tables.go       2020-12-08 
08:13:44.000000000 +0800
+++ golang-golang-x-text-0.3.6/language/tables.go       2021-03-30 
13:48:03.000000000 +0800
@@ -47,7 +47,7 @@
        _Zzzz = 251
 )
 
-var regionToGroups = []uint8{ // 357 elements
+var regionToGroups = []uint8{ // 358 elements
        // Entry 0 - 3F
        0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04,
        0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00,
@@ -98,8 +98,8 @@
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00,
-} // Size: 381 bytes
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+} // Size: 382 bytes
 
 var paradigmLocales = [][3]uint16{ // 3 elements
        0: [3]uint16{0x139, 0x0, 0x7b},
@@ -295,4 +295,4 @@
        14: {lang: 0x529, script: 0x3c, group: 0x80, distance: 0x5},
 } // Size: 114 bytes
 
-// Total table size 1471 bytes (1KiB); checksum: 4CB1CD46
+// Total table size 1472 bytes (1KiB); checksum: F86C669

Reply via email to