From 18d9d66f4d3a6a8b468474e25d5bacee500bda85 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 4 Jan 2013 14:38:37 +0000 Subject: Fix bad memory access problems found by Miguel Sofer when valgrinding. --- generic/tclCompCmdsSZ.c | 2 +- generic/tclEnsemble.c | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index 7bead0d..1d04d8b 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -2737,7 +2737,7 @@ TclCompileUnsetCmd( flags = 1; varTokenPtr = TokenAfter(parsePtr->tokenPtr); leadingWord = Tcl_NewObj(); - if (TclWordKnownAtCompileTime(varTokenPtr, leadingWord)) { + if (numWords > 0 && TclWordKnownAtCompileTime(varTokenPtr, leadingWord)) { int len; const char *bytes = Tcl_GetStringFromObj(leadingWord, &len); diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c index 4e2a5cd..9a2d598 100644 --- a/generic/tclEnsemble.c +++ b/generic/tclEnsemble.c @@ -2956,9 +2956,14 @@ TclCompileEnsemble( Tcl_ListObjAppendElement(NULL, replaced, replacement); if (Tcl_ListObjGetElements(NULL, targetCmdObj, &len, &elems) != TCL_OK) { goto failed; - } - if (len != 1) { - goto failed; + } else if (len != 1) { + /* + * Note that at this point we know we can't issue any special + * instruction sequence as the mapping isn't one that we support at + * the compiled level. + */ + + goto cleanup; } targetCmdObj = elems[0]; @@ -3011,7 +3016,7 @@ TclCompileEnsemble( */ failed: - if (len == 1 && depth < 250) { + if (depth < 250) { if (depth > 1) { if (!invokeAnyway) { cmdPtr = oldCmdPtr; -- cgit v0.12 From a2640e1242a6bda25202eb5d73b7cc6a5fa239ef Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 4 Jan 2013 15:01:57 +0000 Subject: Fix memory leak in [format] compiler. --- generic/tclCompCmds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 8fa191b..752db93 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -3082,7 +3082,7 @@ TclCompileFormatCmd( * after our attempt to spot a literal). */ - for (; --i>=0 ;) { + for (; i>=0 ; i--) { Tcl_DecrRefCount(objv[i]); } ckfree(objv); -- cgit v0.12 From f5f116ff983872cb0da47325218d26f0348454f5 Mon Sep 17 00:00:00 2001 From: mig Date: Sat, 5 Jan 2013 00:15:19 +0000 Subject: Add an assertion that checks the stack depth under TCL_COMPILE_DEBUG *before* stack cleanup. It currently triggers at several spots in the testsuite! --- generic/tclExecute.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 3635bab..496bd9b 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -255,9 +255,16 @@ VarHashCreateVar( * and within range. */ -#define NEXT_INST_F(pcAdjustment, nCleanup, resultHandling) \ +#if TCL_COMPILE_DEBUG +#define CHECK_STACK() assert(CURR_DEPTH <= codePtr->maxStackDepth) +#else +#define CHECK_STACK() +#endif + +#define NEXT_INST_F(pcAdjustment, nCleanup, resultHandling) \ do { \ TCL_CT_ASSERT((nCleanup >= 0) && (nCleanup <= 2)); \ + CHECK_STACK(); \ if (nCleanup == 0) { \ if (resultHandling != 0) { \ if ((resultHandling) > 0) { \ @@ -286,7 +293,8 @@ VarHashCreateVar( } \ } while (0) -#define NEXT_INST_V(pcAdjustment, nCleanup, resultHandling) \ +#define NEXT_INST_V(pcAdjustment, nCleanup, resultHandling) \ + CHECK_STACK(); \ do { \ pc += (pcAdjustment); \ cleanup = (nCleanup); \ -- cgit v0.12 From 0498b26260e48f53a79c30db281432e57c78b966 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 5 Jan 2013 00:28:11 +0000 Subject: adjust stub library version number --- doc/InitStubs.3 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/InitStubs.3 b/doc/InitStubs.3 index 2cfbb70..e43d23e 100644 --- a/doc/InitStubs.3 +++ b/doc/InitStubs.3 @@ -64,8 +64,8 @@ Define the USE_TCL_STUBS symbol. Typically, you would include the .IP 3) 5 Link the extension with the Tcl stubs library instead of the standard Tcl library. On Unix platforms, the library name is -\fIlibtclstub8.1.a\fR; on Windows platforms, the library name is -\fItclstub81.lib\fR. +\fIlibtclstub8.4.a\fR; on Windows platforms, the library name is +\fItclstub84.lib\fR. .PP If the extension also requires the Tk API, it must also call \fBTk_InitStubs\fR to initialize the Tk stubs interface and link -- cgit v0.12 From 8ed264286869e58830dbd831907ca25189123d6c Mon Sep 17 00:00:00 2001 From: mig Date: Sat, 5 Jan 2013 00:36:25 +0000 Subject: fix the new assertion, it should not trigger when an expansion is in progress --- generic/tclExecute.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 496bd9b..fbf8f6d 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -251,12 +251,15 @@ VarHashCreateVar( * otherwise, push objResultPtr. If (result < 0), objResultPtr already * has the correct reference count. * - * We use the new compile-time assertions to cheack that nCleanup is constant + * We use the new compile-time assertions to check that nCleanup is constant * and within range. */ +/* Verify the stack depth, only when no expansion is in progress */ + #if TCL_COMPILE_DEBUG -#define CHECK_STACK() assert(CURR_DEPTH <= codePtr->maxStackDepth) +#define CHECK_STACK() \ + assert((auxObjList != NULL) || (CURR_DEPTH <= codePtr->maxStackDepth)) #else #define CHECK_STACK() #endif -- cgit v0.12 From a9a9afc838c1d357e9a50c1045a90276f49edb42 Mon Sep 17 00:00:00 2001 From: mig Date: Sat, 5 Jan 2013 03:43:05 +0000 Subject: improved stack checking under TCL_COMPILE_DEBUG --- generic/tclExecute.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index fbf8f6d..8759ec9 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -259,7 +259,8 @@ VarHashCreateVar( #if TCL_COMPILE_DEBUG #define CHECK_STACK() \ - assert((auxObjList != NULL) || (CURR_DEPTH <= codePtr->maxStackDepth)) + ValidatePcAndStackTop(codePtr, pc, CURR_DEPTH, \ + /*checkStack*/ auxObjList == NULL) #else #define CHECK_STACK() #endif @@ -696,7 +697,7 @@ static void PrintByteCodeInfo(ByteCode *codePtr); static const char * StringForResultCode(int result); static void ValidatePcAndStackTop(ByteCode *codePtr, const unsigned char *pc, int stackTop, - int stackLowerBound, int checkStack); + int checkStack); #endif /* TCL_COMPILE_DEBUG */ static ByteCode * CompileExprObj(Tcl_Interp *interp, Tcl_Obj *objPtr); static void DeleteExecStack(ExecStack *esPtr); @@ -2254,8 +2255,7 @@ TEBCresume( * Skip the stack depth check if an expansion is in progress. */ - ValidatePcAndStackTop(codePtr, pc, CURR_DEPTH, 0, - /*checkStack*/ auxObjList == NULL); + CHECK_STACK(); if (traceInstructions) { fprintf(stdout, "%2d: %2d ", iPtr->numLevels, (int) CURR_DEPTH); TclPrintInstruction(codePtr, pc); @@ -8571,11 +8571,10 @@ ValidatePcAndStackTop( int stackTop, /* Current stack top. Must be between * stackLowerBound and stackUpperBound * (inclusive). */ - int stackLowerBound, /* Smallest legal value for stackTop. */ int checkStack) /* 0 if the stack depth check should be * skipped. */ { - int stackUpperBound = stackLowerBound + codePtr->maxStackDepth; + int stackUpperBound = codePtr->maxStackDepth; /* Greatest legal value for stackTop. */ unsigned relativePc = (unsigned) (pc - codePtr->codeStart); unsigned long codeStart = (unsigned long) codePtr->codeStart; @@ -8593,13 +8592,13 @@ ValidatePcAndStackTop( (unsigned) opCode, relativePc); Tcl_Panic("TclNRExecuteByteCode execution failure: bad opcode"); } - if (checkStack && - ((stackTop < stackLowerBound) || (stackTop > stackUpperBound))) { + if (checkStack && + ((stackTop < 0) || (stackTop > stackUpperBound))) { int numChars; const char *cmd = GetSrcInfoForPc(pc, codePtr, &numChars, NULL); - fprintf(stderr, "\nBad stack top %d at pc %u in TclNRExecuteByteCode (min %i, max %i)", - stackTop, relativePc, stackLowerBound, stackUpperBound); + fprintf(stderr, "\nBad stack top %d at pc %u in TclNRExecuteByteCode (min 0, max %i)", + stackTop, relativePc, stackUpperBound); if (cmd != NULL) { Tcl_Obj *message; -- cgit v0.12