summaryrefslogtreecommitdiffstats
path: root/generic/tclStrToD.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2017-11-09 14:59:36 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2017-11-09 14:59:36 (GMT)
commit944a3d95ffd92e872e30021a6b4bc7d932759c22 (patch)
tree115e9c7476f7164837b7122760147ae95bd5b422 /generic/tclStrToD.c
parent29dda71bad5e67eb3ada1ce9f836ca43bde1c216 (diff)
parent78374f18a4199081db4462452b16c3e4193edc92 (diff)
downloadtcl-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.c65
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);
}