Ticket UUID: | 756791 | |||
Title: | [patch]Tcl incorrectly uses ckfree() when freeProc == free() | |||
Type: | Bug | Version: | None | |
Submitter: | landonf | Created on: | 2003-06-18 19:17:52 | |
Subsystem: | 41. Memory Allocation | Assigned To: | aku | |
Priority: | 9 Immediate | Severity: | Minor | |
Status: | Closed | Last Modified: | 2023-10-11 12:58:56 | |
Resolution: | Fixed | Closed By: | chrstphrchvz | |
Closed on: | 2023-10-11 12:58:56 | |||
Description: |
Tcl incorrectly uses ckfree() on pointers supplied with a freeProc of free() Fix attached, explanation below. Prototype for Tcl_SetResult: Tcl_SetResult(interp, string, freeProc) Tcl_SetResult allows one to specify any custom free function that matches the Tcl_FreeProc prototype, or one of TCL_VOLATILE, TCL_STATIC, or TCL_DYNAMIC. If one specifies TCL_DYNAMIC, it is assumed that the string pointer is owned by the Tcl allocator, and ckfree() is used to free the allocated memory. However, if free() is specified, ckfree() is ALSO used to free the allocated memory. This is incorrect, as ckfree() can not be used on memory allocated by malloc. if ((iPtr->freeProc == TCL_DYNAMIC) || (iPtr->freeProc == (Tcl_FreeProc *) free)) { ckfree(iPtr->result); } When looking through the code, I found that this error was propagated in numerous other locations. Attached is a fix. In all cases, the above if conditional has been changed to remove the test for iPtr->freeProc == (Tcl_FreeProc *) free. In example: if (iPtr->freeProc == TCL_DYNAMIC) { ... } Detailed problem information follows: Tcl_DStringGetResult(interp, dsPtr): If iPtr->freeProc is either TCL_DYNAMIC or free, dsPtr- >string is set to iPtr->result. Later, when Tcl_DStringFree() is called, ckfree() will be called on dsPtr->string. Tcl_Release(clientData): If Tcl_EventuallyFree has been called on the pointer passed to Tcl_Release, refPtr->mustFree will be set, and refPtr- >freeProc will be set to the free function given to Tcl_EventuallyFree. If refPtr->freeProc is either TCL_DYNAMIC or free, ckfree(clientData) will be called. Tcl_EventuallyFree(clientData, freeProc): If there is no reference in the refArray for the clientData pointer, clientData is immediately freed using the supplied freeProc, unless freeProc == free() or TCL_DYNAMIC, and then, ckfree(clientData) is called. Tcl_DiscardResult(statePtr) If Tcl_SetResult was called with a freeProc of free, Tcl_SaveResult(interp, statePtr) will set statePtr->freeProc to iPtr->freeProc, and statePtr->result to iPtr->result. When Tcl_DiscardResult is called on this statePtr, if statePtr- >freeProc is TCL_DYNAMIC or free(), ckfree() is called on statPtr->result. Tcl_SetResult(interp, string, freeProc) If the old interp->freeProc is TCL_DYNAMIC or free(), ckfree is called. Tcl_SetObjResult(interp, objPtr) If interp->result && interp->freeProc are not NULL, and interp->freeProc is either TCL_DYNAMIC or free(), ckfree() is called. Tcl_GetObjResult(interp): If interp->result && interp->freeProc are not NULL, and interp->freeProc is either TCL_DYNAMIC or free(), ckfree() is called. Tcl_FreeResult(interp): If interp->freeProc is not NULL, and interp->freeProc is either TCL_DYNAMIC or free(), ckfree() is called. | |||
User Comments: |
chrstphrchvz added on 2023-10-11 12:58:56:
There is still an instance of this issue in Tk: https://core.tcl-lang.org/tk/info/9675dd5916ba hobbs added on 2003-07-17 04:25:32: Logged In: YES user_id=72656 patch had one bug. commited fixed for 8.5a and 8.4.4. landonf added on 2003-06-19 02:17:52: File Added - 53476: tcl-diff-ckfree.diff |
Attachments:
- tcl-diff-ckfree.diff [download] added by landonf on 2003-06-19 02:17:52. [details]