diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | generic/tclExecute.c | 40 |
2 files changed, 23 insertions, 22 deletions
@@ -1,5 +1,10 @@ 2002-08-01 Miguel Sofer <msofer@users.sourceforge.net> + * generic/tclExecute.c: bugfix (reading freed memory). Testsuite + passed on linux/i386, compile-13.1 hung on linux/alpha. + +2002-08-01 Miguel Sofer <msofer@users.sourceforge.net> + * generic/tclExecute.c: added a reference count for the complete execution stack, instead of Tcl_Preserve/Tcl_Release. diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 24613aa..d90a362 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclExecute.c,v 1.87 2002/08/01 20:02:11 msofer Exp $ + * RCS: @(#) $Id: tclExecute.c,v 1.88 2002/08/01 22:17:07 msofer Exp $ */ #include "tclInt.h" @@ -636,7 +636,7 @@ GrowEvaluationStack(eePtr) int newElems = 2*currElems; int currBytes = currElems * sizeof(Tcl_Obj *); int newBytes = 2*currBytes; - Tcl_Obj **newStackPtr; + Tcl_Obj **newStackPtr = (Tcl_Obj **) ckalloc((unsigned) newBytes); Tcl_Obj **oldStackPtr = eePtr->stackPtr; /* @@ -647,33 +647,29 @@ GrowEvaluationStack(eePtr) char *refCount = (char *) oldStackPtr[-1]; /* - * Realloc the stack: copy existing stack items to the new stack - * space, free the old storage if appropriate. + * Copy the existing stack items to the new stack space, free the old + * storage if appropriate, and record the refCount of the new stack + * held by the environment. */ - newStackPtr = (Tcl_Obj **) ckrealloc((VOID *) (oldStackPtr-1), - (unsigned) newBytes); newStackPtr++; - eePtr->stackPtr = newStackPtr; - eePtr->stackEnd = (newElems - 2); /* index of last usable item */ + memcpy((VOID *) newStackPtr, (VOID *) oldStackPtr, + (size_t) currBytes); - if (newStackPtr != oldStackPtr) { + if (refCount == (char *) 1) { + ckfree((VOID *) (oldStackPtr-1)); + } else { /* - * The stack was moved; update the refCounts. + * Remove the reference corresponding to the + * environment pointer. */ - - newStackPtr[-1] = (Tcl_Obj *) ((char *) 1); - if (refCount == (char *) 1) { - ckfree((VOID *) (oldStackPtr-1)); - } else { - /* - * Remove the reference corresponding to the - * environment pointer. - */ - - oldStackPtr[-1] = (Tcl_Obj *) (refCount-1); - } + + oldStackPtr[-1] = (Tcl_Obj *) (refCount-1); } + + eePtr->stackPtr = newStackPtr; + eePtr->stackEnd = (newElems - 2); /* index of last usable item */ + newStackPtr[-1] = (Tcl_Obj *) ((char *) 1); } /* |