[gtk+] wayland: Check transient loop



commit b456db8cf4c8c7d52d4a5c90948bd659b0716de6
Author: Olivier Fourdan <ofourdan redhat com>
Date:   Mon Dec 14 16:34:00 2015 +0100

    wayland: Check transient loop
    
    Gdk Wayland backend walks up the transient windows tree, but does not
    check for cycles when doing so.
    
    As a result, if two or more windows are transient to each other, the
    Wayland gdk backend will enter an infinite loop.
    
    While this is clearly a bug in the application, gtk+/gdk should be more
    robust and handle such errors more gracefully.
    
    To avoid looping infinitely at various point in the code, check for a
    possible loop when setting the transient relationship and deny the
    request to set a window transient for another if that would create a
    loop.
    
    Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=759299

 gdk/wayland/gdkwindow-wayland.c |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)
---
diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c
index 753aac5..0776471 100644
--- a/gdk/wayland/gdkwindow-wayland.c
+++ b/gdk/wayland/gdkwindow-wayland.c
@@ -1943,12 +1943,33 @@ gdk_wayland_window_set_startup_id (GdkWindow   *window,
 {
 }
 
+static gboolean
+check_transient_for_loop (GdkWindow *window,
+                          GdkWindow *parent)
+{
+  while (parent)
+    {
+      GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (parent->impl);
+
+      if (impl->transient_for == window)
+        return TRUE;
+      parent = impl->transient_for;
+    }
+  return FALSE;
+}
+
 static void
 gdk_wayland_window_set_transient_for (GdkWindow *window,
                                       GdkWindow *parent)
 {
   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
 
+  if (check_transient_for_loop (window, parent))
+    {
+      g_warning ("Setting %p transient for %p would create a loop", window, parent);
+      return;
+    }
+
   if (impl->subsurface)
     unmap_subsurface (window);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]