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
This commit is contained in:
Owen W. Taylor 2015-10-22 13:30:27 -04:00
parent a83f822512
commit d8336efddc
2 changed files with 12 additions and 2 deletions

View File

@ -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);

View File

@ -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);
}