aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2017-05-12 12:41:21 +1000
committerSteve Bennett <steveb@workware.net.au>2017-05-12 13:01:45 +1000
commitbc1afe36eb28a54f62503d18e2228a81330ca4ac (patch)
tree17817d9806654ee53be3060afea552600850717f
parent1d6b931d0c873bbad193677734dc9d352628577b (diff)
downloadjimtcl-bc1afe36eb28a54f62503d18e2228a81330ca4ac.zip
jimtcl-bc1afe36eb28a54f62503d18e2228a81330ca4ac.tar.gz
jimtcl-bc1afe36eb28a54f62503d18e2228a81330ca4ac.tar.bz2
jim: Fix ref count problem with interpolated dict subst
When duplicating interpolated object type, need to increment ref count of the key to offset the decrement during free. Also remove type-specific dup for dict-substitution which is not needed since it does nothing different from the default dup. Reported-by: Ryan Whitworth <me@ryanwhitworth.com> Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r--jim.c34
-rw-r--r--regtest.tcl1
2 files changed, 18 insertions, 17 deletions
diff --git a/jim.c b/jim.c
index 51f3569..d324e56 100644
--- a/jim.c
+++ b/jim.c
@@ -2307,29 +2307,39 @@ static void JimSetStringBytes(Jim_Obj *objPtr, const char *str)
}
static void FreeDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *objPtr);
-static void DupDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr);
static const Jim_ObjType dictSubstObjType = {
"dict-substitution",
FreeDictSubstInternalRep,
- DupDictSubstInternalRep,
+ NULL,
NULL,
JIM_TYPE_NONE,
};
-static void FreeInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *objPtr)
-{
- Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.indexObjPtr);
-}
+static void FreeInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *objPtr);
+static void DupInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr);
static const Jim_ObjType interpolatedObjType = {
"interpolated",
FreeInterpolatedInternalRep,
- NULL,
+ DupInterpolatedInternalRep,
NULL,
JIM_TYPE_NONE,
};
+static void FreeInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *objPtr)
+{
+ Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.indexObjPtr);
+}
+
+static void DupInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr)
+{
+ /* Copy the interal rep */
+ dupPtr->internalRep = srcPtr->internalRep;
+ /* Need to increment the key ref count */
+ Jim_IncrRefCount(dupPtr->internalRep.dictSubstValue.indexObjPtr);
+}
+
/* -----------------------------------------------------------------------------
* String Object
* ---------------------------------------------------------------------------*/
@@ -4851,16 +4861,6 @@ void FreeDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *objPtr)
Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.indexObjPtr);
}
-void DupDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr)
-{
- JIM_NOTUSED(interp);
-
- dupPtr->internalRep.dictSubstValue.varNameObjPtr =
- srcPtr->internalRep.dictSubstValue.varNameObjPtr;
- dupPtr->internalRep.dictSubstValue.indexObjPtr = srcPtr->internalRep.dictSubstValue.indexObjPtr;
- dupPtr->typePtr = &dictSubstObjType;
-}
-
/* Note: The object *must* be in dict-sugar format */
static void SetDictSubstFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
{
diff --git a/regtest.tcl b/regtest.tcl
index c18e662..2b0fe8c 100644
--- a/regtest.tcl
+++ b/regtest.tcl
@@ -292,6 +292,7 @@ puts "TEST 39 PASSED"
# ref count problem - double free
set d [dict create a b]
lsort r($d)
+catch {dict remove r($d) m}
puts "TEST 40 PASSED"
# TAKE THE FOLLOWING puts AS LAST LINE