Skip to content

Commit fd5b8aa

Browse files
committed
text/scanner: avoid further reads after EOF
Fixes #10735. Change-Id: I5c6e424653657c89da176136ac56597c7565abe5 Reviewed-on: https://go-review.googlesource.com/10039 Reviewed-by: Rob Pike <[email protected]>
1 parent f8fbcef commit fd5b8aa

File tree

2 files changed

+33
-9
lines changed

2 files changed

+33
-9
lines changed

src/text/scanner/scanner.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,9 @@ func (s *Scanner) Next() rune {
314314
s.tokPos = -1 // don't collect token text
315315
s.Line = 0 // invalidate token position
316316
ch := s.Peek()
317-
s.ch = s.next()
317+
if ch != EOF {
318+
s.ch = s.next()
319+
}
318320
return ch
319321
}
320322

@@ -597,6 +599,8 @@ redo:
597599
}
598600
default:
599601
switch ch {
602+
case EOF:
603+
break
600604
case '"':
601605
if s.Mode&ScanStrings != 0 {
602606
s.scanString('"')

src/text/scanner/scanner_test.go

+28-8
Original file line numberDiff line numberDiff line change
@@ -619,29 +619,49 @@ func TestPos(t *testing.T) {
619619

620620
type countReader int
621621

622-
func (c *countReader) Read([]byte) (int, error) {
623-
*c++
624-
622+
func (r *countReader) Read([]byte) (int, error) {
623+
*r++
625624
return 0, io.EOF
626625
}
627626

628-
func TestPeekEOFHandling(t *testing.T) {
627+
func TestNextEOFHandling(t *testing.T) {
629628
var r countReader
630629

631630
// corner case: empty source
632631
s := new(Scanner).Init(&r)
633632

634633
tok := s.Next()
635634
if tok != EOF {
636-
t.Errorf("EOF not reported")
635+
t.Error("1) EOF not reported")
636+
}
637+
638+
tok = s.Peek()
639+
if tok != EOF {
640+
t.Error("2) EOF not reported")
641+
}
642+
643+
if r != 1 {
644+
t.Errorf("scanner called Read %d times, not once", r)
645+
}
646+
}
647+
648+
func TestScanEOFHandling(t *testing.T) {
649+
var r countReader
650+
651+
// corner case: empty source
652+
s := new(Scanner).Init(&r)
653+
654+
tok := s.Scan()
655+
if tok != EOF {
656+
t.Error("1) EOF not reported")
637657
}
638658

639659
tok = s.Peek()
640660
if tok != EOF {
641-
t.Errorf("EOF not reported")
661+
t.Error("2) EOF not reported")
642662
}
643663

644-
if r != 2 {
645-
t.Errorf("scanner called Read %d times, not twice", r)
664+
if r != 1 {
665+
t.Errorf("scanner called Read %d times, not once", r)
646666
}
647667
}

0 commit comments

Comments
 (0)