diff options
author | Tony Cook <tony@develop-help.com> | 2017-08-03 12:11:56 +1000 |
---|---|---|
committer | Tony Cook <tony@develop-help.com> | 2017-08-14 15:38:54 +1000 |
commit | adb0f5c46e10ac97fd958f4cd5526ea6d4b058f6 (patch) | |
tree | 9c7407d18b168df569e41c3057930054525f9a87 | |
parent | 7aaa36b196e5a478a3d1bd32506797db7cebf0b2 (diff) | |
download | perl-adb0f5c46e10ac97fd958f4cd5526ea6d4b058f6.tar.gz |
(perl #131725) ignore the exponent on a decimal float if no digits
Previously the "1e-" in "1e--5" would be treated as "1", but consumed
the "e-".
This wasn't an issue for hex floats.
I considered (and implemented) croaking instead, but this was
inconsistent with the behaviour for hex floats, which only reach this
code if a full hex float has been parsed.
-rw-r--r-- | t/lib/croak/toke | 10 | ||||
-rw-r--r-- | toke.c | 21 |
2 files changed, 29 insertions, 2 deletions
diff --git a/t/lib/croak/toke b/t/lib/croak/toke index 2603224fdd..c477be0336 100644 --- a/t/lib/croak/toke +++ b/t/lib/croak/toke @@ -394,3 +394,13 @@ $a = <<~ ; EXPECT Use of bare << to mean <<"" is forbidden at - line 1. +######## +# NAME incomplete floating point decimal exponent (#131725) +1e--5 +EXPECT +Bareword found where operator expected at - line 1, near "1e" + (Missing operator before e?) +Number found where operator expected at - line 1, near "--5" + (Missing operator before 5?) +syntax error at - line 1, near "1e" +Execution of - aborted due to compilation errors. @@ -11182,9 +11182,11 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp) || UNLIKELY(hexfp && isALPHA_FOLD_EQ(*s, 'p'))) && strchr("+-0123456789_", s[1])) { - floatit = TRUE; + int exp_digits = 0; + const char *save_s = s; + char * save_d = d; - /* regardless of whether user said 3E5 or 3e5, use lower 'e', + /* regardless of whether user said 3E5 or 3e5, use lower 'e', ditto for p (hexfloats) */ if ((isALPHA_FOLD_EQ(*s, 'e'))) { /* At least some Mach atof()s don't grok 'E' */ @@ -11216,6 +11218,7 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp) /* read digits of exponent */ while (isDIGIT(*s) || *s == '_') { if (isDIGIT(*s)) { + ++exp_digits; if (d >= e) Perl_croak(aTHX_ "%s", number_too_long); *d++ = *s++; @@ -11227,6 +11230,20 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp) lastub = s++; } } + + if (!exp_digits) { + /* no exponent digits, the [eEpP] could be for something else, + * though in practice we don't get here for p since that's preparsed + * earlier, and results in only the 0xX being consumed, so behave similarly + * for decimal floats and consume only the D.DD, leaving the [eE] to the + * next token. + */ + s = save_s; + d = save_d; + } + else { + floatit = TRUE; + } } |