1
0
mirror of https://github.com/golang/go synced 2024-11-23 09:30:03 -07:00

bufio: make Reader.Peek invalidate Unreads

Since Reader.Peek potentially reads from the underlying io.Reader,
discarding previous buffers, UnreadRune and UnreadByte cannot
necessarily work.  Change Peek to invalidate the unread buffers in all
cases (as allowed according to the documentation) and thus prevent
hiding bugs in the caller.

(This change was previoiusly merged and then reverted due concern about
being too close to a release)

Fixes #18556

Change-Id: I9027d75aa834d4b27703f37711ba25de04d89f3c
GitHub-Last-Rev: 917ef1e511
GitHub-Pull-Request: golang/go#28768
Reviewed-on: https://go-review.googlesource.com/c/149297
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Martin Garton 2018-11-13 13:34:42 +00:00 committed by Ian Lance Taylor
parent 9d025bdafe
commit e51b19a993
2 changed files with 21 additions and 0 deletions

View File

@ -128,6 +128,9 @@ func (b *Reader) Peek(n int) ([]byte, error) {
return nil, ErrNegativeCount
}
b.lastByte = -1
b.lastRuneSize = -1
for b.w-b.r < n && b.w-b.r < len(b.buf) && b.err == nil {
b.fill() // b.w-b.r < len(b.buf) => buffer is not full
}

View File

@ -285,6 +285,24 @@ func TestUnreadRune(t *testing.T) {
}
}
func TestNoUnreadRuneAfterPeek(t *testing.T) {
br := NewReader(strings.NewReader("example"))
br.ReadRune()
br.Peek(1)
if err := br.UnreadRune(); err == nil {
t.Error("UnreadRune didn't fail after Peek")
}
}
func TestNoUnreadByteAfterPeek(t *testing.T) {
br := NewReader(strings.NewReader("example"))
br.ReadByte()
br.Peek(1)
if err := br.UnreadByte(); err == nil {
t.Error("UnreadByte didn't fail after Peek")
}
}
func TestUnreadByte(t *testing.T) {
segments := []string{"Hello, ", "world"}
r := NewReader(&StringReader{data: segments})