language: fix off-by-one error
Regions are encoded starting from 1. However, one of the
region-related tables assumed 0-based indices. This
caused a crash when used with ZZ, the largest region.
Fixes golang/go#43834
Change-Id: Iaed6b9d2683cd50504e6d33c8a6df8b21dd1687d
Reviewed-on: https://go-review.googlesource.com/c/text/+/305469
Trust: Marcel van Lohuizen <mpvl@golang.org>
Run-TryBot: Marcel van Lohuizen <mpvl@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Seth Vargo <sethvargo@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/language/gen.go b/language/gen.go
index 445882e..60bdf64 100644
--- a/language/gen.go
+++ b/language/gen.go
@@ -150,7 +150,9 @@
regions := strings.Split(g.Contains, " ")
regionHierarchy[g.Type] = append(regionHierarchy[g.Type], regions...)
}
- regionToGroups := make([]uint8, language.NumRegions)
+ // Regions start at 1, so the slice must be one larger than the number of
+ // regions.
+ regionToGroups := make([]uint8, language.NumRegions+1)
idToIndex := map[string]uint8{}
for i, mv := range lm[0].MatchVariable {
diff --git a/language/match_test.go b/language/match_test.go
index c21b863..a6df3e1 100644
--- a/language/match_test.go
+++ b/language/match_test.go
@@ -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 --git a/language/tables.go b/language/tables.go
index 87e58a0..96b57f6 100644
--- a/language/tables.go
+++ b/language/tables.go
@@ -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