summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2019-04-08 15:03:13 (GMT)
committersebres <sebres@users.sourceforge.net>2019-04-08 15:03:13 (GMT)
commit3a8a841386b2df65eca6c7018106438bc7c6d07d (patch)
tree76eedb7e68ef6909bbe93be026cac36d87ddb876
parentc1de90d70a6cac71dc4200eb9d9fb2b08a8f9b1c (diff)
downloadtcl-3a8a841386b2df65eca6c7018106438bc7c6d07d.zip
tcl-3a8a841386b2df65eca6c7018106438bc7c6d07d.tar.gz
tcl-3a8a841386b2df65eca6c7018106438bc7c6d07d.tar.bz2
closes [45b9faf103f2] (tclVar cached lookup): fixes segfaulting if variable released before set; partially revert [4100488a3ca38abf]
-rw-r--r--generic/tclCmdMZ.c6
-rw-r--r--generic/tclVar.c11
2 files changed, 9 insertions, 8 deletions
diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c
index 5eb854b..2671d49 100644
--- a/generic/tclCmdMZ.c
+++ b/generic/tclCmdMZ.c
@@ -4812,24 +4812,18 @@ TryPostBody(
Tcl_Obj *varName;
Tcl_ListObjIndex(NULL, info[3], 0, &varName);
- Tcl_IncrRefCount(varName);
if (Tcl_ObjSetVar2(interp, varName, NULL, resultObj,
TCL_LEAVE_ERR_MSG) == NULL) {
- Tcl_DecrRefCount(varName);
Tcl_DecrRefCount(resultObj);
goto handlerFailed;
}
- Tcl_DecrRefCount(varName);
Tcl_DecrRefCount(resultObj);
if (dummy > 1) {
Tcl_ListObjIndex(NULL, info[3], 1, &varName);
- Tcl_IncrRefCount(varName);
if (Tcl_ObjSetVar2(interp, varName, NULL, options,
TCL_LEAVE_ERR_MSG) == NULL) {
- Tcl_DecrRefCount(varName);
goto handlerFailed;
}
- Tcl_DecrRefCount(varName);
}
} else {
/*
diff --git a/generic/tclVar.c b/generic/tclVar.c
index 3271935..affc848 100644
--- a/generic/tclVar.c
+++ b/generic/tclVar.c
@@ -722,7 +722,7 @@ TclObjLookupVarEx(
Tcl_Obj *cachedNamePtr = localName(varFramePtr, index);
if (part1Ptr == cachedNamePtr) {
- cachedNamePtr = NULL;
+ LocalSetIntRep(part1Ptr, index, NULL);
} else {
/*
* [80304238ac] Trickiness here. We will store and incr the
@@ -735,6 +735,14 @@ TclObjLookupVarEx(
* cachedNamePtr and leave it as string only. This is
* radical and destructive, so a better idea would be welcome.
*/
+
+ /*
+ * Firstly set cached local var reference (avoid free before set,
+ * see [45b9faf103f2])
+ */
+ LocalSetIntRep(part1Ptr, index, cachedNamePtr);
+
+ /* Then wipe it */
TclFreeIntRep(cachedNamePtr);
/*
@@ -744,7 +752,6 @@ TclObjLookupVarEx(
*/
LocalSetIntRep(cachedNamePtr, index, NULL);
}
- LocalSetIntRep(part1Ptr, index, cachedNamePtr);
} else {
/*
* At least mark part1Ptr as already parsed.