-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Hi list,
the attached patch fixes FS#679 for me. I don't have a proper test case, but I'm
99% sure this patch is correct.
I hope this patch explains itself.
Uli
P.S.
I'm submitting this now because someone else reported this bug on irc today.
- --
"Do you know that books smell like nutmeg or some spice from a foreign land?"
-- Faber in Fahrenheit 451
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
iQEcBAEBCAAGBQJLFXryAAoJECLkKOvLj8sGD1sIAKPxcYQ4uEvrV7oDan50htDP
qga3BFxRA+7o8rOyQ2jSXD/UtbdmL8xhMK5F9LbCRsp5nbL0mQ0tQdH8Y+YCN5fN
mPJryWBm7TkvN5ssQ2X1hIqKQGGo9X+QVx08bTcNMzD2Dwv95tgnCVCys48OZLDB
W+M/gv0buX1jH4k8w7sGVLZM+mNfdZFtBbjG0EfBlXYAMzy6jGibpFC29QCI6teP
JZAzmzRLzWXirIOFt9X1XMGuQ3r8mu7sAf3z3XjrRsxAMHe7I7aNo6VHyadcJ3G7
PvoXUJXdGuhW0Bi5U0YHTCAZrcWkHNF0dkgRZjrKNLyx1Vz603OovInfHKr+EZQ=
=N5UP
-----END PGP SIGNATURE-----
>From 00a5673458b5fc2105ef2b5028bece47f65eb95a Mon Sep 17 00:00:00 2001
From: Uli Schlachter <[email protected]>
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 <[email protected]>
---
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 a97d789..370d9ae 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 88e8c46..b3a06cb 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 37a80b3..6ebd296 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
--
1.6.5