[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#986576: marked as done (unblock: golang-golang-x-text/0.3.6-1)



Your message dated Wed, 07 Apr 2021 20:21:18 +0000
with message-id <E1lUEfu-0004iN-EL@respighi.debian.org>
and subject line unblock golang-golang-x-text
has caused the Debian Bug report #986576,
regarding unblock: golang-golang-x-text/0.3.6-1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
986576: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=986576
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock
X-Debbugs-Cc: zhsj@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 <zhsj@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-go@tracker.debian.org>
 Uploaders: Martín Ferrari <tincho@debian.org>,
-           Anthony Fok <foka@debian.org>
+           Anthony Fok <foka@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

--- End Message ---
--- Begin Message ---
Unblocked.

--- End Message ---

Reply to: