-----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

Reply via email to