summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2019-01-31 12:52:56 (GMT)
committersebres <sebres@users.sourceforge.net>2019-01-31 12:52:56 (GMT)
commitfc5dc8e81101cd4ed4970ab6451792f7fa975811 (patch)
treec757e494573ed730bf351e558352d6903229a9fc /generic
parent8a8e70d5a6a4db9ed214aa5d0b81bf0a63f910cd (diff)
downloadtcl-fc5dc8e81101cd4ed4970ab6451792f7fa975811.zip
tcl-fc5dc8e81101cd4ed4970ab6451792f7fa975811.tar.gz
tcl-fc5dc8e81101cd4ed4970ab6451792f7fa975811.tar.bz2
code review with small amend (note nameLength is number of bytes, the argument may be utf-8 as well as not necessarily a NTS, so access of char after end may cause segfault).
Diffstat (limited to 'generic')
-rw-r--r--generic/tclInt.h5
-rw-r--r--generic/tclProc.c33
2 files changed, 18 insertions, 20 deletions
diff --git a/generic/tclInt.h b/generic/tclInt.h
index 5b0206f..b5f9f76 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -902,9 +902,8 @@ typedef struct CompiledLocal {
/* Next compiler-recognized local variable for
* this procedure, or NULL if this is the last
* local. */
- int nameLength; /* The number of bytes in local
- * variable's name. Used to speed up variable
- * lookups. */
+ int nameLength; /* The number of bytes in local variable's name.
+ * Among others used to speed up var lookups. */
int frameIndex; /* Index in the array of compiler-assigned
* variables in the procedure call frame. */
int flags; /* Flag bits for the local variable. Same as
diff --git a/generic/tclProc.c b/generic/tclProc.c
index f9869b8..03cb0f0 100644
--- a/generic/tclProc.c
+++ b/generic/tclProc.c
@@ -371,11 +371,9 @@ TclCreateProc(
Interp *iPtr = (Interp *) interp;
register Proc *procPtr;
- int i, result, numArgs, plen;
- const char *bytes, *argname, *argnamei;
- char argnamelast;
+ int i, result, numArgs;
register CompiledLocal *localPtr = NULL;
- Tcl_Obj *defPtr, *errorObj, **argArray;
+ Tcl_Obj **argArray;
int precompiled = 0;
if (bodyPtr->typePtr == &tclProcBodyType) {
@@ -412,6 +410,7 @@ TclCreateProc(
*/
if (Tcl_IsShared(bodyPtr)) {
+ const char *bytes;
int length;
Tcl_Obj *sharedBodyPtr = bodyPtr;
@@ -474,6 +473,7 @@ TclCreateProc(
}
for (i = 0; i < numArgs; i++) {
+ const char *argname, *argnamei, *argnamelast;
int fieldCount, nameLength;
Tcl_Obj **fieldValues;
@@ -487,7 +487,7 @@ TclCreateProc(
goto procError;
}
if (fieldCount > 2) {
- errorObj = Tcl_NewStringObj(
+ Tcl_Obj *errorObj = Tcl_NewStringObj(
"too many fields in argument specifier \"", -1);
Tcl_AppendObjToObj(errorObj, argArray[i]);
Tcl_AppendToObj(errorObj, "\"", -1);
@@ -511,11 +511,10 @@ TclCreateProc(
*/
argnamei = argname;
- plen = nameLength;
- argnamelast = argname[plen-1];
- while (plen--) {
- if (argnamei[0] == '(') {
- if (argnamelast == ')') { /* We have an array element. */
+ argnamelast = Tcl_UtfPrev(argname + nameLength, argname);
+ while (argnamei < argnamelast) {
+ if (*argnamei == '(') {
+ if (*argnamelast == ')') { /* We have an array element. */
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"formal parameter \"%s\" is an array element",
Tcl_GetString(fieldValues[0])));
@@ -523,8 +522,9 @@ TclCreateProc(
"FORMALARGUMENTFORMAT", NULL);
goto procError;
}
- } else if ((argnamei[0] == ':') && (argnamei[1] == ':')) {
- errorObj = Tcl_NewStringObj("formal parameter \"", -1);
+ } else if (*argnamei == ':' && *(argnamei+1) == ':') {
+ Tcl_Obj *errorObj = Tcl_NewStringObj(
+ "formal parameter \"", -1);
Tcl_AppendObjToObj(errorObj, fieldValues[0]);
Tcl_AppendToObj(errorObj, "\" is not a simple name", -1);
Tcl_SetObjResult(interp, errorObj);
@@ -575,8 +575,8 @@ TclCreateProc(
if ((valueLength != tmpLength)
|| memcmp(value, tmpPtr, tmpLength) != 0
) {
- errorObj = Tcl_ObjPrintf(
- "procedure \"%s\": formal parameter \"" ,procName);
+ Tcl_Obj *errorObj = Tcl_ObjPrintf(
+ "procedure \"%s\": formal parameter \"", procName);
Tcl_AppendObjToObj(errorObj, fieldValues[0]);
Tcl_AppendToObj(errorObj, "\" has "
"default value inconsistent with precompiled body", -1);
@@ -641,9 +641,8 @@ TclCreateProc(
localPtr = procPtr->firstLocalPtr;
procPtr->firstLocalPtr = localPtr->nextPtr;
- defPtr = localPtr->defValuePtr;
- if (defPtr != NULL) {
- Tcl_DecrRefCount(defPtr);
+ if (localPtr->defValuePtr != NULL) {
+ Tcl_DecrRefCount(localPtr->defValuePtr);
}
ckfree(localPtr);