]> Cypherpunks repositories - gostls13.git/commitdiff
text/scanner: don't allow Float exponents with no mantissa
authorBen Hoyt <benhoyt@gmail.com>
Sat, 11 Aug 2018 10:02:52 +0000 (12:02 +0200)
committerRobert Griesemer <gri@golang.org>
Mon, 20 Aug 2018 17:01:34 +0000 (17:01 +0000)
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 <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/text/scanner/scanner.go
src/text/scanner/scanner_test.go

index 4e76664dc0c81d223c29cd76333eaef62c6110fb..893a4edbaf92f1bd5b5e070b98075ed16f17740f 100644 (file)
@@ -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
index 9a6b72ef673b0eca61b06c0da25ee4d6113237c1..e26e816f519894ae0cb6d6d25cca25da2430122a 100644 (file)
@@ -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)