From eb3d0976d6642da1d58097dd0c63336427f68e3d Mon Sep 17 00:00:00 2001 From: Miguel Sofer Date: Tue, 10 Jun 2003 19:58:25 +0000 Subject: * generic/tclBasic.c: * generic/tclExecute.c: let TclExecuteObjvInternal call TclInterpReady instead of relying on its callers to do so; fix for the part of [Bug 495830] that is new in 8.4. * tests/interp.test: Added tests 18.9 (knownbug) and 18.10 --- ChangeLog | 8 ++++++++ generic/tclBasic.c | 36 ++++++++++++++---------------------- generic/tclExecute.c | 9 ++++++--- tests/interp.test | 12 +++++++++++- 4 files changed, 39 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index a05d6c3..ad86d24 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2003-06-10 Miguel Sofer + + * generic/tclBasic.c: + * generic/tclExecute.c: let TclExecuteObjvInternal call + TclInterpReady instead of relying on its callers to do so; fix for + the part of [Bug 495830] that is new in 8.4. + * tests/interp.test: Added tests 18.9 (knownbug) and 18.10 + 2003-06-09 Don Porter * string.test (string-4.15): Added test for [string first] bug diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 8eda27e..80f5bda 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -13,7 +13,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclBasic.c,v 1.75.2.3 2003/05/12 20:16:08 dgp Exp $ + * RCS: @(#) $Id: tclBasic.c,v 1.75.2.4 2003/06/10 19:58:34 msofer Exp $ */ #include "tclInt.h" @@ -2919,7 +2919,7 @@ TclInterpReady(interp) * it's probably because of an infinite loop somewhere. */ - if (((iPtr->numLevels) >= iPtr->maxNestingDepth) + if (((iPtr->numLevels) > iPtr->maxNestingDepth) || (TclpCheckStackSpace() == 0)) { Tcl_AppendToObj(Tcl_GetObjResult(interp), "too many nested evaluations (infinite loop?)", -1); @@ -2936,9 +2936,7 @@ TclInterpReady(interp) * * This procedure evaluates a Tcl command that has already been * parsed into words, with one Tcl_Obj holding each word. The caller - * is responsible for checking that the interpreter is ready to - * evaluate (by calling TclInterpReady), and also to manage the - * iPtr->numLevels. + * is responsible for managing the iPtr->numLevels. * * Results: * The return value is a standard Tcl completion code such as @@ -2986,6 +2984,10 @@ TclEvalObjvInternal(interp, objc, objv, command, length, flags) int traceCode = TCL_OK; int checkTraces = 1; + if (TclInterpReady(interp) == TCL_ERROR) { + return TCL_ERROR; + } + if (objc == 0) { return TCL_OK; } @@ -3029,8 +3031,6 @@ TclEvalObjvInternal(interp, objc, objv, command, length, flags) "invalid command name \"", Tcl_GetString(objv[0]), "\"", (char *) NULL); code = TCL_ERROR; - } else if (TclInterpReady(interp) == TCL_ERROR) { - code = TCL_ERROR; } else { iPtr->numLevels++; code = TclEvalObjvInternal(interp, objc+1, newObjv, command, length, 0); @@ -3191,13 +3191,9 @@ Tcl_EvalObjv(interp, objc, objv, flags) } } - code = TclInterpReady(interp); - if (code == TCL_OK) { - iPtr->numLevels++; - code = TclEvalObjvInternal(interp, objc, objv, cmdString, cmdLen, - flags); - iPtr->numLevels--; - } + iPtr->numLevels++; + code = TclEvalObjvInternal(interp, objc, objv, cmdString, cmdLen, flags); + iPtr->numLevels--; /* * If we are again at the top level, process any unusual @@ -3666,14 +3662,10 @@ Tcl_EvalEx(interp, script, numBytes, flags) * Execute the command and free the objects for its words. */ - if (TclInterpReady(interp) == TCL_ERROR) { - code = TCL_ERROR; - } else { - iPtr->numLevels++; - code = TclEvalObjvInternal(interp, objectsUsed, objv, - parse.commandStart, parse.commandSize, 0); - iPtr->numLevels--; - } + iPtr->numLevels++; + code = TclEvalObjvInternal(interp, objectsUsed, objv, + parse.commandStart, parse.commandSize, 0); + iPtr->numLevels--; if (code != TCL_OK) { if (iPtr->numLevels == 0) { if (code == TCL_RETURN) { diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 272d939..578be7e 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclExecute.c,v 1.94.2.2 2003/04/18 20:06:05 hobbs Exp $ + * RCS: @(#) $Id: tclExecute.c,v 1.94.2.3 2003/06/10 19:58:35 msofer Exp $ */ #include "tclInt.h" @@ -895,7 +895,9 @@ TclCompEvalObj(interp, objPtr) * Check that the interpreter is ready to execute scripts */ + iPtr->numLevels++; if (TclInterpReady(interp) == TCL_ERROR) { + iPtr->numLevels--; return TCL_ERROR; } @@ -917,6 +919,7 @@ TclCompEvalObj(interp, objPtr) iPtr->errorLine = 1; result = tclByteCodeType.setFromAnyProc(interp, objPtr); if (result != TCL_OK) { + iPtr->numLevels--; return result; } iPtr->evalFlags = 0; @@ -976,9 +979,7 @@ TclCompEvalObj(interp, objPtr) */ codePtr->refCount++; - iPtr->numLevels++; result = TclExecuteByteCode(interp, codePtr); - iPtr->numLevels--; codePtr->refCount--; if (codePtr->refCount <= 0) { TclCleanupByteCode(codePtr); @@ -986,6 +987,8 @@ TclCompEvalObj(interp, objPtr) } else { result = TCL_OK; } + iPtr->numLevels--; + /* * If no commands at all were executed, check for asynchronous diff --git a/tests/interp.test b/tests/interp.test index f29aec6..e4b34eb 100644 --- a/tests/interp.test +++ b/tests/interp.test @@ -10,7 +10,7 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # -# RCS: @(#) $Id: interp.test,v 1.19.2.3 2003/05/12 22:35:40 dgp Exp $ +# RCS: @(#) $Id: interp.test,v 1.19.2.4 2003/06/10 19:58:37 msofer Exp $ if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2.1 @@ -759,6 +759,16 @@ if {[info commands testinterpdelete] == ""} { list [catch {a eval foo} msg] $msg } {1 {attempt to call eval in deleted interpreter}} } +test interp-18.9 {eval in deleted interp, bug 495830} {knownbug} { + interp create tst + interp alias tst suicide {} interp delete tst + list [catch {tst eval {suicide; set a 5}} msg] $msg +} {1 {attempt to call eval in deleted interpreter}} +test interp-18.10 {eval in deleted interp, bug 495830} { + interp create tst + interp alias tst suicide {} interp delete tst + list [catch {tst eval {set set set; suicide; $set a 5}} msg] $msg +} {1 {attempt to call eval in deleted interpreter}} # Test alias deletion -- cgit v0.12