summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--generic/tclEnv.c5
-rwxr-xr-xgeneric/tclStrToD.c48
3 files changed, 42 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index 34a0c00..0830cc4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2007-04-23 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclEnv.c (ReplaceString): Clear memory correctly when
+ growing the cache to avoid reads of uninitialised data.
+ * generic/tclStrToD.c (AccumulateDecimalDigit): Fixed a mistake
+ where we'd run beyond the end of the 'pow10_wide' array if
+ a number begins with a string of more than 'maxpow10_wide' zeroes.
+ Both these issues reported under [Bug 1705778] - detected with
+ the existing test suite, no new regression tests required.
+
2007-04-22 Miguel Sofer <msofer@users.sf.net>
* generic/tclVar.c (TclDeleteNamespaceVars): fixed access to freed
diff --git a/generic/tclEnv.c b/generic/tclEnv.c
index 596e68b..30bce65 100644
--- a/generic/tclEnv.c
+++ b/generic/tclEnv.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclEnv.c,v 1.32 2007/04/10 14:47:13 dkf Exp $
+ * RCS: @(#) $Id: tclEnv.c,v 1.33 2007/04/23 17:34:06 kennykb Exp $
*/
#include "tclInt.h"
@@ -677,7 +677,8 @@ ReplaceString(
environCache = (char **) ckrealloc ((char *) environCache,
(cacheSize + growth) * sizeof(char *));
environCache[cacheSize] = newStr;
- (void) memset(environCache+cacheSize+1, (int) 0, (size_t) (growth - 1));
+ (void) memset(environCache+cacheSize+1, (int) 0,
+ (size_t) ((growth-1) * sizeof(char*)));
cacheSize += growth;
}
}
diff --git a/generic/tclStrToD.c b/generic/tclStrToD.c
index afcf7eb..dc19855 100755
--- a/generic/tclStrToD.c
+++ b/generic/tclStrToD.c
@@ -14,7 +14,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclStrToD.c,v 1.29 2007/04/16 13:36:35 dkf Exp $
+ * RCS: @(#) $Id: tclStrToD.c,v 1.30 2007/04/23 17:34:07 kennykb Exp $
*
*----------------------------------------------------------------------
*/
@@ -1182,32 +1182,42 @@ AccumulateDecimalDigit(
* to this digit. */
{
int i, n;
+ Tcl_WideUInt w;
/*
- * Check if the number still fits in a wide.
+ * Try wide multiplication first
*/
- if (!bignumFlag && *wideRepPtr!=0 && ((numZeros >= maxpow10_wide) ||
- *wideRepPtr > ((~(Tcl_WideUInt)0)-digit)/pow10_wide[numZeros+1])) {
- /*
- * Oops, it's overflowed, have to allocate a bignum.
- */
-
- TclBNInitBignumFromWideUInt (bignumRepPtr, *wideRepPtr);
- bignumFlag = 1;
+ if (!bignumFlag) {
+ w = *wideRepPtr;
+ if (w == 0) {
+ /*
+ * There's no need to multiply if the multiplicand is zero.
+ */
+ *wideRepPtr = digit;
+ return 0;
+ } else if (numZeros >= maxpow10_wide
+ || w > ((~(Tcl_WideUInt)0)-digit)/pow10_wide[numZeros+1]) {
+ /*
+ * Wide multiplication will overflow. Expand the
+ * number to a bignum and fall through into the bignum case.
+ */
+
+ TclBNInitBignumFromWideUInt (bignumRepPtr, w);
+ } else {
+ /*
+ * Wide multiplication.
+ */
+ *wideRepPtr = w * pow10_wide[numZeros+1] + digit;
+ return 0;
+ }
}
/*
- * Multiply the number by 10**numZeros+1 and add in the new digit.
+ * Bignum multiplication.
*/
- if (!bignumFlag) {
- /*
- * Wide multiplication.
- */
-
- *wideRepPtr = *wideRepPtr * pow10_wide[numZeros+1] + digit;
- } else if (numZeros < log10_DIGIT_MAX) {
+ if (numZeros < log10_DIGIT_MAX) {
/*
* Up to about 8 zeros - single digit multiplication.
*/
@@ -1240,7 +1250,7 @@ AccumulateDecimalDigit(
mp_add_d(bignumRepPtr, (mp_digit) digit, bignumRepPtr);
}
- return bignumFlag;
+ return 1;
}
/*