From bc1afe36eb28a54f62503d18e2228a81330ca4ac Mon Sep 17 00:00:00 2001 From: Steve Bennett Date: Fri, 12 May 2017 12:41:21 +1000 Subject: 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 Signed-off-by: Steve Bennett --- jim.c | 34 +++++++++++++++++----------------- regtest.tcl | 1 + 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 -- cgit v1.1