From 2a0cc806f686d7a496ed397d64bad36b2eaba2c5 Mon Sep 17 00:00:00 2001 From: vincentdarley Date: Tue, 9 Dec 2003 13:43:35 +0000 Subject: fix to memory leaks and reading of freed memory FossilOrigin-Name: 44167e843701469c7aad866fac58a5fbb929998f --- ChangeLog | 7 +++++++ generic/tkTextTag.c | 16 +++++++++++++++- win/tkWinWm.c | 38 ++++++++++++++++++++------------------ 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5361f53..2913169 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2003-12-09 Vince Darley + + * win/tkWinWm.c: fix to memory leak on certain error cases. + + * generic/tkTextTag.c: fix reading of freed tag memory, by removing + all references to freed tags. + 2003-12-08 Jeff Hobbs * doc/entry.n: clean up usage of 'edition' as a verb. diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c index 3762de9..4fb536a 100644 --- a/generic/tkTextTag.c +++ b/generic/tkTextTag.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: tkTextTag.c,v 1.15 2003/12/05 17:19:06 vincentdarley Exp $ + * RCS: @(#) $Id: tkTextTag.c,v 1.16 2003/12/09 13:43:35 vincentdarley Exp $ */ #include "default.h" @@ -990,6 +990,8 @@ TkTextFreeTag(textPtr, tagPtr) TkText *textPtr; /* Info about overall widget. */ register TkTextTag *tagPtr; /* Tag being deleted. */ { + int i; + /* Let Tk do most of the hard work for us */ Tk_FreeConfigOptions((char *) tagPtr, tagPtr->optionTable, textPtr->tkwin); @@ -997,6 +999,18 @@ TkTextFreeTag(textPtr, tagPtr) if (tagPtr->tabArrayPtr != NULL) { ckfree((char *) tagPtr->tabArrayPtr); } + /* Make sure this tag isn't referenced from the 'current' tag array */ + for (i = 0; i < textPtr->numCurTags; i++) { + if (textPtr->curTagArrayPtr[i] == tagPtr) { + for (; i < textPtr->numCurTags-1; i++) { + textPtr->curTagArrayPtr[i] = textPtr->curTagArrayPtr[i+1]; + } + textPtr->curTagArrayPtr[textPtr->numCurTags] = NULL; + textPtr->numCurTags--; + break; + } + } + /* Finally free the tag's memory */ ckfree((char *) tagPtr); } diff --git a/win/tkWinWm.c b/win/tkWinWm.c index edd91a2..57d823b 100644 --- a/win/tkWinWm.c +++ b/win/tkWinWm.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinWm.c,v 1.55 2003/03/12 00:25:42 mdejong Exp $ + * RCS: @(#) $Id: tkWinWm.c,v 1.56 2003/12/09 13:43:35 vincentdarley Exp $ */ #include "tkWinInt.h" @@ -1466,44 +1466,36 @@ ReadIconOrCursorFromFile(Tcl_Interp* interp, Tcl_Obj* fileName, BOOL isIcon) { ckfree( (char*)lpIR ); return NULL; } + /* NULL-out everything to make memory management easier */ + for( i = 0; i < lpIR->nNumImages; i++ ) { + lpIR->IconImages[i].lpBits = NULL; + } /* Loop through and read in each image */ for( i = 0; i < lpIR->nNumImages; i++ ) { /* Allocate memory for the resource */ lpIR->IconImages[i].lpBits = (LPBYTE) ckalloc(lpIDE[i].dwBytesInRes); if (lpIR->IconImages[i].lpBits == NULL) { Tcl_AppendResult(interp,"Error allocating memory",(char*)NULL); - Tcl_Close(NULL, channel); - ckfree( (char*)lpIR ); - ckfree( (char*)lpIDE ); - return NULL; + goto readError; } lpIR->IconImages[i].dwNumBytes = lpIDE[i].dwBytesInRes; /* Seek to beginning of this image */ if (Tcl_Seek(channel, lpIDE[i].dwImageOffset, FILE_BEGIN) == -1) { Tcl_AppendResult(interp,"Error seeking in file",(char*)NULL); - Tcl_Close(NULL, channel); - ckfree( (char*)lpIR ); - ckfree( (char*)lpIDE ); - return NULL; + goto readError; } /* Read it in */ dwBytesRead = Tcl_Read( channel, lpIR->IconImages[i].lpBits, lpIDE[i].dwBytesInRes); if (dwBytesRead != lpIDE[i].dwBytesInRes) { Tcl_AppendResult(interp,"Error reading file",(char*)NULL); - Tcl_Close(NULL, channel); - ckfree( (char*)lpIDE ); - ckfree( (char*)lpIR ); - return NULL; + goto readError; } /* Set the internal pointers appropriately */ if (!AdjustIconImagePointers( &(lpIR->IconImages[i]))) { Tcl_AppendResult(interp,"Error converting to internal format", (char*)NULL); - Tcl_Close(NULL, channel); - ckfree( (char*)lpIDE ); - ckfree( (char*)lpIR ); - return NULL; + goto readError; } lpIR->IconImages[i].hIcon = MakeIconOrCursorFromResource(&(lpIR->IconImages[i]), isIcon); @@ -1513,10 +1505,20 @@ ReadIconOrCursorFromFile(Tcl_Interp* interp, Tcl_Obj* fileName, BOOL isIcon) { Tcl_Close(NULL, channel); if (lpIR == NULL){ Tcl_AppendResult(interp,"Reading of ", Tcl_GetString(fileName), - " failed!",(char*)NULL); + " failed!",(char*)NULL); return NULL; } return lpIR; + readError: + Tcl_Close(NULL, channel); + for( i = 0; i < lpIR->nNumImages; i++ ) { + if (lpIR->IconImages[i].lpBits != NULL) { + ckfree((char*)lpIR->IconImages[i].lpBits); + } + } + ckfree((char*)lpIDE ); + ckfree((char*)lpIR ); + return NULL; } /* -- cgit v0.12