summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2022-05-22 17:11:58 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2022-05-22 17:11:58 (GMT)
commit393936e2b829ec47b742c3225bb29250a8e728b8 (patch)
tree9e3c2fbb691e02ea80a48f8073b6028042246971 /generic
parent185db606f066a1ec6904691d6446ef62e184f674 (diff)
downloadtcl-393936e2b829ec47b742c3225bb29250a8e728b8.zip
tcl-393936e2b829ec47b742c3225bb29250a8e728b8.tar.gz
tcl-393936e2b829ec47b742c3225bb29250a8e728b8.tar.bz2
Proposed fix for [76ad7aeba3]: boundary case bug in [string is integer]. Missing: more unit-tests
Diffstat (limited to 'generic')
-rw-r--r--generic/tclCmdMZ.c21
-rw-r--r--generic/tclObj.c18
2 files changed, 27 insertions, 12 deletions
diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c
index c94abbd..8d3eda9 100644
--- a/generic/tclCmdMZ.c
+++ b/generic/tclCmdMZ.c
@@ -1451,7 +1451,6 @@ StringIsCmd(
int (*chcomp)(int) = NULL; /* The UniChar comparison function. */
int i, failat = 0, result = 1, strict = 0, index, length1, length2;
Tcl_Obj *objPtr, *failVarObj = NULL;
- Tcl_WideInt w;
static const char *const isClasses[] = {
"alnum", "alpha", "ascii", "control",
@@ -1590,9 +1589,13 @@ StringIsCmd(
case STR_IS_GRAPH:
chcomp = Tcl_UniCharIsGraph;
break;
- case STR_IS_INT:
- if (TCL_OK == TclGetIntFromObj(NULL, objPtr, &i)) {
- break;
+ case STR_IS_INT: {
+ void *p;
+ int type;
+ if (TCL_OK == TclGetNumberFromObj(NULL, objPtr, &p, &type)
+ && (type == TCL_NUMBER_LONG) && (*(long *)p <= INT_MAX) && (*(long *)p >= INT_MIN)) {
+ break;
+ }
}
goto failedIntParse;
case STR_IS_ENTIER:
@@ -1640,9 +1643,13 @@ StringIsCmd(
failat = 0;
}
break;
- case STR_IS_WIDE:
- if (TCL_OK == TclGetWideIntFromObj(NULL, objPtr, &w)) {
- break;
+ case STR_IS_WIDE: {
+ void *p;
+ int type;
+ if (TCL_OK == TclGetNumberFromObj(NULL, objPtr, &p, &type)
+ && (type == TCL_NUMBER_WIDE)) {
+ break;
+ }
}
failedIntParse:
diff --git a/generic/tclObj.c b/generic/tclObj.c
index b2fd80b..531a256 100644
--- a/generic/tclObj.c
+++ b/generic/tclObj.c
@@ -2500,21 +2500,29 @@ Tcl_GetIntFromObj(
#if (LONG_MAX == INT_MAX)
return TclGetLongFromObj(interp, objPtr, (long *) intPtr);
#else
- long l;
+ void *p;
+ int type;
- if (TclGetLongFromObj(interp, objPtr, &l) != TCL_OK) {
+ if ((TclGetNumberFromObj(NULL, objPtr, &p, &type) != TCL_OK)
+ || (type == TCL_NUMBER_DOUBLE)) {
+ if (interp != NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "expected integer but got \"%s\"", Tcl_GetString(objPtr)));
+ Tcl_SetErrorCode(interp, "TCL", "VALUE", "INTEGER", NULL);
+ }
return TCL_ERROR;
}
- if ((ULONG_MAX > UINT_MAX) && ((l > UINT_MAX) || (l < -(long)UINT_MAX))) {
+ if ((type != TCL_NUMBER_LONG) || ((ULONG_MAX > UINT_MAX)
+ && ((*(long *)p > UINT_MAX) || (*(long *)p < -(long)UINT_MAX)))) {
if (interp != NULL) {
const char *s =
- "integer value too large to represent as non-long integer";
+ "integer value too large to represent";
Tcl_SetObjResult(interp, Tcl_NewStringObj(s, -1));
Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, NULL);
}
return TCL_ERROR;
}
- *intPtr = (int) l;
+ *intPtr = (int)*(long *)p;
return TCL_OK;
#endif
}