internal/coverage/slicewriter: fix off-by-1 error in seek utilities

The slicewriter Seek method was being too restrictive on offsets
accepted, due to an off-by-one problem in the error checking code.
This fixes the problem and touches up the unit tests.

Change-Id: I75d6121551de19ec9275f0e331810db231db6ea9
Reviewed-on: https://go-review.googlesource.com/c/go/+/488116
Run-TryBot: Than McIntosh <thanm@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Than McIntosh 2023-04-24 10:33:01 -04:00
parent ada0eec827
commit 7b89531860
2 changed files with 10 additions and 7 deletions

View file

@ -38,21 +38,21 @@ func (sws *WriteSeeker) Write(p []byte) (n int, err error) {
func (sws *WriteSeeker) Seek(offset int64, whence int) (int64, error) {
switch whence {
case io.SeekStart:
if sws.off != offset && (offset < 0 || offset >= int64(len(sws.payload))) {
if sws.off != offset && (offset < 0 || offset > int64(len(sws.payload))) {
return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", offset, len(sws.payload))
}
sws.off = offset
return offset, nil
case io.SeekCurrent:
newoff := sws.off + offset
if newoff != sws.off && (newoff < 0 || newoff >= int64(len(sws.payload))) {
if newoff != sws.off && (newoff < 0 || newoff > int64(len(sws.payload))) {
return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", newoff, len(sws.payload))
}
sws.off += offset
return sws.off, nil
case io.SeekEnd:
newoff := int64(len(sws.payload)) + offset
if newoff != sws.off && (newoff < 0 || newoff >= int64(len(sws.payload))) {
if newoff != sws.off && (newoff < 0 || newoff > int64(len(sws.payload))) {
return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", newoff, len(sws.payload))
}
sws.off = newoff

View file

@ -47,12 +47,13 @@ func TestSliceWriter(t *testing.T) {
sleq(t, b, p)
}
sk := func(t *testing.T, ws *WriteSeeker, offset int64, whence int) {
sk := func(t *testing.T, ws *WriteSeeker, offset int64, whence int) int64 {
t.Helper()
_, err := ws.Seek(offset, whence)
off, err := ws.Seek(offset, whence)
if err != nil {
t.Fatalf("unexpected seek error: %v", err)
}
return off
}
wp1 := []byte{1, 2}
@ -80,6 +81,8 @@ func TestSliceWriter(t *testing.T) {
rf(t, ws, []byte{2, 7})
sk(t, ws, -4, io.SeekEnd)
rf(t, ws, []byte{2, 7})
off := sk(t, ws, 0, io.SeekEnd)
sk(t, ws, off, io.SeekStart)
// seek back and overwrite
sk(t, ws, 1, io.SeekStart)
@ -98,7 +101,7 @@ func TestSliceWriter(t *testing.T) {
if err == nil {
t.Fatalf("expected error on invalid -1 seek")
}
_, err = ws.Seek(int64(len(ws.BytesWritten())), io.SeekStart)
_, err = ws.Seek(int64(len(ws.BytesWritten())+1), io.SeekStart)
if err == nil {
t.Fatalf("expected error on invalid %d seek", len(ws.BytesWritten()))
}
@ -108,7 +111,7 @@ func TestSliceWriter(t *testing.T) {
if err == nil {
t.Fatalf("expected error on invalid -1 seek")
}
_, err = ws.Seek(int64(len(ws.BytesWritten())), io.SeekCurrent)
_, err = ws.Seek(int64(len(ws.BytesWritten())+1), io.SeekCurrent)
if err == nil {
t.Fatalf("expected error on invalid %d seek", len(ws.BytesWritten()))
}