From cc2e77295ef3c1acc81ccbe45e1cf063d45b9058 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 24 Nov 2015 17:53:41 +0100 Subject: [PATCH] device: Fix dispose The way master devices detach from their other master counterpart is vulnerable to infinite recursion due to the way we first recurse on the other device before clearing the pointer, this may happen if that last reference to the other master device is held by the device->associated field. https://bugzilla.gnome.org/show_bug.cgi?id=732742 --- gdk/gdkdevice.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/gdk/gdkdevice.c b/gdk/gdkdevice.c index a1a59d27a0..0e325d60c3 100644 --- a/gdk/gdkdevice.c +++ b/gdk/gdkdevice.c @@ -323,17 +323,20 @@ static void gdk_device_dispose (GObject *object) { GdkDevice *device = GDK_DEVICE (object); + GdkDevice *associated = device->associated; - if (device->type == GDK_DEVICE_TYPE_SLAVE) - _gdk_device_remove_slave (device->associated, device); + if (associated && device->type == GDK_DEVICE_TYPE_SLAVE) + _gdk_device_remove_slave (associated, device); - if (device->associated) + if (associated) { - if (device->type == GDK_DEVICE_TYPE_MASTER) - _gdk_device_set_associated_device (device->associated, NULL); - - g_object_unref (device->associated); device->associated = NULL; + + if (device->type == GDK_DEVICE_TYPE_MASTER && + associated->associated == device) + _gdk_device_set_associated_device (associated, NULL); + + g_object_unref (associated); } G_OBJECT_CLASS (gdk_device_parent_class)->dispose (object);