From 306e6900a04b226e12b76ba8d7c4366b0b336c9a Mon Sep 17 00:00:00 2001 From: Miguel Sofer Date: Fri, 18 Jul 2008 04:23:35 +0000 Subject: * generic/tclDictObj.c (DictWithCmd, DictUpdateCmd): fix refcounting bugs that caused crashes [Bug 2017857]. * generic/tclBasic.c (TclNREvalObjEx): streamline the management of the command frame (opt). --- ChangeLog | 8 ++++++++ generic/tclBasic.c | 31 +++++++++++++++---------------- generic/tclDictObj.c | 16 +++++----------- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index 16317ad..e2803c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-07-18 Miguel Sofer + + * generic/tclDictObj.c (DictWithCmd, DictUpdateCmd): fix + refcounting bugs that caused crashes [Bug 2017857]. + + * generic/tclBasic.c (TclNREvalObjEx): streamline the management + of the command frame (opt). + 2008-07-17 Donal K. Fellows * generic/tclDictObj.c (DictWithCmd, FinalizeDictWith): Split the diff --git a/generic/tclBasic.c b/generic/tclBasic.c index d2a1054..902b666 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -16,7 +16,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclBasic.c,v 1.312 2008/07/15 13:50:15 dkf Exp $ + * RCS: @(#) $Id: tclBasic.c,v 1.313 2008/07/18 04:23:54 msofer Exp $ */ #include "tclInt.h" @@ -5354,23 +5354,25 @@ TclNREvalObjEx( * dynamic execution we ignore the invoker, even if known. */ - int line, i; + int line, i, nline; char *w; Tcl_Obj **elements, *copyPtr = TclListObjCopy(NULL, objPtr); - CmdFrame *eoFramePtr = (CmdFrame *) - TclStackAlloc(interp, sizeof(CmdFrame)); + CmdFrame *eoFramePtr; + + Tcl_ListObjGetElements(NULL, copyPtr, + &nline, &elements); + eoFramePtr = (CmdFrame *) TclStackAlloc(interp, + sizeof(CmdFrame) + nline * sizeof(int)); + eoFramePtr->nline = nline; + eoFramePtr->line = (int *) (eoFramePtr + 1); + eoFramePtr->type = TCL_LOCATION_EVAL_LIST; eoFramePtr->level = (iPtr->cmdFramePtr == NULL? 1 : iPtr->cmdFramePtr->level + 1); eoFramePtr->framePtr = iPtr->framePtr; eoFramePtr->nextPtr = iPtr->cmdFramePtr; - Tcl_ListObjGetElements(NULL, copyPtr, - &(eoFramePtr->nline), &elements); - eoFramePtr->line = (int *) - ckalloc(eoFramePtr->nline * sizeof(int)); - eoFramePtr->cmd.listPtr = objPtr; eoFramePtr->data.eval.path = NULL; @@ -5574,17 +5576,14 @@ TEOEx_ListCallback( Tcl_Obj *copyPtr = data[2]; /* - * Remove the cmdFrame if it was added. + * Remove the cmdFrame */ - Tcl_DecrRefCount(copyPtr); - iPtr->cmdFramePtr = iPtr->cmdFramePtr->nextPtr; - ckfree((char *) eoFramePtr->line); - eoFramePtr->line = NULL; - eoFramePtr->nline = 0; + iPtr->cmdFramePtr = eoFramePtr->nextPtr; TclStackFree(interp, eoFramePtr); - + Tcl_DecrRefCount(copyPtr); TclDecrRefCount(objPtr); + return result; } diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index 9764c30..9cf2739 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclDictObj.c,v 1.61 2008/07/17 21:57:15 dkf Exp $ + * RCS: @(#) $Id: tclDictObj.c,v 1.62 2008/07/18 04:23:55 msofer Exp $ */ #include "tclInt.h" @@ -2931,13 +2931,10 @@ DictUpdateCmd( objPtr = Tcl_NewListObj(objc-3, objv+2); Tcl_IncrRefCount(objPtr); + Tcl_IncrRefCount(objv[1]); TclNR_AddCallback(interp, FinalizeDictUpdate, objv[1], objPtr, NULL,NULL); -#if 0 - /* This crashes when doing nested [dict update]s. */ + return TclNREvalObjEx(interp, objv[objc-1], 0, iPtr->cmdFramePtr, objc-1); -#else - return TclNR_EvalObj(interp, objv[objc-1], 0); -#endif } static int @@ -3111,16 +3108,13 @@ DictWithCmd( pathPtr = NULL; if (objc > 3) { pathPtr = Tcl_NewListObj(objc-3, objv+2); + Tcl_IncrRefCount(pathPtr); } Tcl_IncrRefCount(objv[1]); TclNR_AddCallback(interp, FinalizeDictWith, objv[1], keysPtr, pathPtr, NULL); -#if 0 - /* This crashes when doing nested [dict with]s. */ + return TclNREvalObjEx(interp, objv[objc-1], 0, iPtr->cmdFramePtr, objc-1); -#else - return TclNR_EvalObj(interp, objv[objc-1], 0); -#endif } static int -- cgit v0.12