changeset 1332:c0f29ce1a879

Fixed too broad of an if() in dw_window_destroy on OS/2 and Windows... This code error caused memory to be leaked when destroying windows under some circumstances. Specifically unpacked or orphaned windows. Also fixed crashes or memory corruption when destroying unpacked windows on Windows...This is due to the object window not having a Box allocated.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Thu, 10 Nov 2011 19:10:00 +0000
parents 4c12170f003f
children c993df7ffdd8
files os2/dw.c win/dw.c
diffstat 2 files changed, 75 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/os2/dw.c	Thu Nov 10 18:06:32 2011 +0000
+++ b/os2/dw.c	Thu Nov 10 19:10:00 2011 +0000
@@ -4068,35 +4068,42 @@
    if((menu = WinWindowFromID(handle, FID_MENU)) != NULLHANDLE)
       _free_menu_data(menu);
 
-   if(parent != desktop && thisbox && thisbox->count)
-   {
-      int z, index = -1;
-      Item *tmpitem, *thisitem = thisbox->items;
-
-      for(z=0;z<thisbox->count;z++)
-      {
-         if(thisitem[z].hwnd == handle)
-            index = z;
-      }
-
-      if(index == -1)
-         return 0;
-
-      tmpitem = malloc(sizeof(Item)*(thisbox->count-1));
-
-      /* Copy all but the current entry to the new list */
-      for(z=0;z<index;z++)
-      {
-         tmpitem[z] = thisitem[z];
-      }
-      for(z=index+1;z<thisbox->count;z++)
-      {
-         tmpitem[z-1] = thisitem[z];
-      }
-
-      thisbox->items = tmpitem;
-      free(thisitem);
-      thisbox->count--;
+   /* If it is a desktop window let WM_DESTROY handle it */
+   if(parent != desktop)
+   {
+      /* If the parent box has items... 
+       * try to remove it from the layout 
+       */
+     if(thisbox && thisbox->count)
+      {
+         int z, index = -1;
+         Item *tmpitem, *thisitem = thisbox->items;
+
+         for(z=0;z<thisbox->count;z++)
+         {
+            if(thisitem[z].hwnd == handle)
+               index = z;
+         }
+
+         if(index == -1)
+            return 0;
+
+         tmpitem = malloc(sizeof(Item)*(thisbox->count-1));
+
+         /* Copy all but the current entry to the new list */
+         for(z=0;z<index;z++)
+         {
+            tmpitem[z] = thisitem[z];
+         }
+         for(z=index+1;z<thisbox->count;z++)
+         {
+            tmpitem[z-1] = thisitem[z];
+         }
+
+         thisbox->items = tmpitem;
+         free(thisitem);
+         thisbox->count--;
+      }
       _free_window_memory(frame ? frame : handle);
    }
    return WinDestroyWindow(frame ? frame : handle);
--- a/win/dw.c	Thu Nov 10 18:06:32 2011 +0000
+++ b/win/dw.c	Thu Nov 10 19:10:00 2011 +0000
@@ -3734,6 +3734,9 @@
       dw_messagebox("Dynamic Windows", DW_MB_OK|DW_MB_ERROR, "Could not initialize the object window. error code %d", GetLastError());
       exit(1);
    }
+   
+   /* Create empty box data */
+   SetWindowLongPtr(DW_HWND_OBJECT, GWLP_USERDATA, (LONG_PTR)calloc(sizeof(Box), 1));
 
    /* We need the version to check capability like up-down controls */
    dwVersion = GetVersion();
@@ -4032,35 +4035,42 @@
    if(menu)
       _free_menu_data(menu);
 
-   if(parent != HWND_DESKTOP && thisbox && thisbox->count)
-   {
-      int z, index = -1;
-      Item *tmpitem, *thisitem = thisbox->items;
-
-      for(z=0;z<thisbox->count;z++)
-      {
-         if(thisitem[z].hwnd == handle)
-            index = z;
-      }
-
-      if(index == -1)
-         return 0;
-
-      tmpitem = malloc(sizeof(Item)*(thisbox->count-1));
-
-      /* Copy all but the current entry to the new list */
-      for(z=0;z<index;z++)
-      {
-         tmpitem[z] = thisitem[z];
-      }
-      for(z=index+1;z<thisbox->count;z++)
-      {
-         tmpitem[z-1] = thisitem[z];
-      }
-
-      thisbox->items = tmpitem;
-      free(thisitem);
-      thisbox->count--;
+   /* If it is a desktop window let WM_DESTROY handle it */
+   if(parent != HWND_DESKTOP)
+   {
+      /* If the parent box has items... 
+       * try to remove it from the layout 
+       */
+      if(thisbox && thisbox->count)
+      {
+         int z, index = -1;
+         Item *tmpitem, *thisitem = thisbox->items;
+
+         for(z=0;z<thisbox->count;z++)
+         {
+            if(thisitem[z].hwnd == handle)
+               index = z;
+         }
+
+         if(index == -1)
+            return 0;
+
+         tmpitem = malloc(sizeof(Item)*(thisbox->count-1));
+
+         /* Copy all but the current entry to the new list */
+         for(z=0;z<index;z++)
+         {
+            tmpitem[z] = thisitem[z];
+         }
+         for(z=index+1;z<thisbox->count;z++)
+         {
+            tmpitem[z-1] = thisitem[z];
+         }
+
+         thisbox->items = tmpitem;
+         free(thisitem);
+         thisbox->count--;
+      }
       _free_window_memory(handle, 0);
       EnumChildWindows(handle, _free_window_memory, 0);
    }