diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2022-11-28 23:16:31 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2022-11-28 23:16:31 (GMT) |
commit | 71b0ad990caaf6a297049da2c63821a4e29c57ac (patch) | |
tree | f27faff96ed68e42d4c00da3a522f9eef06a2528 /generic | |
parent | da196c33450ded41b2370bf956f7d3cd7b081069 (diff) | |
download | tcl-71b0ad990caaf6a297049da2c63821a4e29c57ac.zip tcl-71b0ad990caaf6a297049da2c63821a4e29c57ac.tar.gz tcl-71b0ad990caaf6a297049da2c63821a4e29c57ac.tar.bz2 |
Reduce shimmering: If a conclusion can be drawn about the number of list elements, don't get the elements before the list length is checked
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclArithSeries.h | 4 | ||||
-rw-r--r-- | generic/tclAssembly.c | 5 | ||||
-rw-r--r-- | generic/tclBinary.c | 10 | ||||
-rw-r--r-- | generic/tclCmdAH.c | 6 | ||||
-rw-r--r-- | generic/tclCmdIL.c | 10 | ||||
-rw-r--r-- | generic/tclCmdMZ.c | 5 | ||||
-rw-r--r-- | generic/tclDecls.h | 1 | ||||
-rw-r--r-- | generic/tclEnsemble.c | 12 | ||||
-rw-r--r-- | generic/tclListObj.c | 4 | ||||
-rw-r--r-- | generic/tclProc.c | 8 | ||||
-rw-r--r-- | generic/tclTrace.c | 19 | ||||
-rw-r--r-- | generic/tclVar.c | 8 | ||||
-rw-r--r-- | generic/tclZipfs.c | 6 |
13 files changed, 76 insertions, 22 deletions
diff --git a/generic/tclArithSeries.h b/generic/tclArithSeries.h index 1daacdd..28fd993 100644 --- a/generic/tclArithSeries.h +++ b/generic/tclArithSeries.h @@ -15,7 +15,7 @@ * Note that the len can in theory be always computed by start,end,step * but it's faster to cache it inside the internal representation. */ -typedef struct ArithSeries { +typedef struct { Tcl_Size len; Tcl_Obj **elements; int isDouble; @@ -23,7 +23,7 @@ typedef struct ArithSeries { Tcl_WideInt end; Tcl_WideInt step; } ArithSeries; -typedef struct ArithSeriesDbl { +typedef struct { Tcl_Size len; Tcl_Obj **elements; int isDouble; diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c index dbf37bb8..ab5cd7a 100644 --- a/generic/tclAssembly.c +++ b/generic/tclAssembly.c @@ -1985,7 +1985,7 @@ CreateMirrorJumpTable( * table. */ int i; - if (TclListObjGetElementsM(interp, jumps, &objc, &objv) != TCL_OK) { + if (TclListObjLengthM(interp, jumps, &objc) != TCL_OK) { return TCL_ERROR; } if (objc % 2 != 0) { @@ -1997,6 +1997,9 @@ CreateMirrorJumpTable( } return TCL_ERROR; } + if (TclListObjGetElementsM(interp, jumps, &objc, &objv) != TCL_OK) { + return TCL_ERROR; + } /* * Allocate the jumptable. diff --git a/generic/tclBinary.c b/generic/tclBinary.c index e4c8766..b744203 100644 --- a/generic/tclBinary.c +++ b/generic/tclBinary.c @@ -1125,11 +1125,10 @@ BinaryFormatCmd( * The macro evals its args more than once: avoid arg++ */ - if (TclListObjGetElementsM(interp, objv[arg], &listc, - &listv) != TCL_OK) { + if (TclListObjLengthM(interp, objv[arg], &listc + ) != TCL_OK) { return TCL_ERROR; } - arg++; if (count == BINARY_ALL) { count = listc; @@ -1139,6 +1138,11 @@ BinaryFormatCmd( -1)); return TCL_ERROR; } + if (TclListObjGetElementsM(interp, objv[arg], &listc, + &listv) != TCL_OK) { + return TCL_ERROR; + } + arg++; } offset += count*size; break; diff --git a/generic/tclCmdAH.c b/generic/tclCmdAH.c index 9905633..2281b5a 100644 --- a/generic/tclCmdAH.c +++ b/generic/tclCmdAH.c @@ -2860,8 +2860,8 @@ EachloopCmd( result = TCL_ERROR; goto done; } - TclListObjGetElementsM(NULL, statePtr->vCopyList[i], - &statePtr->varcList[i], &statePtr->varvList[i]); + TclListObjLengthM(NULL, statePtr->vCopyList[i], + &statePtr->varcList[i]); if (statePtr->varcList[i] < 1) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s varlist is empty", @@ -2872,6 +2872,8 @@ EachloopCmd( result = TCL_ERROR; goto done; } + TclListObjGetElementsM(NULL, statePtr->vCopyList[i], + &statePtr->varcList[i], &statePtr->varvList[i]); /* Values */ if (TclHasInternalRep(objv[2+i*2],&tclArithSeriesType)) { diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index e2493c4..8e52d65 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -20,6 +20,7 @@ #include "tclInt.h" #include "tclRegexp.h" #include "tclArithSeries.h" +#include "tclTomMath.h" #include <math.h> #include <assert.h> @@ -2573,6 +2574,7 @@ Tcl_LlengthObjCmd( /* Argument objects. */ { int listLen, result; + Tcl_Obj *objPtr; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "list"); @@ -2589,7 +2591,8 @@ Tcl_LlengthObjCmd( * length. */ - Tcl_SetObjResult(interp, Tcl_NewWideIntObj(listLen)); + TclNewUIntObj(objPtr, listLen); + Tcl_SetObjResult(interp, objPtr); return TCL_OK; } @@ -3152,7 +3155,7 @@ Tcl_LreverseObjCmd( } /* end ArithSeries */ /* True List */ - if (TclListObjGetElementsM(interp, objv[1], &elemc, &elemv) != TCL_OK) { + if (TclListObjLengthM(interp, objv[1], &elemc) != TCL_OK) { return TCL_ERROR; } @@ -3164,6 +3167,9 @@ Tcl_LreverseObjCmd( Tcl_SetObjResult(interp, objv[1]); return TCL_OK; } + if (TclListObjGetElementsM(interp, objv[1], &elemc, &elemv) != TCL_OK) { + return TCL_ERROR; + } if (Tcl_IsShared(objv[1]) || ListObjRepIsShared(objv[1])) { /* Bug 1675044 */ diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 57541f9..147c2dc 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -3610,7 +3610,7 @@ TclNRSwitchObjCmd( Tcl_Obj **listv; blist = objv[0]; - if (TclListObjGetElementsM(interp, objv[0], &objc, &listv) != TCL_OK) { + if (TclListObjLengthM(interp, objv[0], &objc) != TCL_OK) { return TCL_ERROR; } @@ -3623,6 +3623,9 @@ TclNRSwitchObjCmd( "?-option ...? string {?pattern body ...? ?default body?}"); return TCL_ERROR; } + if (TclListObjGetElementsM(interp, objv[0], &objc, &listv) != TCL_OK) { + return TCL_ERROR; + } objv = listv; splitObjs = 1; } diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 75fc17e..d8b4b5d 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -4182,6 +4182,7 @@ extern const TclStubs *tclStubsPtr; /* !END!: Do not edit above this line. */ #undef TclUnusedStubEntry + #if defined(USE_TCL_STUBS) # undef Tcl_CreateInterp # undef Tcl_FindExecutable diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c index 88b611f..963f1d8 100644 --- a/generic/tclEnsemble.c +++ b/generic/tclEnsemble.c @@ -562,8 +562,8 @@ TclNamespaceEnsembleCmd( continue; } do { - if (TclListObjGetElementsM(interp, listObj, &len, - &listv) != TCL_OK) { + if (TclListObjLengthM(interp, listObj, &len + ) != TCL_OK) { Tcl_DictObjDone(&search); if (patchedDict) { Tcl_DecrRefCount(patchedDict); @@ -582,6 +582,14 @@ TclNamespaceEnsembleCmd( } goto freeMapAndError; } + if (TclListObjGetElementsM(interp, listObj, &len, + &listv) != TCL_OK) { + Tcl_DictObjDone(&search); + if (patchedDict) { + Tcl_DecrRefCount(patchedDict); + } + goto freeMapAndError; + } cmd = TclGetString(listv[0]); if (!(cmd[0] == ':' && cmd[1] == ':')) { Tcl_Obj *newList = Tcl_DuplicateObj(listObj); diff --git a/generic/tclListObj.c b/generic/tclListObj.c index 776ff0e..80477f7 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -1994,7 +1994,7 @@ int Tcl_ListObjLength( Tcl_Interp *interp, /* Used to report errors if not NULL. */ Tcl_Obj *listObj, /* List object whose #elements to return. */ - Tcl_Size *lenPtr) /* The resulting int is stored here. */ + Tcl_Size *lenPtr) /* The resulting length is stored here. */ { ListRep listRep; @@ -2632,7 +2632,7 @@ TclLindexFlat( /* Handle ArithSeries as special case */ if (TclHasInternalRep(listObj,&tclArithSeriesType)) { - Tcl_WideInt listLen = TclArithSeriesObjLength(listObj); + Tcl_Size listLen = TclArithSeriesObjLength(listObj); Tcl_Size index; Tcl_Obj *elemObj = NULL; for (i=0 ; i<indexCount && listObj ; i++) { diff --git a/generic/tclProc.c b/generic/tclProc.c index b8c324e..3ada9ea 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -2508,6 +2508,14 @@ SetLambdaFromAny( * length is not 2, then it cannot be converted to lambdaType. */ + result = TclListObjLengthM(NULL, objPtr, &objc); + if ((result != TCL_OK) || ((objc != 2) && (objc != 3))) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't interpret \"%s\" as a lambda expression", + Tcl_GetString(objPtr))); + Tcl_SetErrorCode(interp, "TCL", "VALUE", "LAMBDA", NULL); + return TCL_ERROR; + } result = TclListObjGetElementsM(NULL, objPtr, &objc, &objv); if ((result != TCL_OK) || ((objc != 2) && (objc != 3))) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( diff --git a/generic/tclTrace.c b/generic/tclTrace.c index e2be167..3e8844a 100644 --- a/generic/tclTrace.c +++ b/generic/tclTrace.c @@ -429,7 +429,7 @@ TraceExecutionObjCmd( * pointer to its array of element pointers. */ - result = TclListObjGetElementsM(interp, objv[4], &listLen, &elemPtrs); + result = TclListObjLengthM(interp, objv[4], &listLen); if (result != TCL_OK) { return result; } @@ -441,6 +441,10 @@ TraceExecutionObjCmd( NULL); return TCL_ERROR; } + result = TclListObjGetElementsM(interp, objv[4], &listLen, &elemPtrs); + if (result != TCL_OK) { + return result; + } for (i = 0; i < listLen; i++) { if (Tcl_GetIndexFromObj(interp, elemPtrs[i], opStrings, "operation", TCL_EXACT, &index) != TCL_OK) { @@ -672,7 +676,7 @@ TraceCommandObjCmd( * pointer to its array of element pointers. */ - result = TclListObjGetElementsM(interp, objv[4], &listLen, &elemPtrs); + result = TclListObjLengthM(interp, objv[4], &listLen); if (result != TCL_OK) { return result; } @@ -684,7 +688,10 @@ TraceCommandObjCmd( NULL); return TCL_ERROR; } - + result = TclListObjGetElementsM(interp, objv[4], &listLen, &elemPtrs); + if (result != TCL_OK) { + return result; + } for (i = 0; i < listLen; i++) { if (Tcl_GetIndexFromObj(interp, elemPtrs[i], opStrings, "operation", TCL_EXACT, &index) != TCL_OK) { @@ -873,7 +880,7 @@ TraceVariableObjCmd( * pointer to its array of element pointers. */ - result = TclListObjGetElementsM(interp, objv[4], &listLen, &elemPtrs); + result = TclListObjLengthM(interp, objv[4], &listLen); if (result != TCL_OK) { return result; } @@ -885,6 +892,10 @@ TraceVariableObjCmd( NULL); return TCL_ERROR; } + result = TclListObjGetElementsM(interp, objv[4], &listLen, &elemPtrs); + if (result != TCL_OK) { + return result; + } for (i = 0; i < listLen ; i++) { if (Tcl_GetIndexFromObj(interp, elemPtrs[i], opStrings, "operation", TCL_EXACT, &index) != TCL_OK) { diff --git a/generic/tclVar.c b/generic/tclVar.c index 2a96fb6..c614371 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -4161,8 +4161,7 @@ ArraySetCmd( int elemLen; Tcl_Obj **elemPtrs, *copyListObj; - result = TclListObjGetElementsM(interp, arrayElemObj, - &elemLen, &elemPtrs); + result = TclListObjLengthM(interp, arrayElemObj, &elemLen); if (result != TCL_OK) { return result; } @@ -4175,6 +4174,11 @@ ArraySetCmd( if (elemLen == 0) { goto ensureArray; } + result = TclListObjGetElementsM(interp, arrayElemObj, + &elemLen, &elemPtrs); + if (result != TCL_OK) { + return result; + } /* * We needn't worry about traces invalidating arrayPtr: should that be diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 3b1d787..1b602ea 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -3044,7 +3044,7 @@ ZipFSMkZipOrImg( } } Tcl_IncrRefCount(list); - if (TclListObjGetElementsM(interp, list, &lobjc, &lobjv) != TCL_OK) { + if (TclListObjLengthM(interp, list, &lobjc) != TCL_OK) { Tcl_DecrRefCount(list); return TCL_ERROR; } @@ -3060,6 +3060,10 @@ ZipFSMkZipOrImg( ZIPFS_ERROR_CODE(interp, "EMPTY"); return TCL_ERROR; } + if (TclListObjGetElementsM(interp, list, &lobjc, &lobjv) != TCL_OK) { + Tcl_DecrRefCount(list); + return TCL_ERROR; + } out = Tcl_FSOpenFileChannel(interp, targetFile, "wb", 0755); if (out == NULL) { Tcl_DecrRefCount(list); |