From b0e2bf8b95f1f12347c727655de8f1b904b6647a Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 21 Nov 2009 10:54:44 +0100 Subject: [PATCH] Fix a invalid pointer crash bug This changes wibox_t::mouse_over to a proper reference. That way one can't remove that widget from underneath us which would lead to an unprotected lua error. Signed-off-by: Uli Schlachter Signed-off-by: Julien Danjou --- event.c | 12 ++++++++++-- objects/wibox.c | 19 ++++++++++++++++--- objects/wibox.h | 2 ++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/event.c b/event.c index a97d7891f..370d9ae0e 100644 --- a/event.c +++ b/event.c @@ -358,11 +358,19 @@ event_handle_widget_motionnotify(void *object, luaA_object_push(globalconf.L, *mouse_over); luaA_object_emit_signal(globalconf.L, -1, "mouse::leave", 0); lua_pop(globalconf.L, 1); + + luaA_object_unref(globalconf.L, *mouse_over); + *mouse_over = NULL; } if(widget) { - /* emit mouse::enter signal on new widget and register it */ + /* Get a ref on this widget so that it can't be unref'd from + * underneath us (-> invalid pointer dereference). */ + luaA_object_push(globalconf.L, widget); + luaA_object_ref(globalconf.L, -1); *mouse_over = widget; + + /* emit mouse::enter signal on new widget */ luaA_object_push(globalconf.L, widget); luaA_object_emit_signal(globalconf.L, -1, "mouse::enter", 0); lua_pop(globalconf.L, 1); @@ -429,7 +437,7 @@ event_handle_leavenotify(void *data __attribute__ ((unused)), /* emit mouse::leave signal on widget the mouse was over */ luaA_object_emit_signal(globalconf.L, -1, "mouse::leave", 0); lua_pop(globalconf.L, 1); - wibox->mouse_over = NULL; + wibox_clear_mouse_over(wibox); } luaA_object_push(globalconf.L, wibox); diff --git a/objects/wibox.c b/objects/wibox.c index 88e8c46b6..b3a06cbe1 100644 --- a/objects/wibox.c +++ b/objects/wibox.c @@ -86,7 +86,7 @@ static void wibox_need_update(wibox_t *wibox) { wibox->need_update = true; - wibox->mouse_over = NULL; + wibox_clear_mouse_over(wibox); } static int @@ -631,6 +631,19 @@ wibox_refresh(void) } } +/** Clear the wibox' mouse_over pointer. + * \param wibox The wibox. + */ +void +wibox_clear_mouse_over(wibox_t *wibox) +{ + if (wibox->mouse_over) + { + luaA_object_unref(globalconf.L, wibox->mouse_over); + wibox->mouse_over = NULL; + } +} + /** Set a wibox visible or not. * \param L The Lua VM state. * \param udx The wibox. @@ -643,7 +656,7 @@ wibox_set_visible(lua_State *L, int udx, bool v) if(v != wibox->visible) { wibox->visible = v; - wibox->mouse_over = NULL; + wibox_clear_mouse_over(wibox); if(wibox->screen) { @@ -686,7 +699,7 @@ wibox_detach(lua_State *L, int udx) /* restore visibility */ wibox->visible = v; - wibox->mouse_over = NULL; + wibox_clear_mouse_over(wibox); wibox_wipe(wibox); diff --git a/objects/wibox.h b/objects/wibox.h index 37a80b38a..6ebd29600 100644 --- a/objects/wibox.h +++ b/objects/wibox.h @@ -99,5 +99,7 @@ void wibox_class_setup(lua_State *); lua_class_t wibox_class; +void wibox_clear_mouse_over(wibox_t *); + #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80