Skip to content

Commit 9956a54

Browse files
committed
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 <[email protected]> Run-TryBot: Robert Griesemer <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 8427429 commit 9956a54

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

src/text/scanner/scanner.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ func (s *Scanner) errorf(format string, args ...any) {
346346

347347
func (s *Scanner) isIdentRune(ch rune, i int) bool {
348348
if s.IsIdentRune != nil {
349-
return s.IsIdentRune(ch, i)
349+
return ch != EOF && s.IsIdentRune(ch, i)
350350
}
351351
return ch == '_' || unicode.IsLetter(ch) || unicode.IsDigit(ch) && i > 0
352352
}

src/text/scanner/scanner_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,3 +913,22 @@ func extractInts(t string, mode uint) (res string) {
913913
}
914914
}
915915
}
916+
917+
func TestIssue50909(t *testing.T) {
918+
var s Scanner
919+
s.Init(strings.NewReader("hello \n\nworld\n!\n"))
920+
s.IsIdentRune = func(ch rune, _ int) bool { return ch != '\n' }
921+
922+
r := ""
923+
n := 0
924+
for s.Scan() != EOF && n < 10 {
925+
r += s.TokenText()
926+
n++
927+
}
928+
929+
const R = "hello world!"
930+
const N = 3
931+
if r != R || n != N {
932+
t.Errorf("got %q (n = %d); want %q (n = %d)", r, n, R, N)
933+
}
934+
}

0 commit comments

Comments
 (0)