From 9956a5423e40bab92c572489eae26ba80ed803ab Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Tue, 15 Mar 2022 21:44:37 -0700 Subject: [PATCH] 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 --- src/text/scanner/scanner.go | 2 +- src/text/scanner/scanner_test.go | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) 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) + } +} -- 2.50.0