From: Ben Hoyt Date: Sat, 11 Aug 2018 10:02:52 +0000 (+0200) Subject: text/scanner: don't allow Float exponents with no mantissa X-Git-Tag: go1.12beta1~1439 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=6c7e199e500d3f81bda4ce383839e7f0336ed63c;p=gostls13.git text/scanner: don't allow Float exponents with no mantissa Previously Scanner would allow float literals like "1.5e" and "1e+" that weren't actually valid Go float literals, and also not valid when passed to ParseFloat. This commit fixes that behaviour to match the documentation ("recognizes all literals as defined by the Go language specification"), and Scanner emits an error in these cases. Fixes #26374 Change-Id: I6855402ea43febb448c6dff105b9578e31803c01 Reviewed-on: https://go-review.googlesource.com/129095 Reviewed-by: Robert Griesemer Run-TryBot: Robert Griesemer TryBot-Result: Gobot Gobot --- diff --git a/src/text/scanner/scanner.go b/src/text/scanner/scanner.go index 4e76664dc0..893a4edbaf 100644 --- a/src/text/scanner/scanner.go +++ b/src/text/scanner/scanner.go @@ -384,6 +384,9 @@ func (s *Scanner) scanExponent(ch rune) rune { if ch == '-' || ch == '+' { ch = s.next() } + if !isDecimal(ch) { + s.error("illegal exponent") + } ch = s.scanMantissa(ch) } return ch diff --git a/src/text/scanner/scanner_test.go b/src/text/scanner/scanner_test.go index 9a6b72ef67..e26e816f51 100644 --- a/src/text/scanner/scanner_test.go +++ b/src/text/scanner/scanner_test.go @@ -252,6 +252,14 @@ func checkTok(t *testing.T, s *Scanner, line int, got, want rune, text string) { } } +func checkTokErr(t *testing.T, s *Scanner, line int, want rune, text string) { + prevCount := s.ErrorCount + checkTok(t, s, line, s.Scan(), want, text) + if s.ErrorCount != prevCount+1 { + t.Fatalf("want error for %q", text) + } +} + func countNewlines(s string) int { n := 0 for _, ch := range s { @@ -282,6 +290,21 @@ func TestScan(t *testing.T) { testScan(t, GoTokens&^SkipComments) } +func TestIllegalExponent(t *testing.T) { + const src = "1.5e 1.5E 1e+ 1e- 1.5z" + s := new(Scanner).Init(strings.NewReader(src)) + checkTokErr(t, s, 1, Float, "1.5e") + checkTokErr(t, s, 1, Float, "1.5E") + checkTokErr(t, s, 1, Float, "1e+") + checkTokErr(t, s, 1, Float, "1e-") + checkTok(t, s, 1, s.Scan(), Float, "1.5") + checkTok(t, s, 1, s.Scan(), Ident, "z") + checkTok(t, s, 1, s.Scan(), EOF, "") + if s.ErrorCount != 4 { + t.Errorf("%d errors, want 4", s.ErrorCount) + } +} + func TestPosition(t *testing.T) { src := makeSource("\t\t\t\t%s\n") s := new(Scanner).Init(src) @@ -475,6 +498,10 @@ func TestError(t *testing.T) { testError(t, `0x`, ":1:3", "illegal hexadecimal number", Int) testError(t, `0xg`, ":1:3", "illegal hexadecimal number", Int) testError(t, `'aa'`, ":1:4", "illegal char literal", Char) + testError(t, `1.5e`, ":1:5", "illegal exponent", Float) + testError(t, `1.5E`, ":1:5", "illegal exponent", Float) + testError(t, `1.5e+`, ":1:6", "illegal exponent", Float) + testError(t, `1.5e-`, ":1:6", "illegal exponent", Float) testError(t, `'`, ":1:2", "literal not terminated", Char) testError(t, `'`+"\n", ":1:2", "literal not terminated", Char)