summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--generic/tkTextTag.c16
-rw-r--r--win/tkWinWm.c38
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 <vincentdarley@users.sourceforge.net>
+
+ * 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 <jeffh@ActiveState.com>
* 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;
}
/*