bytes: fix panic in bytes.Buffer.Peek

This change fixed the overlooked offset in bytes.Buffer.Peek.
Otherwise, it will either return wrong result or panic with
"runtime error: slice bounds out of range".

Change-Id: Ic42fd8a27fb9703c51430f298933b91cf0d45451
GitHub-Last-Rev: fb97ebc3b1
GitHub-Pull-Request: golang/go#76165
Reviewed-on: https://go-review.googlesource.com/c/go/+/717640
Reviewed-by: Michael Pratt <mpratt@google.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
This commit is contained in:
Aaron Chen 2025-11-13 01:43:03 +00:00 committed by Gopher Robot
parent 0a569528ea
commit b57962b7c7
2 changed files with 13 additions and 7 deletions

View file

@ -86,7 +86,7 @@ func (b *Buffer) Peek(n int) ([]byte, error) {
if b.Len() < n { if b.Len() < n {
return b.buf[b.off:], io.EOF return b.buf[b.off:], io.EOF
} }
return b.buf[b.off:n], nil return b.buf[b.off : b.off+n], nil
} }
// empty reports whether the unread portion of the buffer is empty. // empty reports whether the unread portion of the buffer is empty.

View file

@ -533,19 +533,25 @@ func TestReadString(t *testing.T) {
var peekTests = []struct { var peekTests = []struct {
buffer string buffer string
skip int
n int n int
expected string expected string
err error err error
}{ }{
{"", 0, "", nil}, {"", 0, 0, "", nil},
{"aaa", 3, "aaa", nil}, {"aaa", 0, 3, "aaa", nil},
{"foobar", 2, "fo", nil}, {"foobar", 0, 2, "fo", nil},
{"a", 2, "a", io.EOF}, {"a", 0, 2, "a", io.EOF},
{"helloworld", 4, 3, "owo", nil},
{"helloworld", 5, 5, "world", nil},
{"helloworld", 5, 6, "world", io.EOF},
{"helloworld", 10, 1, "", io.EOF},
} }
func TestPeek(t *testing.T) { func TestPeek(t *testing.T) {
for _, test := range peekTests { for _, test := range peekTests {
buf := NewBufferString(test.buffer) buf := NewBufferString(test.buffer)
buf.Next(test.skip)
bytes, err := buf.Peek(test.n) bytes, err := buf.Peek(test.n)
if string(bytes) != test.expected { if string(bytes) != test.expected {
t.Errorf("expected %q, got %q", test.expected, bytes) t.Errorf("expected %q, got %q", test.expected, bytes)
@ -553,8 +559,8 @@ func TestPeek(t *testing.T) {
if err != test.err { if err != test.err {
t.Errorf("expected error %v, got %v", test.err, err) t.Errorf("expected error %v, got %v", test.err, err)
} }
if buf.Len() != len(test.buffer) { if buf.Len() != len(test.buffer)-test.skip {
t.Errorf("bad length after peek: %d, want %d", buf.Len(), len(test.buffer)) t.Errorf("bad length after peek: %d, want %d", buf.Len(), len(test.buffer)-test.skip)
} }
} }
} }