]> Cypherpunks repositories - gostls13.git/commitdiff
bufio: don't panic when Scanner sees an impossible Read count
authorIan Lance Taylor <iant@golang.org>
Wed, 25 Mar 2020 03:09:11 +0000 (20:09 -0700)
committerIan Lance Taylor <iant@golang.org>
Wed, 25 Mar 2020 19:16:39 +0000 (19:16 +0000)
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>
src/bufio/scan.go
src/bufio/scan_test.go

index 4e787c4b0a427669527376127ea4140f1386bce5..976b5994eb05a66cd832c846528196088b4aed5d 100644 (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)
index 25682256887daaa0b973e5660ef453ef80713488..ceb813ae8d5938cf05f4dc638c74beb0c0b41019 100644 (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")
+       }
+}