1
0
mirror of https://github.com/golang/go synced 2024-11-17 07:04:44 -07:00

bufio: don't panic when Scanner sees an impossible Read count

Fixes #38053

Change-Id: Ib0f9777f37eeaa07eb8ecb6df3e97e9d4b46dcd8
Reviewed-on: https://go-review.googlesource.com/c/go/+/225357
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
Ian Lance Taylor 2020-03-24 20:09:11 -07:00
parent fcb8f8384a
commit b878d8db66
2 changed files with 59 additions and 0 deletions

View File

@ -211,6 +211,10 @@ func (s *Scanner) Scan() bool {
// be extra careful: Scanner is for safe, simple jobs.
for loop := 0; ; {
n, err := s.r.Read(s.buf[s.end:len(s.buf)])
if n < 0 || n > len(s.buf)-s.end {
n = 0
err = errors.New("bufio.Scanner: Read returned impossible count")
}
s.end += n
if err != nil {
s.setErr(err)

View File

@ -537,3 +537,58 @@ func TestHugeBuffer(t *testing.T) {
t.Fatal("after scan:", s.Err())
}
}
// negativeEOFReader returns an invalid -1 at the end, as though it
// were wrapping the read system call.
type negativeEOFReader int
func (r *negativeEOFReader) Read(p []byte) (int, error) {
if *r > 0 {
c := int(*r)
if c > len(p) {
c = len(p)
}
for i := 0; i < c; i++ {
p[i] = 'a'
}
p[c-1] = '\n'
*r -= negativeEOFReader(c)
return c, nil
}
return -1, io.EOF
}
// Test that the scanner doesn't panic on a reader that returns a
// negative count of bytes read (issue 38053).
func TestNegativeEOFReader(t *testing.T) {
r := negativeEOFReader(10)
scanner := NewScanner(&r)
c := 0
for scanner.Scan() {
c++
if c > 1 {
t.Error("read too many lines")
break
}
}
if scanner.Err() == nil {
t.Error("scanner.Err returned nil, expected an error")
}
}
// largeReader returns an invalid count that is larger than the number
// of bytes requested.
type largeReader struct{}
func (largeReader) Read(p []byte) (int, error) {
return len(p) + 1, nil
}
func TestLargeReader(t *testing.T) {
scanner := NewScanner(largeReader{})
for scanner.Scan() {
}
if scanner.Err() == nil {
t.Error("scanner.Err returned nil, expected an error")
}
}