diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | generic/tclGet.c | 8 | ||||
-rw-r--r-- | generic/tclObj.c | 52 |
3 files changed, 28 insertions, 38 deletions
@@ -1,3 +1,9 @@ +2005-04-20 Don Porter <dgp@users.sourceforge.net> + + * generic/tclGet.c (Tcl_GetInt): Corrected error that did not + * generic/tclObj.c (Tcl_GetIntFromObj): permit 0x80000000 to be + recognized as an integer on TCL_WIDE_INT_IS_LONG systems [Bug 1090869]. + 2005-04-20 Kevin B. Kenny <kennykb@acm.org> * generic/tclFileName.c: Silenced a compiler warning about diff --git a/generic/tclGet.c b/generic/tclGet.c index 1fd6277..6a56647 100644 --- a/generic/tclGet.c +++ b/generic/tclGet.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclGet.c,v 1.9 2004/04/06 22:25:51 dgp Exp $ + * RCS: @(#) $Id: tclGet.c,v 1.10 2005/04/20 16:04:19 dgp Exp $ */ #include "tclInt.h" @@ -91,7 +91,11 @@ Tcl_GetInt(interp, string, intPtr) * an int. */ - if ((errno == ERANGE) || (((long)(int) i) != i)) { + if ((errno == ERANGE) +#if (LONG_MAX > INT_MAX) + || (i > UINT_MAX) || (i < -(long)UINT_MAX) +#endif + ) { if (interp != (Tcl_Interp *) NULL) { Tcl_SetResult(interp, "integer value too large to represent", TCL_STATIC); diff --git a/generic/tclObj.c b/generic/tclObj.c index 28c2e53..aa30598 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclObj.c,v 1.75 2005/04/05 16:19:10 msofer Exp $ + * RCS: @(#) $Id: tclObj.c,v 1.76 2005/04/20 16:04:20 dgp Exp $ */ #include "tclInt.h" @@ -1958,15 +1958,14 @@ Tcl_GetIntFromObj(interp, objPtr, intPtr) register Tcl_Obj *objPtr; /* The object from which to get a int. */ register int *intPtr; /* Place to store resulting int. */ { - register long l = 0; int result; + Tcl_WideInt w = 0; /* If the object isn't already an integer of any width, try to * convert it to one. */ - if (objPtr->typePtr != &tclIntType - && objPtr->typePtr != &tclWideIntType) { + if (objPtr->typePtr != &tclIntType && objPtr->typePtr != &tclWideIntType) { result = SetIntOrWideFromAny(interp, objPtr); if (result != TCL_OK) { return result; @@ -1975,45 +1974,26 @@ Tcl_GetIntFromObj(interp, objPtr, intPtr) /* Object should now be either int or wide. Get its value. */ - if (objPtr->typePtr == &tclIntType) { - l = objPtr->internalRep.longValue; - } else if (objPtr->typePtr == &tclWideIntType) { #ifndef TCL_WIDE_INT_IS_LONG - /* - * If the object is already a wide integer, don't convert it. - * This code allows for any integer in the range -ULONG_MAX to - * ULONG_MAX to be converted to a long, ignoring overflow. - * The rule preserves existing semantics for conversion of - * integers on input, but avoids inadvertent demotion of - * wide integers to 32-bit ones in the internal rep. - */ - Tcl_WideInt w = objPtr->internalRep.wideValue; - if (w >= -(Tcl_WideInt)(ULONG_MAX) - && w <= (Tcl_WideInt)(ULONG_MAX)) { - l = Tcl_WideAsLong(w); - } else { - goto tooBig; - } -#else - l = objPtr->internalRep.longValue; + if (objPtr->typePtr == &tclWideIntType) { + w = objPtr->internalRep.wideValue; + } else #endif - } else { - Tcl_Panic("string->integer conversion failed to convert the obj."); + { + w = Tcl_LongAsWide(objPtr->internalRep.longValue); } - if (((long)((int)l)) == l) { - *intPtr = (int)l; - return TCL_OK; - } -#ifndef TCL_WIDE_INT_IS_LONG - tooBig: -#endif - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( + if ((LLONG_MAX > UINT_MAX) + && ((w > UINT_MAX) || (w < -(Tcl_WideInt)UINT_MAX))) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( "integer value too large to represent as non-long integer", -1)); + } + return TCL_ERROR; } - return TCL_ERROR; + *intPtr = (int)w; + return TCL_OK; } /* |