wayland: Sanity check cursor image size
authorMatthias Clasen <mclasen@redhat.com>
Fri, 27 May 2022 02:28:57 +0000 (22:28 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Fri, 27 May 2022 10:59:10 +0000 (06:59 -0400)
On Wayland it is a protocol violation to upload buffers with
dimensions that are not an integer multiple of the buffer scale.

Until recently, Mutter did not enforce this. When it started
doing so, some users started seeing crashes in GTK apps because the
cursor theme ended up with e.g. a 15x16 pixel image at scale of 2.

Add a small sanity check for this case.

gdk/wayland/gdkcursor-wayland.c

index c859f3ccacdaf96a71d68f97126e1934d49b498b..a5602bcbaf9f94df8d93ae0923cbe9a4942a3100 100644 (file)
@@ -178,6 +178,7 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
       if (c)
         {
           struct wl_cursor_image *image;
+          int cursor_scale;
 
           if (image_index >= c->image_count)
             {
@@ -189,12 +190,22 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
 
           image = c->images[image_index];
 
-          *hotspot_x = image->hotspot_x / desired_scale;
-          *hotspot_y = image->hotspot_y / desired_scale;
+          cursor_scale = desired_scale;
+          if ((image->width % cursor_scale != 0) ||
+              (image->height % cursor_scale != 0))
+            {
+              g_warning (G_STRLOC " cursor image size (%dx%d) not an integer"
+                         "multiple of scale (%d)", image->width, image->height,
+                         cursor_scale);
+              cursor_scale = 1;
+            }
+
+          *hotspot_x = image->hotspot_x / cursor_scale;
+          *hotspot_y = image->hotspot_y / cursor_scale;
 
-          *width = image->width / desired_scale;
-          *height = image->height / desired_scale;
-          *scale = desired_scale;
+          *width = image->width / cursor_scale;
+          *height = image->height / cursor_scale;
+          *scale = cursor_scale;
 
           return wl_cursor_image_get_buffer (image);
         }