diff options
author | dgp <dgp@users.sourceforge.net> | 2006-12-07 23:35:29 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2006-12-07 23:35:29 (GMT) |
commit | 3956ac10bc7eb76aeae3705e041bef841361d208 (patch) | |
tree | 3086eac10fe782de5811f761f5595936c615c60b /generic/tclExecute.c | |
parent | 00ea0049a0fcf1517652f613da6ee76288bfb1ac (diff) | |
download | tcl-3956ac10bc7eb76aeae3705e041bef841361d208.zip tcl-3956ac10bc7eb76aeae3705e041bef841361d208.tar.gz tcl-3956ac10bc7eb76aeae3705e041bef841361d208.tar.bz2 |
* generic/tclCompCmds.c: Additional commits correct most
* generic/tclExecute.c: failing tests illustrating bugs uncovered
* generic/tclMathOp.c: in [Path 1578137].
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r-- | generic/tclExecute.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 0e3368d..86e1db2 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.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: tclExecute.c,v 1.256 2006/12/01 14:31:19 dgp Exp $ + * RCS: @(#) $Id: tclExecute.c,v 1.257 2006/12/07 23:35:29 dgp Exp $ */ #include "tclInt.h" @@ -3942,8 +3942,13 @@ TclExecuteByteCode( if (*pc == INST_LSHIFT) { /* Large left shifts create integer overflow */ - result = Tcl_GetIntFromObj(NULL, value2Ptr, &shift); - if (result != TCL_OK) { + /* BEWARE! Can't use Tcl_GetIntFromObj() here because + * that converts values in the (unsigned int) range to + * their signed int counterparts, leading to incorrect + * results. + */ + if ((type2 != TCL_NUMBER_LONG) + || (*((CONST long *)ptr2) > (long) INT_MAX)) { /* * Technically, we could hold the value (1 << (INT_MAX+1)) in * an mp_int, but since we're using mp_mul_2d() to do the @@ -3953,8 +3958,12 @@ TclExecuteByteCode( Tcl_SetObjResult(interp, Tcl_NewStringObj( "integer value too large to represent", -1)); + result = TCL_ERROR; goto checkForCatch; } + shift = (int)(*((CONST long *)ptr2)); + + /* Handle shifts within the native long range */ TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr))); if ((type1 == TCL_NUMBER_LONG) && ((size_t)shift < CHAR_BIT*sizeof(long)) @@ -4786,6 +4795,7 @@ TclExecuteByteCode( if (type2 == TCL_NUMBER_BIG) { Tcl_SetObjResult(interp, Tcl_NewStringObj("exponent too large", -1)); + result = TCL_ERROR; goto checkForCatch; } /* TODO: Perform those computations that fit in native types */ @@ -4806,7 +4816,7 @@ TclExecuteByteCode( #endif { /* Check for overflow */ - if (((w1 < 0) && (w2 < 0) && (wResult > 0)) + if (((w1 < 0) && (w2 < 0) && (wResult >= 0)) || ((w1 > 0) && (w2 > 0) && (wResult < 0))) { goto overflow; } @@ -4821,7 +4831,7 @@ TclExecuteByteCode( { /* Must check for overflow */ if (((w1 < 0) && (w2 > 0) && (wResult > 0)) - || ((w1 > 0) && (w2 < 0) && (wResult < 0))) { + || ((w1 >= 0) && (w2 < 0) && (wResult < 0))) { goto overflow; } } @@ -4906,6 +4916,7 @@ TclExecuteByteCode( Tcl_NewStringObj("exponent too large", -1)); mp_clear(&big1); mp_clear(&big2); + result = TCL_ERROR; goto checkForCatch; } mp_expt_d(&big1, big2.dp[0], &bigResult); |