Commit 6c7e199e authored by Ben Hoyt's avatar Ben Hoyt Committed by Robert Griesemer

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/129095Reviewed-by: 's avatarRobert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 7b9c2c19
......@@ -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
......
......@@ -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`, "<input>:1:3", "illegal hexadecimal number", Int)
testError(t, `0xg`, "<input>:1:3", "illegal hexadecimal number", Int)
testError(t, `'aa'`, "<input>:1:4", "illegal char literal", Char)
testError(t, `1.5e`, "<input>:1:5", "illegal exponent", Float)
testError(t, `1.5E`, "<input>:1:5", "illegal exponent", Float)
testError(t, `1.5e+`, "<input>:1:6", "illegal exponent", Float)
testError(t, `1.5e-`, "<input>:1:6", "illegal exponent", Float)
testError(t, `'`, "<input>:1:2", "literal not terminated", Char)
testError(t, `'`+"\n", "<input>:1:2", "literal not terminated", Char)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment