IsIdentRune may be installed by a client of the scanner. If the
installed function accepts EOF as a valid identifier rune, Scan
calls may not terminate.
Check for EOF when a user-defined IsIdentRune is used.
Fixes #50909.
Change-Id: Ib104b03ee59e2d58faa71f227c3b51ba424f7f61
Reviewed-on: https://go-review.googlesource.com/c/go/+/393254
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
func (s *Scanner) isIdentRune(ch rune, i int) bool {
if s.IsIdentRune != nil {
- return s.IsIdentRune(ch, i)
+ return ch != EOF && s.IsIdentRune(ch, i)
}
return ch == '_' || unicode.IsLetter(ch) || unicode.IsDigit(ch) && i > 0
}
}
}
}
+
+func TestIssue50909(t *testing.T) {
+ var s Scanner
+ s.Init(strings.NewReader("hello \n\nworld\n!\n"))
+ s.IsIdentRune = func(ch rune, _ int) bool { return ch != '\n' }
+
+ r := ""
+ n := 0
+ for s.Scan() != EOF && n < 10 {
+ r += s.TokenText()
+ n++
+ }
+
+ const R = "hello world!"
+ const N = 3
+ if r != R || n != N {
+ t.Errorf("got %q (n = %d); want %q (n = %d)", r, n, R, N)
+ }
+}