(svn r12942) -Fix [FS#1979]: closing some windows caused recursion in the Window deletion causing the reading invalid/freed data which could cause crashes.
authorrubidium
Sun, 04 May 2008 21:36:37 +0000
changeset 9083 e18c37b3a45e
parent 9082 8a28686aeff2
child 9084 55b2d2cb8b90
(svn r12942) -Fix [FS#1979]: closing some windows caused recursion in the Window deletion causing the reading invalid/freed data which could cause crashes.
src/window.cpp
--- a/src/window.cpp	Sun May 04 10:05:50 2008 +0000
+++ b/src/window.cpp	Sun May 04 21:36:37 2008 +0000
@@ -416,16 +416,28 @@
 {
 	if (w == NULL) return;
 
-	/* Delete any children a window might have in a head-recursive manner */
-	Window *v = FindChildWindow(w);
-	if (v != NULL) DeleteWindow(v);
-
 	if (_thd.place_mode != VHM_NONE &&
 			_thd.window_class == w->window_class &&
 			_thd.window_number == w->window_number) {
 		ResetObjectToPlace();
 	}
 
+	/* Prevent Mouseover() from resetting mouse-over coordinates on a non-existing window */
+	if (_mouseover_last_w == w) _mouseover_last_w = NULL;
+
+	/* Find the window in the z-array, and effectively remove it
+	 * by moving all windows after it one to the left. This must be
+	 * done before removing the child so we cannot cause recursion
+	 * between the deletion of the parent and the child. */
+	Window **wz = FindWindowZPosition(w);
+	if (wz == NULL) return;
+	memmove(wz, wz + 1, (byte*)_last_z_window - (byte*)wz);
+	_last_z_window--;
+
+	/* Delete any children a window might have in a head-recursive manner */
+	Window *v = FindChildWindow(w);
+	if (v != NULL) DeleteWindow(v);
+
 	CallWindowEventNP(w, WE_DESTROY);
 	if (w->viewport != NULL) DeleteWindowViewport(w);
 
@@ -435,16 +447,6 @@
 	w->widget_count = 0;
 	w->parent = NULL;
 
-	/* Prevent Mouseover() from resetting mouse-over coordinates on a non-existing window */
-	if (_mouseover_last_w == w) _mouseover_last_w = NULL;
-
-	/* Find the window in the z-array, and effectively remove it
-	 * by moving all windows after it one to the left */
-	Window **wz = FindWindowZPosition(w);
-	if (wz == NULL) return;
-	memmove(wz, wz + 1, (byte*)_last_z_window - (byte*)wz);
-	_last_z_window--;
-
 	delete w;
 }