summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2021-12-07 18:17:47 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2021-12-07 18:17:47 (GMT)
commit0ae4f5e518be69796d5f6e6c1833a0af2945b473 (patch)
treee45239537d92b297e97a3406833d61ed4d4e02c4
parentc5ed34e7e6933f734555cbc8eea44eaae31be32c (diff)
parentdc62ebb08b7bee1ff2cac7fdf8d35237bed15e7b (diff)
downloadtcl-0ae4f5e518be69796d5f6e6c1833a0af2945b473.zip
tcl-0ae4f5e518be69796d5f6e6c1833a0af2945b473.tar.gz
tcl-0ae4f5e518be69796d5f6e6c1833a0af2945b473.tar.bz2
Merge 8.7
-rw-r--r--generic/tclStrToD.c85
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);