summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2008-07-18 04:23:35 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2008-07-18 04:23:35 (GMT)
commit306e6900a04b226e12b76ba8d7c4366b0b336c9a (patch)
tree59fcb5999c458580b7d132e00c5906ceb08b3037 /generic
parent222e9f575e6b44d31e1bdc5c84430c514465e32d (diff)
downloadtcl-306e6900a04b226e12b76ba8d7c4366b0b336c9a.zip
tcl-306e6900a04b226e12b76ba8d7c4366b0b336c9a.tar.gz
tcl-306e6900a04b226e12b76ba8d7c4366b0b336c9a.tar.bz2
* 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).
Diffstat (limited to 'generic')
-rw-r--r--generic/tclBasic.c31
-rw-r--r--generic/tclDictObj.c16
2 files changed, 20 insertions, 27 deletions
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