From 6d22670307928dfdce75a7536598486fa25d51d7 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Thu, 22 Oct 2015 13:30:27 -0400 Subject: [PATCH] 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 c842be0cf..9ff469a81 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 fdb69de2d..95386dc7d 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); }