aboutsummaryrefslogtreecommitdiff
path: root/src/bufio/scan.go
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2014-11-06 09:57:46 +1100
committerRob Pike <r@golang.org>2014-11-06 09:57:46 +1100
commit590f5283762a6e80796c3ae2bde410319162cb45 (patch)
tree3959f29536f143fde183b6cddc63c04731bc0082 /src/bufio/scan.go
parentbb4a358af3469a1dee0cb5bcae245865233aa9ea (diff)
downloadgo-590f5283762a6e80796c3ae2bde410319162cb45.tar.xz
bufio: don't loop generating empty tokens
The new rules for split functions mean that we are exposed to the common bug of a function that loops forever at EOF. Pick these off by shutting down the scanner if too many consecutive empty tokens are delivered. Fixes #9020. LGTM=rsc, adg R=golang-codereviews, rsc, adg, bradfitz CC=golang-codereviews https://golang.org/cl/169970043
Diffstat (limited to 'src/bufio/scan.go')
-rw-r--r--src/bufio/scan.go12
1 files changed, 12 insertions, 0 deletions
diff --git a/src/bufio/scan.go b/src/bufio/scan.go
index a41451524d..73ad763b8f 100644
--- a/src/bufio/scan.go
+++ b/src/bufio/scan.go
@@ -36,6 +36,7 @@ type Scanner struct {
start int // First non-processed byte in buf.
end int // End of data in buf.
err error // Sticky error.
+ empties int // Count of successive empty tokens.
}
// SplitFunc is the signature of the split function used to tokenize the
@@ -108,6 +109,8 @@ func (s *Scanner) Text() string {
// 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.
+// Split panics if the split function returns 100 empty tokens without
+// advancing the input. This is a common error mode for scanners.
func (s *Scanner) Scan() bool {
// Loop until we have a token.
for {
@@ -125,6 +128,14 @@ func (s *Scanner) Scan() bool {
}
s.token = token
if token != nil {
+ if len(token) > 0 {
+ s.empties = 0
+ } else {
+ s.empties++
+ if s.empties > 100 {
+ panic("bufio.Scan: 100 empty tokens without progressing")
+ }
+ }
return true
}
}
@@ -172,6 +183,7 @@ func (s *Scanner) Scan() bool {
break
}
if n > 0 {
+ s.empties = 0
break
}
loop++