[gnome-shell/gnome-3-18] Defend against failure of cairo_pattern_get_surface()



commit d8336efddca5e5eb7524035d6dd1205efcbdb4e1
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Thu Oct 22 13:30:27 2015 -0400

    Defend against failure of cairo_pattern_get_surface()
    
    There are quite a few crashes in retrace.fedoraproject.org that are a result of
    of cairo_pattern_get_surface() failing, then a subsequent call to
    cairo_image_surface_get_width() crashing because no surface was returned to the
    out parameter. Knowing what causes these is hard - my best guess is widgets getting
    allocated at ridiculous sizes - but avoiding the crash makes sense in any case.
    
    See https://bugzilla.redhat.com/show_bug.cgi?id=1206754
    
    https://bugzilla.gnome.org/show_bug.cgi?id=756983

 src/st/st-private.c            |    7 ++++++-
 src/st/st-theme-node-drawing.c |    7 ++++++-
 2 files changed, 12 insertions(+), 2 deletions(-)
---
diff --git a/src/st/st-private.c b/src/st/st-private.c
index c842be0..9ff469a 100644
--- a/src/st/st-private.c
+++ b/src/st/st-private.c
@@ -512,7 +512,12 @@ _st_create_shadow_cairo_pattern (StShadow        *shadow_spec,
   g_return_val_if_fail (shadow_spec != NULL, NULL);
   g_return_val_if_fail (src_pattern != NULL, NULL);
 
-  cairo_pattern_get_surface (src_pattern, &src_surface);
+  if (cairo_pattern_get_surface (src_pattern, &src_surface) != CAIRO_STATUS_SUCCESS)
+    /* The most likely reason we can't get the pattern is that sizing went hairwire
+     * and the caller tried to create a surface too big for memory, leaving us with
+     * a pattern in an error state; we return a transparent pattern for the shadow.
+     */
+    return cairo_pattern_create_rgba(1.0, 1.0, 1.0, 0.0);
 
   width_in  = cairo_image_surface_get_width  (src_surface);
   height_in = cairo_image_surface_get_height (src_surface);
diff --git a/src/st/st-theme-node-drawing.c b/src/st/st-theme-node-drawing.c
index 75fc53f..28151b9 100644
--- a/src/st/st-theme-node-drawing.c
+++ b/src/st/st-theme-node-drawing.c
@@ -741,7 +741,11 @@ paint_shadow_pattern_to_cairo_context (StShadow *shadow_spec,
       /* Then subtract out the bounds of the surface in the surface
        * pattern; we transform the context by the inverse of the
        * pattern matrix to get to surface coordinates */
-      cairo_pattern_get_surface (pattern, &surface);
+
+      if (cairo_pattern_get_surface (pattern, &surface) != CAIRO_STATUS_SUCCESS)
+        /* Something went wrong previously */
+        goto no_surface;
+
       width = cairo_image_surface_get_width  (surface);
       height = cairo_image_surface_get_height (surface);
 
@@ -752,6 +756,7 @@ paint_shadow_pattern_to_cairo_context (StShadow *shadow_spec,
       cairo_rectangle (cr, 0, height, width, - height);
       cairo_fill (cr);
 
+    no_surface:
       cairo_restore (cr);
     }
 


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