summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2022-11-28 23:16:31 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2022-11-28 23:16:31 (GMT)
commit71b0ad990caaf6a297049da2c63821a4e29c57ac (patch)
treef27faff96ed68e42d4c00da3a522f9eef06a2528 /generic
parentda196c33450ded41b2370bf956f7d3cd7b081069 (diff)
downloadtcl-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.h4
-rw-r--r--generic/tclAssembly.c5
-rw-r--r--generic/tclBinary.c10
-rw-r--r--generic/tclCmdAH.c6
-rw-r--r--generic/tclCmdIL.c10
-rw-r--r--generic/tclCmdMZ.c5
-rw-r--r--generic/tclDecls.h1
-rw-r--r--generic/tclEnsemble.c12
-rw-r--r--generic/tclListObj.c4
-rw-r--r--generic/tclProc.c8
-rw-r--r--generic/tclTrace.c19
-rw-r--r--generic/tclVar.c8
-rw-r--r--generic/tclZipfs.c6
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);