summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2003-06-10 19:58:25 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2003-06-10 19:58:25 (GMT)
commiteb3d0976d6642da1d58097dd0c63336427f68e3d (patch)
treea89c6d5cb9c9431ba2df9e76e0b0de0ee9bcae8c
parent88bf24e7cb31b621f6232bbe780c1ea64a5c77cc (diff)
downloadtcl-eb3d0976d6642da1d58097dd0c63336427f68e3d.zip
tcl-eb3d0976d6642da1d58097dd0c63336427f68e3d.tar.gz
tcl-eb3d0976d6642da1d58097dd0c63336427f68e3d.tar.bz2
* 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
-rw-r--r--ChangeLog8
-rw-r--r--generic/tclBasic.c36
-rw-r--r--generic/tclExecute.c9
-rw-r--r--tests/interp.test12
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 <msofer@users.sf.net>
+
+ * 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 <dgp@users.sourceforge.net>
* 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