Skip to content

Commit 7b89531

Browse files
committed
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 <[email protected]> Reviewed-by: Cherry Mui <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent ada0eec commit 7b89531

File tree

2 files changed

+10
-7
lines changed

2 files changed

+10
-7
lines changed

src/internal/coverage/slicewriter/slicewriter.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,21 @@ func (sws *WriteSeeker) Write(p []byte) (n int, err error) {
3838
func (sws *WriteSeeker) Seek(offset int64, whence int) (int64, error) {
3939
switch whence {
4040
case io.SeekStart:
41-
if sws.off != offset && (offset < 0 || offset >= int64(len(sws.payload))) {
41+
if sws.off != offset && (offset < 0 || offset > int64(len(sws.payload))) {
4242
return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", offset, len(sws.payload))
4343
}
4444
sws.off = offset
4545
return offset, nil
4646
case io.SeekCurrent:
4747
newoff := sws.off + offset
48-
if newoff != sws.off && (newoff < 0 || newoff >= int64(len(sws.payload))) {
48+
if newoff != sws.off && (newoff < 0 || newoff > int64(len(sws.payload))) {
4949
return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", newoff, len(sws.payload))
5050
}
5151
sws.off += offset
5252
return sws.off, nil
5353
case io.SeekEnd:
5454
newoff := int64(len(sws.payload)) + offset
55-
if newoff != sws.off && (newoff < 0 || newoff >= int64(len(sws.payload))) {
55+
if newoff != sws.off && (newoff < 0 || newoff > int64(len(sws.payload))) {
5656
return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", newoff, len(sws.payload))
5757
}
5858
sws.off = newoff

src/internal/coverage/slicewriter/slw_test.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,13 @@ func TestSliceWriter(t *testing.T) {
4747
sleq(t, b, p)
4848
}
4949

50-
sk := func(t *testing.T, ws *WriteSeeker, offset int64, whence int) {
50+
sk := func(t *testing.T, ws *WriteSeeker, offset int64, whence int) int64 {
5151
t.Helper()
52-
_, err := ws.Seek(offset, whence)
52+
off, err := ws.Seek(offset, whence)
5353
if err != nil {
5454
t.Fatalf("unexpected seek error: %v", err)
5555
}
56+
return off
5657
}
5758

5859
wp1 := []byte{1, 2}
@@ -80,6 +81,8 @@ func TestSliceWriter(t *testing.T) {
8081
rf(t, ws, []byte{2, 7})
8182
sk(t, ws, -4, io.SeekEnd)
8283
rf(t, ws, []byte{2, 7})
84+
off := sk(t, ws, 0, io.SeekEnd)
85+
sk(t, ws, off, io.SeekStart)
8386

8487
// seek back and overwrite
8588
sk(t, ws, 1, io.SeekStart)
@@ -98,7 +101,7 @@ func TestSliceWriter(t *testing.T) {
98101
if err == nil {
99102
t.Fatalf("expected error on invalid -1 seek")
100103
}
101-
_, err = ws.Seek(int64(len(ws.BytesWritten())), io.SeekStart)
104+
_, err = ws.Seek(int64(len(ws.BytesWritten())+1), io.SeekStart)
102105
if err == nil {
103106
t.Fatalf("expected error on invalid %d seek", len(ws.BytesWritten()))
104107
}
@@ -108,7 +111,7 @@ func TestSliceWriter(t *testing.T) {
108111
if err == nil {
109112
t.Fatalf("expected error on invalid -1 seek")
110113
}
111-
_, err = ws.Seek(int64(len(ws.BytesWritten())), io.SeekCurrent)
114+
_, err = ws.Seek(int64(len(ws.BytesWritten())+1), io.SeekCurrent)
112115
if err == nil {
113116
t.Fatalf("expected error on invalid %d seek", len(ws.BytesWritten()))
114117
}

0 commit comments

Comments
 (0)