From 0c2604871db8e162533e9729c9e5201334510785 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 3 Jun 2015 12:26:38 +0000 Subject: [268b23df11] When GetSrcInfoForPc() returns NULL, make sure it also sets the length to a non-positive value so nothing tries to read offsets from a NULL pointer. --- generic/tclExecute.c | 14 ++++++-------- tests/execute.test | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 43c2b08..5957951 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -9995,10 +9995,8 @@ GetSrcInfoForPc( int bestSrcLength = -1; /* Initialized to avoid compiler warning. */ int bestCmdIdx = -1; - if ((pcOffset < 0) || (pcOffset >= codePtr->numCodeBytes)) { - if (pcBeg != NULL) *pcBeg = NULL; - return NULL; - } + /* The pc must point within the bytecode */ + assert ((pcOffset >= 0) && (pcOffset < codePtr->numCodeBytes)); /* * Decode the code and source offset and length for each command. The @@ -10083,10 +10081,6 @@ GetSrcInfoForPc( *pcBeg = prev; } - if (bestDist == INT_MAX) { - return NULL; - } - if (lengthPtr != NULL) { *lengthPtr = bestSrcLength; } @@ -10095,6 +10089,10 @@ GetSrcInfoForPc( *cmdIdxPtr = bestCmdIdx; } + if (bestDist == INT_MAX) { + return NULL; + } + return (codePtr->source + bestSrcOffset); } diff --git a/tests/execute.test b/tests/execute.test index 94af158..aaf4bc0 100644 --- a/tests/execute.test +++ b/tests/execute.test @@ -1043,6 +1043,20 @@ test execute-11.1 {Bug 3142026: GrowEvaluationStack off-by-one} -setup { } -cleanup { interp delete slave } -result ok + +test execute-11.2 {Bug 268b23df11} -setup { + proc zero {} {return 0} + proc crash {} {expr {abs([zero])}} + proc noop args {} + trace add execution crash enterstep noop +} -body { + crash +} -cleanup { + trace remove execution crash enterstep noop + rename noop {} + rename crash {} + rename zero {} +} -result 0 # cleanup if {[info commands testobj] != {}} { -- cgit v0.12 From 40e080788cc6a4045283e0cc0d4cd3317bfadac3 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 3 Jun 2015 17:40:10 +0000 Subject: Put the ellipsis inside, not outside, the close quote. --- generic/tclDisassemble.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index b3753c31..0a325b3 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -842,10 +842,10 @@ PrintSourceToObj( continue; } } - Tcl_AppendToObj(appendObj, "\"", -1); if (*p != '\0') { Tcl_AppendToObj(appendObj, "...", -1); } + Tcl_AppendToObj(appendObj, "\"", -1); } /* -- cgit v0.12 From f3337d5804891dde384cbc16b853b551ce5187d0 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 3 Jun 2015 19:08:15 +0000 Subject: [268b23df11] Revised patch to create phony source string when the original script does not actually contain the command being invoked. (Example: the tcl::mathfunc::* command invoked via [expr] interpretation) --- generic/tclExecute.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 5957951..4a6c009 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -8235,6 +8235,7 @@ TEBCresume( bytes = GetSrcInfoForPc(pc, codePtr, &length, NULL, NULL); opnd = TclGetUInt4AtPtr(pc+1); pc += (opnd-1); + assert(bytes); PUSH_OBJECT(Tcl_NewStringObj(bytes, length)); goto instEvalStk; } @@ -9900,7 +9901,12 @@ TclGetSourceFromFrame( cfPtr->cmd = GetSrcInfoForPc((unsigned char *) cfPtr->data.tebc.pc, codePtr, &cfPtr->len, NULL, NULL); } - cfPtr->cmdObj = Tcl_NewStringObj(cfPtr->cmd, cfPtr->len); + if (cfPtr->cmd) { + cfPtr->cmdObj = Tcl_NewStringObj(cfPtr->cmd, cfPtr->len); + } else { + cfPtr->cmdObj = Tcl_NewListObj(objc, objv); + cfPtr->cmd = Tcl_GetStringFromObj(cfPtr->cmdObj, &cfPtr->len); + } Tcl_IncrRefCount(cfPtr->cmdObj); } return cfPtr->cmdObj; @@ -10081,6 +10087,10 @@ GetSrcInfoForPc( *pcBeg = prev; } + if (bestDist == INT_MAX) { + return NULL; + } + if (lengthPtr != NULL) { *lengthPtr = bestSrcLength; } @@ -10089,10 +10099,6 @@ GetSrcInfoForPc( *cmdIdxPtr = bestCmdIdx; } - if (bestDist == INT_MAX) { - return NULL; - } - return (codePtr->source + bestSrcOffset); } -- cgit v0.12