[go] push by r@golang.org - bufio.Scan: don't stop after Read returns 0, nil... on 2013-04-19 00:37 GMT

5 views
Skip to first unread message

g...@googlecode.com

unread,
Apr 18, 2013, 8:38:42 PM4/18/13
to golang-...@googlegroups.com
Revision: 13e00572ed0b
Branch: default
Author: Rob Pike <r...@golang.org>
Date: Thu Apr 18 17:37:21 2013
Log: bufio.Scan: don't stop after Read returns 0, nil
But stop eventually if the reader misbehaves.

R=golang-dev, bradfitz
CC=golang-dev
https://codereview.appspot.com/8757045
http://code.google.com/p/go/source/detail?r=13e00572ed0b

Modified:
/src/pkg/bufio/scan.go
/src/pkg/bufio/scan_test.go

=======================================
--- /src/pkg/bufio/scan.go Wed Apr 10 20:58:19 2013
+++ /src/pkg/bufio/scan.go Thu Apr 18 17:37:21 2013
@@ -103,8 +103,7 @@

// Scan advances the Scanner to the next token, which will then be
// available through the Bytes or Text method. It returns false when the
-// scan stops, either by reaching the end of the input, a zero-length
-// read from the input, or an error.
+// scan stops, either by reaching the end of the input or an error.
// After Scan returns false, the Err method will return any error that
// occurred during scanning, except that if it was io.EOF, Err
// will return nil.
@@ -159,15 +158,25 @@
s.start = 0
continue
}
- // Finally we can read some input.
- n, err := s.r.Read(s.buf[s.end:len(s.buf)])
- if err != nil {
- s.setErr(err)
- }
- if n == 0 { // Don't loop forever if Reader doesn't deliver EOF.
- s.setErr(io.EOF)
+ // Finally we can read some input. Make sure we don't get stuck with
+ // a misbehaving Reader. Officially we don't need to do this, but let's
+ // be extra careful: Scanner is for safe, simple jobs.
+ for loop := 0; ; {
+ n, err := s.r.Read(s.buf[s.end:len(s.buf)])
+ s.end += n
+ if err != nil {
+ s.setErr(err)
+ break
+ }
+ if n > 0 {
+ break
+ }
+ loop++
+ if loop > 100 {
+ s.setErr(io.ErrNoProgress)
+ break
+ }
}
- s.end += n
}
}

=======================================
--- /src/pkg/bufio/scan_test.go Wed Apr 10 20:58:19 2013
+++ /src/pkg/bufio/scan_test.go Thu Apr 18 17:37:21 2013
@@ -386,3 +386,21 @@
t.Errorf("unexpected error: %v", err)
}
}
+
+// Test that Scan finishes if we have endless empty reads.
+type endlessZeros struct{}
+
+func (endlessZeros) Read(p []byte) (int, error) {
+ return 0, nil
+}
+
+func TestBadReader(t *testing.T) {
+ scanner := NewScanner(endlessZeros{})
+ for scanner.Scan() {
+ t.Fatal("read should fail")
+ }
+ err := scanner.Err()
+ if err != io.ErrNoProgress {
+ t.Errorf("unexpected error: %v", err)
+ }
+}
Reply all
Reply to author
Forward
0 new messages