-qlongdouble considered harmful by Merijn.
[p5sagit/p5-mst-13.2.git] / toke.c
diff --git a/toke.c b/toke.c
index 79399fd..fe4069a 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -2847,6 +2847,8 @@ Perl_yylex(pTHX)
                s++;
            if (s < d)
                s++;
+           else if (s > d) /* Found by Ilya: feed random input to Perl. */
+             Perl_croak(aTHX_ "panic: input overflow");
            incline(s);
            if (PL_lex_formbrack && PL_lex_brackets <= PL_lex_formbrack) {
                PL_bufptr = s;
@@ -6876,12 +6878,11 @@ S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims)
 
   Read a number in any of the formats that Perl accepts:
 
-  0(x[0-7A-F]+)|([0-7]+)|(b[01])
-  \d([\d_]*\d)?(\.\d([\d_]*\d)?)?[Ee](\d+)
-
-  Underbars (_) are allowed in decimal numbers.  If -w is on,
-  underbars must not be consecutive, and they cannot start
-  or end integer or fractional parts.
+  \d(_?\d)*(\.(\d(_?\d)*)?)?[Ee][\+\-]?(\d(_?\d)*)     12 12.34 12.
+  \.\d(_?\d)*[Ee][\+\-]?(\d(_?\d)*)                    .34
+  0b[01](_?[01])*
+  0[0-7](_?[0-7])*
+  0x[0-9A-Fa-f](_?[0-9A-Fa-f])*
 
   Like most scan_ routines, it uses the PL_tokenbuf buffer to hold the
   thing it reads.
@@ -7161,22 +7162,48 @@ Perl_scan_num(pTHX_ char *start, YYSTYPE* lvalp)
        }
 
        /* read exponent part, if present */
-       if (*s && strchr("eE",*s) && strchr("+-0123456789",s[1])) {
+       if (*s && strchr("eE",*s) && strchr("+-0123456789_", s[1])) {
            floatit = TRUE;
            s++;
 
            /* regardless of whether user said 3E5 or 3e5, use lower 'e' */
            *d++ = 'e';         /* At least some Mach atof()s don't grok 'E' */
 
+           /* stray preinitial _ */
+           if (*s == '_') {
+               if (ckWARN(WARN_SYNTAX))
+                   Perl_warner(aTHX_ WARN_SYNTAX,
+                               "Misplaced _ in number");
+               lastub = s++;
+           }
+
            /* allow positive or negative exponent */
            if (*s == '+' || *s == '-')
                *d++ = *s++;
 
-           /* read digits of exponent (no underbars :-) */
-           while (isDIGIT(*s)) {
-               if (d >= e)
-                   Perl_croak(aTHX_ number_too_long);
-               *d++ = *s++;
+           /* stray initial _ */
+           if (*s == '_') {
+               if (ckWARN(WARN_SYNTAX))
+                   Perl_warner(aTHX_ WARN_SYNTAX,
+                               "Misplaced _ in number");
+               lastub = s++;
+           }
+
+           /* read digits of exponent */
+           while (isDIGIT(*s) || *s == '_') {
+               if (isDIGIT(*s)) {
+                   if (d >= e)
+                       Perl_croak(aTHX_ number_too_long);
+                   *d++ = *s++;
+               }
+               else {
+                  if (ckWARN(WARN_SYNTAX) &&
+                      ((lastub && s == lastub + 1) ||
+                       (!isDIGIT(s[1]) && s[1] != '_')))
+                      Perl_warner(aTHX_ WARN_SYNTAX,
+                                  "Misplaced _ in number");
+                  lastub = s++;
+               }
            }
        }