diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2015-11-24 17:53:41 +0100 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2015-11-24 20:52:12 +0100 |
commit | cc2e77295ef3c1acc81ccbe45e1cf063d45b9058 (patch) | |
tree | d90555756ba5a21976c040443bb15e8acbd593a0 /gdk/gdkdevice.c | |
parent | d62febcf97581528398f79e8094eb26f8461b315 (diff) | |
download | gtk+-cc2e77295ef3c1acc81ccbe45e1cf063d45b9058.tar.gz |
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
Diffstat (limited to 'gdk/gdkdevice.c')
-rw-r--r-- | gdk/gdkdevice.c | 17 |
1 files 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); |