From 3a8ec6512bee89ac495891665fc40bf1d893a389 Mon Sep 17 00:00:00 2001
From: Tomas Janousek <tomi@nomi.cz>
Date: Tue, 5 Feb 2008 18:31:15 +0100
Subject: Fix a freed memory access in ~BScreen.

mit->second->parent() == 0 didn't do what it was supposed to. m_parent being
zero does not imply that no pointer points to it.

Signed-off-by: Tomas Janousek <tomi@nomi.cz>
---
 src/Screen.cc | 41 ++++++++++++++++++++++++++---------------
 1 file changed, 26 insertions(+), 15 deletions(-)

diff --git a/src/Screen.cc b/src/Screen.cc
index 400e7e2..16f39b1 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -559,21 +559,32 @@ BScreen::~BScreen() {
     // we need to destroy it before we destroy workspaces
     m_workspacemenu.reset(0);
 
-    ExtraMenus::iterator mit = m_extramenus.begin();
-    ExtraMenus::iterator mit_end = m_extramenus.end();
-    for (; mit != mit_end; ++mit) {
-        // we set them to NOT internal so that they will be deleted when the
-        // menu is cleaned up. We can't delete them here because they are
-        // still in the menu
-        // (They need to be internal for most of the time so that if we
-        // rebuild the menu, then they won't be removed.
-        if (mit->second->parent() == 0) {
-            // not attached to our windowmenu
-            // so we clean it up
-            delete mit->second;
-        } else {
-            // let the parent clean it up
-            mit->second->setInternalMenu(false);
+    if (m_extramenus.size()) {
+        // check whether extramenus are included in windowmenu
+        // if not, we clean them ourselves
+        bool extramenus_in_windowmenu = false;
+        for (size_t i = 0, n = m_windowmenu->numberOfItems(); i < n; i++)
+            if (m_windowmenu->find(i)->submenu() == m_extramenus.begin()->second) {
+                extramenus_in_windowmenu = true;
+                break;
+            }
+
+        ExtraMenus::iterator mit = m_extramenus.begin();
+        ExtraMenus::iterator mit_end = m_extramenus.end();
+        for (; mit != mit_end; ++mit) {
+            // we set them to NOT internal so that they will be deleted when the
+            // menu is cleaned up. We can't delete them here because they are
+            // still in the menu
+            // (They need to be internal for most of the time so that if we
+            // rebuild the menu, then they won't be removed.
+            if (! extramenus_in_windowmenu) {
+                // not attached to our windowmenu
+                // so we clean it up
+                delete mit->second;
+            } else {
+                // let the parent clean it up
+                mit->second->setInternalMenu(false);
+            }
         }
     }
 
-- 
cgit v0.11.2