diff --git a/src/index/suffixarray/suffixarray.go b/src/index/suffixarray/suffixarray.go
index 5541f09..4fced50 100644
--- a/src/index/suffixarray/suffixarray.go
+++ b/src/index/suffixarray/suffixarray.go
@@ -143,9 +143,11 @@
len := data.len()
for p := binary.MaxVarintLen64; p < size; n++ {
x, w := binary.Uvarint(buf[p:])
- // prevent index-out-of-bounds error if data is corrupted
+ // - prevent index-out-of-bounds error if data is corrupted
// (was go.dev/issue/53352)
- if n >= len {
+ // - prevent index-out-of-bounds error in a future Lookup
+ // by ensuring all indices x satisfy x < len
+ if n >= len || x > uint64(len) {
return n, errCorrupted
}
data.set(n, int64(x))
diff --git a/src/index/suffixarray/suffixarray_test.go b/src/index/suffixarray/suffixarray_test.go
index 410f9e8..b2f2787 100644
--- a/src/index/suffixarray/suffixarray_test.go
+++ b/src/index/suffixarray/suffixarray_test.go
@@ -659,6 +659,24 @@
// Reading back the corrupted encoding should report an error.
// Before fixing go.dev/issue/53352, this resulted in an index-out-of-range panic.
if err := index.Read(bytes.NewBuffer(encoding)); err != errCorrupted {
- t.Fatalf("got %q; want %q", err, errCorrupted)
+ t.Fatalf("got %v; want %v", err, errCorrupted)
+ }
+}
+
+func TestIndexCorruption(t *testing.T) {
+ index := New([]byte("x"))
+ var buf bytes.Buffer
+ if err := index.Write(&buf); err != nil {
+ t.Fatal(err)
+ }
+
+ // The index data is at the end of the encoding (see TestIssue53352 for the encoding format).
+ // The encoded indices i must be 0 <= i < len(data) because they are used to index into the
+ // data. Corrupt one and make sure we get an error when reading the encoding.
+ buf.Bytes()[buf.Len()-1] = 100
+
+ // Reading back the corrupted encoding should report an error.
+ if err := index.Read(&buf); err != errCorrupted {
+ t.Fatalf("got %v; want %v", err, errCorrupted)
}
}