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