diff options
author | sebres <sebres@users.sourceforge.net> | 2019-04-08 15:03:13 (GMT) |
---|---|---|
committer | sebres <sebres@users.sourceforge.net> | 2019-04-08 15:03:13 (GMT) |
commit | 3a8a841386b2df65eca6c7018106438bc7c6d07d (patch) | |
tree | 76eedb7e68ef6909bbe93be026cac36d87ddb876 | |
parent | c1de90d70a6cac71dc4200eb9d9fb2b08a8f9b1c (diff) | |
download | tcl-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.c | 6 | ||||
-rw-r--r-- | generic/tclVar.c | 11 |
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. |