From 9e85e930da614ebef4e714ec890644d6e7241871 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 28 Aug 2003 17:15:10 +0000 Subject: [PATCH] fix for using freed memory to exec stuff --- openbox/menu.c | 73 +++++++++++++++++++-------------- openbox/menu.h | 5 +-- openbox/menuframe.c | 14 +++++-- plugins/menu/client_list_menu.c | 4 +- 4 files changed, 57 insertions(+), 39 deletions(-) diff --git a/openbox/menu.c b/openbox/menu.c index d742b972..84c5ded5 100644 --- a/openbox/menu.c +++ b/openbox/menu.c @@ -12,7 +12,9 @@ #include "misc.h" #include "parser/parse.h" -GHashTable *menu_hash = NULL; +static GHashTable *menu_hash = NULL; + +ObParseInst *menu_parse_inst; typedef struct _ObMenuParseState ObMenuParseState; @@ -129,69 +131,80 @@ void menu_startup(ObParseInst *i) { menu_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, (GDestroyNotify)menu_destroy_hash_value); + menu_parse_inst = parse_startup(); } void menu_shutdown() { + parse_shutdown(menu_parse_inst); + menu_parse_inst = NULL; + menu_frame_hide_all(); g_hash_table_destroy(menu_hash); menu_hash = NULL; } +gboolean menu_open(gchar *file, xmlDocPtr *doc, xmlNodePtr *node) +{ + gboolean loaded = TRUE; + gchar *p; + + p = g_build_filename(g_get_home_dir(), ".openbox", file, NULL); + if (!parse_load(p, "openbox_menu", doc, node)) { + g_free(p); + p = g_build_filename(RCDIR, file, NULL); + if (!parse_load(p, "openbox_menu", doc, node)) { + g_free(p); + p = g_strdup(file); + if (!parse_load(p, "openbox_menu", doc, node)) { + g_warning("Failed to load menu from '%s'", file); + loaded = FALSE; + } + } + } + g_free(p); + return loaded; +} + void menu_parse() { - ObParseInst *i; ObMenuParseState parse_state; xmlDocPtr doc; xmlNodePtr node; - gchar *p; gboolean loaded = FALSE; + GSList *it; + + for (it = config_menu_files; it; it = g_slist_next(it)) { + if (menu_open(it->data, &doc, &node)) + loaded = TRUE; - i = parse_startup(); - - if (config_menu_path) - if (!(loaded = - parse_load(config_menu_path, "openbox_menu", &doc, &node))) - g_warning("Failed to load menu from '%s'", config_menu_path); - if (!loaded) { - p = g_build_filename(g_get_home_dir(), ".openbox", "menu", NULL); - if (!(loaded = - parse_load(p, "openbox_menu", &doc, &node))) - g_warning("Failed to load menu from '%s'", p); - g_free(p); - } - if (!loaded) { - p = g_build_filename(RCDIR, "menu", NULL); - if (!(loaded = - parse_load(p, "openbox_menu", &doc, &node))) - g_warning("Failed to load menu from '%s'", p); - g_free(p); } + if (!loaded) + loaded = menu_open("menu", &doc, &node); if (loaded) { parse_state.menus = NULL; - parse_register(i, "menu", parse_menu, &parse_state); - parse_register(i, "item", parse_menu_item, &parse_state); - parse_register(i, "separator", parse_menu_separator, &parse_state); - parse_tree(i, doc, node->xmlChildrenNode); + parse_register(menu_parse_inst, "menu", parse_menu, &parse_state); + parse_register(menu_parse_inst, "item", parse_menu_item, &parse_state); + parse_register(menu_parse_inst, "separator", + parse_menu_separator, &parse_state); + parse_tree(menu_parse_inst, doc, node->xmlChildrenNode); } - - parse_shutdown(i); } gboolean menu_new(gchar *name, gchar *title, gpointer data) { ObMenu *self; - if (g_hash_table_lookup(menu_hash, name)) return FALSE; + /*if (g_hash_table_lookup(menu_hash, name)) return FALSE;*/ self = g_new0(ObMenu, 1); self->name = g_strdup(name); self->title = g_strdup(title); self->data = data; - g_hash_table_insert(menu_hash, self->name, self); + g_hash_table_replace(menu_hash, self->name, self); return TRUE; } diff --git a/openbox/menu.h b/openbox/menu.h index c6058635..74519343 100644 --- a/openbox/menu.h +++ b/openbox/menu.h @@ -20,11 +20,10 @@ typedef struct _ObSubmenuMenuEntry ObSubmenuMenuEntry; typedef struct _ObSeparatorMenuEntry ObSeparatorMenuEntry; typedef void (*ObMenuUpdateFunc)(struct _ObMenuFrame *frame, gpointer data); -typedef void (*ObMenuExecuteFunc)(struct _ObMenuEntryFrame *frame, - gpointer data); +typedef void (*ObMenuExecuteFunc)(struct _ObMenuEntry *entry, gpointer data); typedef void (*ObMenuDestroyFunc)(struct _ObMenu *menu, gpointer data); -extern GList *menu_visible; +extern ObParseInst *menu_parse_inst; struct _ObMenu { diff --git a/openbox/menuframe.c b/openbox/menuframe.c index 053034b3..725b1a18 100644 --- a/openbox/menuframe.c +++ b/openbox/menuframe.c @@ -572,16 +572,22 @@ void menu_entry_frame_show_submenu(ObMenuEntryFrame *self) void menu_entry_frame_execute(ObMenuEntryFrame *self, gboolean hide) { if (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL) { + /* grab all this shizzle, cuz when the menu gets hidden, 'self' + gets freed */ + ObMenuEntry *entry = self->entry; + ObMenuExecuteFunc func = self->frame->menu->execute_func; + gpointer data = self->frame->menu->data; + GSList *acts = self->entry->data.normal.actions; + /* release grabs before executing the shit */ menu_frame_hide_all(); - if (self->frame->menu->execute_func) - self->frame->menu->execute_func(self, self->frame->menu->data); + if (func) + func(entry, data); else { GSList *it; - for (it = self->entry->data.normal.actions; it; - it = g_slist_next(it)) + for (it = acts; it; it = g_slist_next(it)) { ObAction *act = it->data; act->data.any.c = self->frame->client; diff --git a/plugins/menu/client_list_menu.c b/plugins/menu/client_list_menu.c index 5b014116..054353fd 100644 --- a/plugins/menu/client_list_menu.c +++ b/plugins/menu/client_list_menu.c @@ -60,11 +60,11 @@ static void desk_menu_update(ObMenuFrame *frame, gpointer data) /* executes it without changing the client in the actions, since we set that when we make the actions! */ -static void desk_menu_execute(ObMenuEntryFrame *self, gpointer data) +static void desk_menu_execute(ObMenuEntry *self, gpointer data) { GSList *it; - for (it = self->entry->data.normal.actions; it; it = g_slist_next(it)) + for (it = self->data.normal.actions; it; it = g_slist_next(it)) { ObAction *act = it->data; act->func(&act->data); -- 2.39.2