summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--generic/tclNamesp.c19
-rw-r--r--generic/tclVar.c22
-rw-r--r--tests/namespace.test26
4 files changed, 56 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 4931461..0c77a8c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2004-05-23 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclNamesp.c (Tcl_FindNamespaceVar): [Bug 959052] fixed,
+ insuring that no "zombie" variables are found.
+ * generic/tclVar.c (TclLookupSimpleVar): comments re [Bug 736729]
+ (predecessor of [Bug 959052]) removed.
+ * tests/namespace.test: added tests 17.10-12
+
2004-05-22 Miguel Sofer <msofer@users.sf.net>
* generic/tclVar.c (TclObjLookupVar, TclObjUnsetVar2): fix for new
diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c
index ded1f96..c369ccf 100644
--- a/generic/tclNamesp.c
+++ b/generic/tclNamesp.c
@@ -21,7 +21,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclNamesp.c,v 1.37 2004/03/24 21:54:32 dkf Exp $
+ * RCS: @(#) $Id: tclNamesp.c,v 1.38 2004/05/23 22:53:20 msofer Exp $
*/
#include "tclInt.h"
@@ -2324,6 +2324,23 @@ Tcl_FindNamespaceVar(interp, name, contextNsPtr, flags)
simpleName);
if (entryPtr != NULL) {
varPtr = (Var *) Tcl_GetHashValue(entryPtr);
+
+ /* Fix for [Bug 959052].
+ * When a varName is looked from a namespace different from the
+ * global one, there is no corresponding variable in the namespace and
+ * there is a "zombie" variable in the global namespace (ie, the
+ * varName is in the hash table, but the variable is unset), this code
+ * returns a reference to the zombie. Except when the zombie was
+ * created by a [variable] call, it should instead create a
+ * variable in the namespace.
+ * In particular, zombies created by [trace], [upvar], [global] or
+ * a reference in a tclNsVarNameType obj should never be found.
+ */
+ if (TclIsVarUndefined(varPtr)
+ && !(varPtr->flags & VAR_NAMESPACE_VAR)
+ && !(flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY))) {
+ varPtr = NULL;
+ }
}
}
}
diff --git a/generic/tclVar.c b/generic/tclVar.c
index 9097fd1..e84ce8f 100644
--- a/generic/tclVar.c
+++ b/generic/tclVar.c
@@ -15,7 +15,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclVar.c,v 1.81 2004/05/22 16:21:17 msofer Exp $
+ * RCS: @(#) $Id: tclVar.c,v 1.82 2004/05/23 22:53:20 msofer Exp $
*/
#include "tclInt.h"
@@ -758,30 +758,18 @@ TclLookupSimpleVar(interp, varName, flags, create, errMsgPtr, indexPtr)
}
}
- /*
- * FIXME: [Bug 736729]
- *
- * When a varName is looked from a namespace different from the
- * global one, there is no corresponding variable in the namespace and
- * there is a "zombie" variable in the global namespace (ie, the
- * varName is in the hash table, but the variable is unset), this code
- * returns a reference to the zombie. It should instead create a
- * variable in the namespace.
- *
- * Fix in progress - that it is not here yet may indicate that the
- * picture above is incomplete or wrong.
- * - Miguel Sofer, 2004-05-22
- */
-
/*
* Don't pass TCL_LEAVE_ERR_MSG, we may yet create the variable,
* or otherwise generate our own error!
*/
+
var = Tcl_FindNamespaceVar(interp, varName, (Tcl_Namespace *) cxtNsPtr,
flags & ~TCL_LEAVE_ERR_MSG);
+
if (var != (Tcl_Var) NULL) {
varPtr = (Var *) var;
}
+
if (varPtr == NULL) {
if (create) { /* var wasn't found so create it */
TclGetNamespaceForQualName(interp, varName, cxtNsPtr,
@@ -799,7 +787,7 @@ TclLookupSimpleVar(interp, varName, flags, create, errMsgPtr, indexPtr)
Tcl_SetHashValue(hPtr, varPtr);
varPtr->hPtr = hPtr;
varPtr->nsPtr = varNsPtr;
- if ((lookGlobal) || (varNsPtr == NULL)) {
+ if (lookGlobal) {
/*
* The variable was created starting from the global
* namespace: a global reference is returned even if
diff --git a/tests/namespace.test b/tests/namespace.test
index 941fad5..7e82ccb 100644
--- a/tests/namespace.test
+++ b/tests/namespace.test
@@ -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: namespace.test,v 1.25 2004/05/22 00:10:54 msofer Exp $
+# RCS: @(#) $Id: namespace.test,v 1.26 2004/05/23 22:53:21 msofer Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest 2
@@ -560,6 +560,30 @@ test namespace-17.9 {Tcl_FindNamespaceVar, relative name and TCL_GLOBAL_ONLY} {
}
set test_ns_1::a
} {hello}
+test namespace-17.10 {Tcl_FindNamespaceVar, do not find zombies (Bug 959052)} {
+ catch {unset x}
+ catch {namespace delete test_ns_1 }
+ catch {namespace delete test_ns_2}
+ namespace eval test_ns_1 upvar x q
+ namespace eval test_ns_2 set x 1
+ catch {set ::x}
+} 1
+test namespace-17.11 {Tcl_FindNamespaceVar, do not find zombies (Bug 959052)} {
+ catch {unset x}
+ catch {namespace delete test_ns_1}
+ trace add variable x write {;#}
+ namespace eval test_ns_1 set x 1
+ catch {set ::x}
+} 1
+test namespace-17.12 {Tcl_FindNamespaceVar, do not find zombies (Bug 959052)} {
+ catch {unset x}
+ catch {namespace delete test_ns_1}
+ namespace eval test_ns_1 {trace add variable x write {;#}}
+ set ::x 0
+ namespace eval test_ns_1 set x 1
+ set ::x
+} 1
+
catch {unset x}
catch {unset l}