From: Robert Griesemer Date: Wed, 16 Mar 2022 04:44:37 +0000 (-0700) Subject: text/scanner: guard against installed IsIdentRune that accepts EOF X-Git-Tag: go1.19beta1~1037 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=9956a5423e40bab92c572489eae26ba80ed803ab;p=gostls13.git text/scanner: guard against installed IsIdentRune that accepts EOF 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 Run-TryBot: Robert Griesemer TryBot-Result: Gopher Robot Reviewed-by: Ian Lance Taylor --- diff --git a/src/text/scanner/scanner.go b/src/text/scanner/scanner.go index f1fbf9861d..735982afcb 100644 --- a/src/text/scanner/scanner.go +++ b/src/text/scanner/scanner.go @@ -346,7 +346,7 @@ func (s *Scanner) errorf(format string, args ...any) { 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 } diff --git a/src/text/scanner/scanner_test.go b/src/text/scanner/scanner_test.go index fe39d3060b..6a454d9be7 100644 --- a/src/text/scanner/scanner_test.go +++ b/src/text/scanner/scanner_test.go @@ -913,3 +913,22 @@ func extractInts(t string, mode uint) (res string) { } } } + +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) + } +}