* make cairo_quartz_surface_to_quartz() return NULL if it's not a valid quartz surface and add null-check at call sites. * fix a couple of leaks under OOM * fix a warning about missing initializers for cairo_quartz_surface_backend b=397293 r+sr+a=vladimir
authormats.palmgren@bredband.net
Thu, 25 Oct 2007 08:49:25 -0700
changeset 7173 03b00fa3a3b9e039c58a8f19de93fa471bd68880
parent 7172 3beb56c8fa6a90902ccee694f198684622b03991
child 7174 dd77ddf3631187357f55ff7a01c147b32dceb4e2
push id1
push userbsmedberg@mozilla.com
push dateThu, 20 Mar 2008 16:49:24 +0000
treeherderautoland@61007906a1f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs397293
milestone1.9a9pre
* make cairo_quartz_surface_to_quartz() return NULL if it's not a valid quartz surface and add null-check at call sites. * fix a couple of leaks under OOM * fix a warning about missing initializers for cairo_quartz_surface_backend b=397293 r+sr+a=vladimir
gfx/cairo/cairo/src/cairo-quartz-surface.c
--- a/gfx/cairo/cairo/src/cairo-quartz-surface.c
+++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c
@@ -465,16 +465,23 @@ static cairo_quartz_surface_t *
 
 	_cairo_surface_clone_similar (ref_type, pat_surf, rect.x, rect.y,
 				      rect.width, rect.height, &new_surf);
 
 	if (target == NULL)
 	    cairo_surface_destroy(ref_type);
 
 	quartz_surf = (cairo_quartz_surface_t *) new_surf;
+
+	if (new_surf &&
+	    cairo_surface_get_type (new_surf) != CAIRO_SURFACE_TYPE_QUARTZ) {
+	    ND((stderr, "got a non-quartz surface, format=%d width=%u height=%u type=%d\n", cairo_surface_get_type (pat_surf), rect.width, rect.height, cairo_surface_get_type (new_surf)));
+	    cairo_surface_destroy (new_surf);
+	    quartz_surf = NULL;
+	}
     } else {
 	/* If it's a quartz surface, we can try to see if it's a CGBitmapContext;
 	 * we do this when we call CGBitmapContextCreateImage below.
 	 */
 	cairo_surface_reference (pat_surf);
 	quartz_surf = (cairo_quartz_surface_t*) pat_surf;
 
     }
@@ -485,16 +492,19 @@ static cairo_quartz_surface_t *
 /* Generic cairo_pattern -> CGPattern function */
 static void
 SurfacePatternDrawFunc (void *info, CGContextRef context)
 {
     cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) info;
     cairo_surface_t *pat_surf = spat->surface;
 
     cairo_quartz_surface_t *quartz_surf = _cairo_quartz_surface_to_quartz (NULL, pat_surf);
+    if (!quartz_surf)
+	return;
+
     CGImageRef img = CGBitmapContextCreateImage (quartz_surf->cgContext);
     CGRect imageBounds;
 
     if (!img) {
 	// ... give up.
 	ND((stderr, "CGBitmapContextCreateImage failed\n"));
 	cairo_surface_destroy ((cairo_surface_t*)quartz_surf);
 	return;
@@ -689,16 +699,19 @@ static cairo_quartz_action_t
 
 	return DO_SHADING;
     } else if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
 	       source->extend == CAIRO_EXTEND_NONE)
     {
 	    cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) source;
 	    cairo_surface_t *pat_surf = spat->surface;
 	    cairo_quartz_surface_t *quartz_surf = _cairo_quartz_surface_to_quartz ((cairo_surface_t *) surface, pat_surf);
+	    if (!quartz_surf)
+		return DO_UNSUPPORTED;
+
 	    CGImageRef img = CGBitmapContextCreateImage (quartz_surf->cgContext);
 	    cairo_matrix_t m = spat->base.matrix;
 	    cairo_rectangle_int_t extents;
 
 	    if (!img)
 		return DO_UNSUPPORTED;
 
 	    surface->sourceImage = img;
@@ -1090,18 +1103,20 @@ static cairo_status_t
 
     if (!quartz_image)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     new_surface = (cairo_quartz_surface_t *)
 	cairo_quartz_surface_create (new_format,
 				     CGImageGetWidth (quartz_image),
 				     CGImageGetHeight (quartz_image));
-    if (!new_surface || new_surface->base.status)
+    if (!new_surface || new_surface->base.status) {
+	CGImageRelease (quartz_image);
 	return CAIRO_INT_STATUS_UNSUPPORTED;
+    }
 
     CGContextSetCompositeOperation (new_surface->cgContext,
 				    kPrivateCGCompositeCopy);
 
     quartz_image_to_png (quartz_image, NULL);
 
     CGContextDrawImage (new_surface->cgContext,
 			CGRectMake (src_x, src_y, width, height),
@@ -1594,16 +1609,19 @@ static const struct _cairo_surface_backe
     _cairo_quartz_surface_fill,
 #if CAIRO_HAS_ATSUI_FONT
     _cairo_quartz_surface_show_glyphs,
 #else 
     NULL, /* surface_show_glyphs */
 #endif /* CAIRO_HAS_ATSUI_FONT */
 
     NULL, /* snapshot */
+    NULL, /* is_similar */
+    NULL, /* reset */
+    NULL  /* fill_stroke */
 };
 
 static cairo_quartz_surface_t *
 _cairo_quartz_surface_create_internal (CGContextRef cgContext,
 					cairo_content_t content,
 					unsigned int width,
 					unsigned int height)
 {
@@ -1765,16 +1783,17 @@ cairo_quartz_surface_create (cairo_forma
 				 bitsPerComponent,
 				 stride,
 				 cgColorspace,
 				 bitinfo);
     CGColorSpaceRelease (cgColorspace);
 
     if (!cgc) {
 	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	free (imageData);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
     /* flip the Y axis */
     CGContextTranslateCTM (cgc, 0.0, height);
     CGContextScaleCTM (cgc, 1.0, -1.0);
 
     surf = _cairo_quartz_surface_create_internal (cgc, _cairo_content_from_format (format),