diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2017-11-09 14:59:36 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2017-11-09 14:59:36 (GMT) |
commit | 944a3d95ffd92e872e30021a6b4bc7d932759c22 (patch) | |
tree | 115e9c7476f7164837b7122760147ae95bd5b422 /generic/tclStrToD.c | |
parent | 29dda71bad5e67eb3ada1ce9f836ca43bde1c216 (diff) | |
parent | 78374f18a4199081db4462452b16c3e4193edc92 (diff) | |
download | tcl-944a3d95ffd92e872e30021a6b4bc7d932759c22.zip tcl-944a3d95ffd92e872e30021a6b4bc7d932759c22.tar.gz tcl-944a3d95ffd92e872e30021a6b4bc7d932759c22.tar.bz2 |
Rebase back to 8.7 (core-8-branch), since that's what the TIP is meant for. (I see no reason to wait for 9.0)
Diffstat (limited to 'generic/tclStrToD.c')
-rw-r--r--[-rwxr-xr-x] | generic/tclStrToD.c | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/generic/tclStrToD.c b/generic/tclStrToD.c index d36415c..ac2ca68 100755..100644 --- a/generic/tclStrToD.c +++ b/generic/tclStrToD.c @@ -483,7 +483,7 @@ TclParseNumber( enum State { INITIAL, SIGNUM, ZERO, ZERO_X, ZERO_O, ZERO_B, ZERO_D, BINARY, - HEXADECIMAL, OCTAL, DECIMAL, + HEXADECIMAL, OCTAL, BAD_OCTAL, DECIMAL, LEADING_RADIX_POINT, FRACTION, EXPONENT_START, EXPONENT_SIGNUM, EXPONENT, sI, sIN, sINF, sINFI, sINFIN, sINFINI, sINFINIT, sINFINITY @@ -528,6 +528,7 @@ TclParseNumber( char d = 0; /* Last hexadecimal digit scanned; initialized * to avoid a compiler warning. */ int shift = 0; /* Amount to shift when accumulating binary */ + int explicitOctal = 0; #define ALL_BITS (~(Tcl_WideUInt)0) #define MOST_BITS (ALL_BITS >> 1) @@ -659,6 +660,7 @@ TclParseNumber( goto zerob; } if (c == 'o' || c == 'O') { + explicitOctal = 1; state = ZERO_O; break; } @@ -666,7 +668,10 @@ TclParseNumber( state = ZERO_D; break; } +#ifdef TCL_NO_DEPRECATED goto decimal; +#endif + /* FALLTHROUGH */ case OCTAL: /* @@ -729,6 +734,58 @@ TclParseNumber( state = OCTAL; break; } + /* FALLTHROUGH */ + + case BAD_OCTAL: + if (explicitOctal) { + /* + * No forgiveness for bad digits in explicitly octal numbers. + */ + + goto endgame; + } + if (flags & TCL_PARSE_INTEGER_ONLY) { + /* + * No seeking floating point when parsing only integer. + */ + + goto endgame; + } +#ifndef TCL_NO_DEPRECATED + + /* + * Scanned a number with a leading zero that contains an 8, 9, + * radix point or E. This is an invalid octal number, but might + * still be floating point. + */ + + if (c == '0') { + numTrailZeros++; + state = BAD_OCTAL; + break; + } else if (isdigit(UCHAR(c))) { + if (objPtr != NULL) { + significandOverflow = AccumulateDecimalDigit( + (unsigned)(c-'0'), numTrailZeros, + &significandWide, &significandBig, + significandOverflow); + } + if (numSigDigs != 0) { + numSigDigs += (numTrailZeros + 1); + } else { + numSigDigs = 1; + } + numTrailZeros = 0; + state = BAD_OCTAL; + break; + } else if (c == '.') { + state = FRACTION; + break; + } else if (c == 'E' || c == 'e') { + state = EXPONENT_START; + break; + } +#endif goto endgame; /* @@ -843,7 +900,9 @@ TclParseNumber( * digits. */ +#ifdef TCL_NO_DEPRECATED decimal: +#endif acceptState = state; acceptPoint = p; acceptLen = len; @@ -1127,6 +1186,7 @@ TclParseNumber( TclFreeIntRep(objPtr); switch (acceptState) { case SIGNUM: + case BAD_OCTAL: case ZERO_X: case ZERO_O: case ZERO_B: @@ -1324,6 +1384,9 @@ TclParseNumber( Tcl_AppendLimitedToObj(msg, bytes, numBytes, 50, ""); Tcl_AppendToObj(msg, "\"", -1); + if (state == BAD_OCTAL) { + Tcl_AppendToObj(msg, " (looks like invalid octal number)", -1); + } Tcl_SetObjResult(interp, msg); Tcl_SetErrorCode(interp, "TCL", "VALUE", "NUMBER", NULL); } |