diff options
-rw-r--r-- | ChangeLog | 31 | ||||
-rw-r--r-- | generic/tclFCmd.c | 21 |
2 files changed, 31 insertions, 21 deletions
@@ -1,9 +1,16 @@ +2011-04-16 Donal K. Fellows <dkf@users.sf.net> + + * generic/tclFCmd.c (TclFileAttrsCmd): Tidied up the memory management + a bit to try to ensure that the dynamic and static cases don't get + confused while still promoting caching where possible. Added a panic + to trap problems in the case where an extension is misusing the API. + 2011-04-13 Don Porter <dgp@users.sourceforge.net> - * generic/tclUtil.c: Rewrite of Tcl_Concat*() routines to - prevent segfaults on buffer overflow. Build them out of existing - primitives already coded to handle overflow properly. Uses the - new TclTrim*() routines. [Bug 3285375] + * generic/tclUtil.c: [Bug 3285375]: Rewrite of Tcl_Concat*() + routines to prevent segfaults on buffer overflow. Build them out of + existing primitives already coded to handle overflow properly. Uses + the new TclTrim*() routines. * generic/tclCmdMZ.c: New internal utility routines TclTrimLeft() * generic/tclInt.h: and TclTrimRight(). Refactor the @@ -11,14 +18,14 @@ 2011-04-13 Miguel Sofer <msofer@users.sf.net> - * generic/tclVar.c: fix for [Bug 2662380], crash caused by - appending to a variable with a write trace that unsets it. + * generic/tclVar.c: [Bug 2662380]: Fix crash caused by appending to a + variable with a write trace that unsets it. 2011-04-12 Don Porter <dgp@users.sourceforge.net> - * generic/tclStringObj.c: Repair corruption in [string reverse] - * tests/string.test: when string rep invalidation failed to also - reset the bytes allocated for string rep to zero [Bug 3285472]. + * generic/tclStringObj.c: [Bug 3285472]: Repair corruption in + * tests/string.test: [string reverse] when string rep invalidation + failed to also reset the bytes allocated for string rep to zero. 2011-04-12 Venkat Iyer <venkat@comit.com> @@ -26,7 +33,7 @@ 2011-04-06 Miguel Sofer <msofer@users.sf.net> - * generic/tclExecute.c (TclCompEvalObj): earlier return if Tip280 + * generic/tclExecute.c (TclCompEvalObj): Earlier return if Tip280 gymnastics not needed. 2011-04-05 Venkat Iyer <venkat@comit.com> @@ -47,8 +54,8 @@ 2011-04-02 Kevin B. Kenny <kennykb@acm.org> - * generic/tclStrToD.c (QuickConversion): Replaced another couple - of 'double' declarations with 'volatile double' to work around + * generic/tclStrToD.c (QuickConversion): Replaced another couple of + 'double' declarations with 'volatile double' to work around misrounding issues in mingw-gcc 3.4.5. 2011-03-24 Donal K. Fellows <dkf@users.sf.net> diff --git a/generic/tclFCmd.c b/generic/tclFCmd.c index 53f955f..5850846 100644 --- a/generic/tclFCmd.c +++ b/generic/tclFCmd.c @@ -950,7 +950,7 @@ TclFileAttrsCmd( int result; CONST char ** attributeStrings; Tcl_Obj* objStrings = NULL; - int numObjStrings = -1; + int numObjStrings = -1, didAlloc = 0; Tcl_Obj *filePtr; if (objc < 3) { @@ -983,9 +983,8 @@ TclFileAttrsCmd( Tcl_AppendResult(interp, "could not read \"", TclGetString(filePtr), "\": ", Tcl_PosixError(interp), NULL); - return TCL_ERROR; } - goto end; + return TCL_ERROR; } /* @@ -1003,12 +1002,16 @@ TclFileAttrsCmd( } attributeStrings = (CONST char **) TclStackAlloc(interp, (1+numObjStrings) * sizeof(char*)); + didAlloc = 1; for (index = 0; index < numObjStrings; index++) { Tcl_ListObjIndex(interp, objStrings, index, &objPtr); attributeStrings[index] = TclGetString(objPtr); } attributeStrings[index] = NULL; + } else if (objStrings != NULL) { + Tcl_Panic("must not update objPtrRef's variable and return non-NULL"); } + if (objc == 0) { /* * Get all attributes. @@ -1069,7 +1072,7 @@ TclFileAttrsCmd( "option", 0, &index) != TCL_OK) { goto end; } - if (numObjStrings != -1) { + if (didAlloc) { TclFreeIntRep(objv[0]); } if (Tcl_FSFileAttrsGet(interp, index, filePtr, @@ -1096,7 +1099,7 @@ TclFileAttrsCmd( "option", 0, &index) != TCL_OK) { goto end; } - if (numObjStrings != -1) { + if (didAlloc) { TclFreeIntRep(objv[i]); } if (i + 1 == objc) { @@ -1113,20 +1116,20 @@ TclFileAttrsCmd( result = TCL_OK; end: - if (numObjStrings != -1) { + if (didAlloc) { /* * Free up the array we allocated. */ TclStackFree(interp, (void *)attributeStrings); + } + if (objStrings != NULL) { /* * We don't need this object that was passed to us any more. */ - if (objStrings != NULL) { - Tcl_DecrRefCount(objStrings); - } + Tcl_DecrRefCount(objStrings); } return result; } |