mirror of
https://github.com/golang/go.git
synced 2026-06-28 03:40:37 +00:00
index/suffixarray: fix incorrect condition
CL 771782 introduced an extra index verification when reading in suffixarray indices. However, instead of testing against the overall suffixarray length, the condition checked against the (current) slice length which may be smaller than the indexarray length. This resulted in an error being reported when benchmarking a larger suffixarray that recorded its data using multiple data slices. The benchmark itself was not expecting an error and instead responded with a panic. Fix the condition by testing against the correct length. Also, adjust the testSaveRestore signature so we can pass in non-nil values so that the benchmark reports an error rather than panicking (before the bug fix). Fixes #79207. Change-Id: I523944ab1b133641e045a35435af6b6e2feed05d Reviewed-on: https://go-review.googlesource.com/c/go/+/774482 Reviewed-by: Robert Griesemer <gri@google.com> Reviewed-by: Keith Randall <khr@golang.org> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Robert Griesemer <gri@google.com> Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
parent
628674a0c1
commit
07840ceeed
2 changed files with 8 additions and 7 deletions
|
|
@ -119,9 +119,9 @@ func writeSlice(w io.Writer, buf []byte, data ints) (n int, err error) {
|
|||
|
||||
var errCorrupted = errors.New("suffixarray: data corrupted")
|
||||
|
||||
// readSlice reads data[:n] from r and returns n.
|
||||
// readSlice reads data[:n] from r and returns n; maxIndex is the length of the suffix array.
|
||||
// It uses buf to buffer the read.
|
||||
func readSlice(r io.Reader, buf []byte, data ints) (n int, err error) {
|
||||
func readSlice(r io.Reader, buf []byte, data ints, maxIndex uint64) (n int, err error) {
|
||||
// read buffer size
|
||||
var size64 int64
|
||||
size64, err = readInt(r, buf)
|
||||
|
|
@ -146,8 +146,8 @@ func readSlice(r io.Reader, buf []byte, data ints) (n int, err error) {
|
|||
// - prevent index-out-of-bounds panic if there are more indices than expected
|
||||
// (was go.dev/issue/53352)
|
||||
// - prevent index-out-of-bounds panic in a future Lookup
|
||||
// by ensuring all indices x satisfy x < len
|
||||
if n >= len || x >= uint64(len) {
|
||||
// by ensuring all indices x satisfy x < maxIndex
|
||||
if n >= len || x >= maxIndex {
|
||||
return n, errCorrupted
|
||||
}
|
||||
data.set(n, int64(x))
|
||||
|
|
@ -200,7 +200,7 @@ func (x *Index) Read(r io.Reader) error {
|
|||
// read index
|
||||
sa := x.sa
|
||||
for sa.len() > 0 {
|
||||
n, err := readSlice(r, buf, sa)
|
||||
n, err := readSlice(r, buf, sa, uint64(n))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ func equal(x, y *Index) bool {
|
|||
}
|
||||
|
||||
// returns the serialized index size
|
||||
func testSaveRestore(t *testing.T, tc *testCase, x *Index) int {
|
||||
func testSaveRestore(t testing.TB, tc *testCase, x *Index) int {
|
||||
var buf bytes.Buffer
|
||||
if err := x.Write(&buf); err != nil {
|
||||
t.Errorf("failed writing index %s (%s)", tc.name, err)
|
||||
|
|
@ -590,13 +590,14 @@ func BenchmarkSaveRestore(b *testing.B) {
|
|||
if ^uint(0) == 0xffffffff && bits == 64 {
|
||||
continue
|
||||
}
|
||||
tc := &testCase{name: "BenchmarkSaveRestore"}
|
||||
b.Run(fmt.Sprintf("bits=%d", bits), func(b *testing.B) {
|
||||
cleanup := setBits(bits)
|
||||
defer cleanup()
|
||||
|
||||
b.StopTimer()
|
||||
x := New(data)
|
||||
size := testSaveRestore(nil, nil, x) // verify correctness
|
||||
size := testSaveRestore(b, tc, x) // verify correctness
|
||||
buf := bytes.NewBuffer(make([]byte, size)) // avoid growing
|
||||
b.SetBytes(int64(size))
|
||||
b.StartTimer()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue