diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2021-12-07 18:17:47 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2021-12-07 18:17:47 (GMT) |
commit | 0ae4f5e518be69796d5f6e6c1833a0af2945b473 (patch) | |
tree | e45239537d92b297e97a3406833d61ed4d4e02c4 | |
parent | c5ed34e7e6933f734555cbc8eea44eaae31be32c (diff) | |
parent | dc62ebb08b7bee1ff2cac7fdf8d35237bed15e7b (diff) | |
download | tcl-0ae4f5e518be69796d5f6e6c1833a0af2945b473.zip tcl-0ae4f5e518be69796d5f6e6c1833a0af2945b473.tar.gz tcl-0ae4f5e518be69796d5f6e6c1833a0af2945b473.tar.bz2 |
Merge 8.7
-rw-r--r-- | generic/tclStrToD.c | 85 |
1 files changed, 69 insertions, 16 deletions
diff --git a/generic/tclStrToD.c b/generic/tclStrToD.c index c428552..f6fe00f 100644 --- a/generic/tclStrToD.c +++ b/generic/tclStrToD.c @@ -716,9 +716,9 @@ TclParseNumber( if (!octalSignificandOverflow) { /* - * Shifting by more bits than are in the value being - * shifted is at least de facto nonportable. Check for - * too large shifts first. + * Shifting by as many or more bits than are in the + * value being shifted is undefined behavior. Check + * for too large shifts first. */ if ((octalSignificandWide != 0) @@ -732,8 +732,17 @@ TclParseNumber( } } if (!octalSignificandOverflow) { - octalSignificandWide = - (octalSignificandWide << shift) + (c - '0'); + /* + * When the significand is 0, it is possible for the + * amount to be shifted to equal or exceed the width + * of the significand. Do not shift when the + * significand is 0 to avoid undefined behavior. + */ + + if (octalSignificandWide != 0) { + octalSignificandWide <<= shift; + } + octalSignificandWide += c - '0'; } else { if (err == MP_OKAY) { err = mp_mul_2d(&octalSignificandBig, shift, @@ -802,9 +811,9 @@ TclParseNumber( shift = 4 * (numTrailZeros + 1); if (!significandOverflow) { /* - * Shifting by more bits than are in the value being - * shifted is at least de facto nonportable. Check for too - * large shifts first. + * Shifting by as many or more bits than are in the + * value being shifted is undefined behavior. Check + * for too large shifts first. */ if (significandWide != 0 && @@ -816,7 +825,17 @@ TclParseNumber( } } if (!significandOverflow) { - significandWide = (significandWide << shift) + d; + /* + * When the significand is 0, it is possible for the + * amount to be shifted to equal or exceed the width + * of the significand. Do not shift when the + * significand is 0 to avoid undefined behavior. + */ + + if (significandWide != 0) { + significandWide <<= shift; + } + significandWide += d; } else if (err == MP_OKAY) { err = mp_mul_2d(&significandBig, shift, &significandBig); if (err == MP_OKAY) { @@ -856,9 +875,9 @@ TclParseNumber( shift = numTrailZeros + 1; if (!significandOverflow) { /* - * Shifting by more bits than are in the value being - * shifted is at least de facto nonportable. Check for too - * large shifts first. + * Shifting by as many or more bits than are in the + * value being shifted is undefined behavior. Check + * for too large shifts first. */ if (significandWide != 0 && @@ -870,7 +889,17 @@ TclParseNumber( } } if (!significandOverflow) { - significandWide = (significandWide << shift) + 1; + /* + * When the significand is 0, it is possible for the + * amount to be shifted to equal or exceed the width + * of the significand. Do not shift when the + * significand is 0 to avoid undefined behavior. + */ + + if (significandWide != 0) { + significandWide <<= shift; + } + significandWide += 1; } else if (err == MP_OKAY) { err = mp_mul_2d(&significandBig, shift, &significandBig); if (err == MP_OKAY) { @@ -1266,7 +1295,15 @@ TclParseNumber( } if (shift) { if (!significandOverflow) { - significandWide <<= shift; + /* + * When the significand is 0, it is possible for the + * amount to be shifted to equal or exceed the width + * of the significand. Do not shift when the + * significand is 0 to avoid undefined behavior. + */ + if (significandWide != 0) { + significandWide <<= shift; + } } else if (err == MP_OKAY) { err = mp_mul_2d(&significandBig, shift, &significandBig); } @@ -1290,7 +1327,15 @@ TclParseNumber( } if (shift) { if (!significandOverflow) { - significandWide <<= shift; + /* + * When the significand is 0, it is possible for the + * amount to be shifted to equal or exceed the width + * of the significand. Do not shift when the + * significand is 0 to avoid undefined behavior. + */ + if (significandWide != 0) { + significandWide <<= shift; + } } else if (err == MP_OKAY) { err = mp_mul_2d(&significandBig, shift, &significandBig); } @@ -1315,7 +1360,15 @@ TclParseNumber( } if (shift) { if (!octalSignificandOverflow) { - octalSignificandWide <<= shift; + /* + * When the significand is 0, it is possible for the + * amount to be shifted to equal or exceed the width + * of the significand. Do not shift when the + * significand is 0 to avoid undefined behavior. + */ + if (octalSignificandWide != 0) { + octalSignificandWide <<= shift; + } } else if (err == MP_OKAY) { err = mp_mul_2d(&octalSignificandBig, shift, &octalSignificandBig); |