[cairo-commit] 11 commits - src/cairo-pdf-operators.c src/cairo-pdf-surface.c src/cairo-ps-surface.c src/cairo-svg-surface.c src/cairo-xlib-private.h src/cairo-xlib-screen.c src/cairo-xlib-surface.c src/cairo-xlib-visual.c test/text-transform.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Apr 2 03:22:12 PDT 2008


 src/cairo-pdf-operators.c |    6 ++--
 src/cairo-pdf-surface.c   |   13 ++++++---
 src/cairo-ps-surface.c    |   13 ++++++++-
 src/cairo-svg-surface.c   |   13 ++++++++-
 src/cairo-xlib-private.h  |   15 ++++++++---
 src/cairo-xlib-screen.c   |   52 ++++++++++++++++++++++++++------------
 src/cairo-xlib-surface.c  |   62 ++++++++++++++++++++++++++++++----------------
 src/cairo-xlib-visual.c   |   19 +++++++++++---
 test/text-transform.c     |   10 ++-----
 9 files changed, 142 insertions(+), 61 deletions(-)

New commits:
commit c1062bf20ab60f6335be0814de245616a8d24bd2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Apr 2 10:43:39 2008 +0100

    [cairo-xlib-surface] Preserve Visuals for non-TrueColor similar surfaces.
    
    Previously, given a valid XRenderFormat the Visual was discarded
    when creating similar surfaces. However the original Visual is
    required to support reading back from non-TrueColor surfaces.

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index c0ffd05..3649ca6 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -48,6 +48,16 @@
 typedef int (*cairo_xlib_error_func_t) (Display     *display,
 					XErrorEvent *event);
 
+static cairo_surface_t *
+_cairo_xlib_surface_create_internal (Display		       *dpy,
+				     Drawable		        drawable,
+				     Screen		       *screen,
+				     Visual		       *visual,
+				     XRenderPictFormat	       *xrender_format,
+				     int			width,
+				     int			height,
+				     int			depth);
+
 static cairo_status_t
 _cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface);
 
@@ -71,10 +81,6 @@ _cairo_xlib_surface_show_glyphs (void                *abstract_dst,
 				 int		      num_glyphs,
 				 cairo_scaled_font_t *scaled_font);
 
-#if CAIRO_HAS_XLIB_XRENDER_SURFACE
-slim_hidden_proto (cairo_xlib_surface_create_with_xrender_format);
-#endif
-
 /*
  * Instead of taking two round trips for each blending request,
  * assume that if a particular drawable fails GetImage that it will
@@ -173,9 +179,11 @@ _cairo_xlib_surface_create_similar_with_format (void	       *abstract_src,
 			 depth);
 
     surface = (cairo_xlib_surface_t *)
-	cairo_xlib_surface_create_with_xrender_format (dpy, pix, src->screen,
-						       xrender_format,
-						       width, height);
+	      _cairo_xlib_surface_create_internal (dpy, pix,
+		                                   src->screen, src->visual,
+						   xrender_format,
+						   width, height,
+						   depth);
     if (surface->base.status) {
 	XFreePixmap (dpy, pix);
 	return &surface->base;
@@ -251,10 +259,11 @@ _cairo_xlib_surface_create_similar (void	       *abstract_src,
 			 xrender_format->depth);
 
     surface = (cairo_xlib_surface_t *)
-	cairo_xlib_surface_create_with_xrender_format (src->dpy, pix,
-						       src->screen,
-						       xrender_format,
-						       width, height);
+	      _cairo_xlib_surface_create_internal (src->dpy, pix,
+		                                   src->screen, src->visual,
+						   xrender_format,
+						   width, height,
+						   xrender_format->depth);
     if (surface->base.status != CAIRO_STATUS_SUCCESS) {
 	XFreePixmap (src->dpy, pix);
 	return &surface->base;
@@ -2392,7 +2401,6 @@ cairo_xlib_surface_create_with_xrender_format (Display		    *dpy,
     return _cairo_xlib_surface_create_internal (dpy, drawable, screen,
 						NULL, format, width, height, 0);
 }
-slim_hidden_def (cairo_xlib_surface_create_with_xrender_format);
 
 /**
  * cairo_xlib_surface_get_xrender_format:
commit b3a70629f8d1f5d7c23f4369d3395af73318eb28
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Apr 2 09:19:11 2008 +0100

    [test/text-transform] Fix pattern leak.
    
    Add missing cairo_pattern_destroy.

diff --git a/test/text-transform.c b/test/text-transform.c
index 0a886db..78a68d7 100644
--- a/test/text-transform.c
+++ b/test/text-transform.c
@@ -41,9 +41,7 @@ cairo_test_t test = {
     draw
 };
 
-void draw_text (cairo_t *cr);
-
-void
+static void
 draw_text (cairo_t *cr)
 {
     cairo_matrix_t tm;
@@ -82,9 +80,6 @@ draw (cairo_t *cr, int width, int height)
 {
     cairo_pattern_t *pattern;
 
-    pattern = cairo_test_create_pattern_from_png (png_filename);
-    cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
-
     cairo_set_source_rgb (cr, 1., 1., 1.);
     cairo_paint (cr);
 
@@ -99,7 +94,10 @@ draw (cairo_t *cr, int width, int height)
     cairo_translate (cr, SIZE, SIZE);
     cairo_rotate (cr, M_PI);
 
+    pattern = cairo_test_create_pattern_from_png (png_filename);
+    cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
     cairo_set_source (cr, pattern);
+    cairo_pattern_destroy (pattern);
 
     draw_text (cr);
 
commit 37c69c0d54c4b77c96497db4d6633558d4e1300d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Mar 31 21:49:34 2008 +0100

    [cairo-xlib] Handle malloc failures for cairo_xlib_visual_info_t.
    
    Tidy the error paths whilst handling visuals, in particular avoiding a
    couple of potential NULL deferences, missed status checks and fresh
    leaks.

diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index 5edb5d2..5bfc2ec 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -133,11 +133,18 @@ _cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info, int depth);
 cairo_private cairo_status_t
 _cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info, int depth, GC gc, cairo_bool_t reset_clip);
 
-cairo_private cairo_xlib_visual_info_t *
+cairo_private cairo_status_t
 _cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
-				    Visual *visual);
+				    Visual *visual,
+				    cairo_xlib_visual_info_t **out);
+
+cairo_private cairo_status_t
+_cairo_xlib_visual_info_create (Display *dpy,
+	                        int screen,
+				VisualID visualid,
+				cairo_xlib_visual_info_t **out);
 
-cairo_private cairo_xlib_visual_info_t *
-_cairo_xlib_visual_info_create (Display *dpy, int screen, VisualID visualid);
+cairo_private void
+_cairo_xlib_visual_info_destroy (Display *dpy, cairo_xlib_visual_info_t *info);
 
 #endif /* CAIRO_XLIB_PRIVATE_H */
diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c
index cdba294..8a3da66 100644
--- a/src/cairo-xlib-screen.c
+++ b/src/cairo-xlib-screen.c
@@ -286,7 +286,7 @@ _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info)
     }
     visuals = _cairo_array_index (&info->visuals, 0);
     for (i = 0; i < _cairo_array_num_elements (&info->visuals); i++)
-	free (visuals[i]);
+	_cairo_xlib_visual_info_destroy (info->display->display, visuals[i]);
     CAIRO_MUTEX_UNLOCK (info->display->mutex);
 
     _cairo_xlib_screen_info_close_display (info);
@@ -422,17 +422,19 @@ _cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info, int depth, GC gc, cai
     return status;
 }
 
-cairo_xlib_visual_info_t *
+cairo_status_t
 _cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
-				    Visual *visual)
+				    Visual *visual,
+				    cairo_xlib_visual_info_t **out)
 {
     cairo_xlib_visual_info_t **visuals, *ret = NULL;
     cairo_status_t status;
-    int i;
+    int i, n_visuals;
 
     CAIRO_MUTEX_LOCK (info->display->mutex);
     visuals = _cairo_array_index (&info->visuals, 0);
-    for (i = 0; i < _cairo_array_num_elements (&info->visuals); i++) {
+    n_visuals = _cairo_array_num_elements (&info->visuals);
+    for (i = 0; i < n_visuals; i++) {
 	if (visuals[i]->visualid == visual->visualid) {
 	    ret = visuals[i];
 	    break;
@@ -440,23 +442,41 @@ _cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
     }
     CAIRO_MUTEX_UNLOCK (info->display->mutex);
 
-    if (ret)
-	return ret;
+    if (ret != NULL) {
+	*out = ret;
+	return CAIRO_STATUS_SUCCESS;
+    }
 
-    ret = _cairo_xlib_visual_info_create (info->display->display,
-					  XScreenNumberOfScreen (info->screen),
-					  visual->visualid);
-    if (ret == NULL)
-	return ret;
+    status = _cairo_xlib_visual_info_create (info->display->display,
+					     XScreenNumberOfScreen (info->screen),
+					     visual->visualid,
+					     &ret);
+    if (status)
+	return status;
 
     CAIRO_MUTEX_LOCK (info->display->mutex);
-    status = _cairo_array_append (&info->visuals, &ret);
+    if (n_visuals != _cairo_array_num_elements (&info->visuals)) {
+	/* check that another thread has not added our visual */
+	int new_visuals = _cairo_array_num_elements (&info->visuals);
+	visuals = _cairo_array_index (&info->visuals, 0);
+	for (i = n_visuals; i < new_visuals; i++) {
+	    if (visuals[i]->visualid == visual->visualid) {
+		_cairo_xlib_visual_info_destroy (info->display->display, ret);
+		ret = visuals[i];
+		break;
+	    }
+	}
+	if (i == new_visuals)
+	    status = _cairo_array_append (&info->visuals, &ret);
+    } else
+	status = _cairo_array_append (&info->visuals, &ret);
     CAIRO_MUTEX_UNLOCK (info->display->mutex);
 
     if (status) {
-	free (ret);
-	ret = NULL;
+	_cairo_xlib_visual_info_destroy (info->display->display, ret);
+	return status;
     }
 
-    return ret;
+    *out = ret;
+    return CAIRO_STATUS_SUCCESS;
 }
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 0662b70..c0ffd05 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -695,8 +695,13 @@ _get_image_surface (cairo_xlib_surface_t    *surface,
 
 	    format = CAIRO_FORMAT_RGB24;
 
-	    visual_info = _cairo_xlib_screen_get_visual_info (surface->screen_info,
-							      surface->visual);
+	    status = _cairo_xlib_screen_get_visual_info (surface->screen_info,
+							 surface->visual,
+							 &visual_info);
+	    if (status) {
+		XDestroyImage (ximage);
+		return status;
+	    }
 
 	    colors = visual_info->colors;
 	}
@@ -845,7 +850,7 @@ _draw_image_surface (cairo_xlib_surface_t   *surface,
     unsigned long *rgb333_to_pseudocolor = NULL;
 
     _pixman_format_to_masks (image->pixman_format, &image_masks);
-    
+
     ximage.width = image->width;
     ximage.height = image->height;
     ximage.format = ZPixmap;
@@ -859,7 +864,7 @@ _draw_image_surface (cairo_xlib_surface_t   *surface,
     ximage.blue_mask = surface->b_mask;
     ximage.xoffset = 0;
 
-    if (image_masks.red_mask   == surface->r_mask   &&
+    if (image_masks.red_mask   == surface->r_mask &&
 	image_masks.green_mask == surface->g_mask &&
 	image_masks.blue_mask  == surface->b_mask)
     {
@@ -887,7 +892,10 @@ _draw_image_surface (cairo_xlib_surface_t   *surface,
 	stride = CAIRO_STRIDE_FOR_WIDTH_BPP (ximage.width,
 					     ximage.bits_per_pixel);
 	ximage.bytes_per_line = stride;
-	ximage.data = malloc (stride * ximage.height);
+	ximage.data = _cairo_malloc_ab (stride, ximage.height);
+	if (ximage.data == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
 	own_data = TRUE;
 
 	XInitImage (&ximage);
@@ -900,8 +908,11 @@ _draw_image_surface (cairo_xlib_surface_t   *surface,
 	} else {
 	    cairo_xlib_visual_info_t *visual_info;
 
-	    visual_info = _cairo_xlib_screen_get_visual_info (surface->screen_info,
-							      surface->visual);
+	    status = _cairo_xlib_screen_get_visual_info (surface->screen_info,
+							 surface->visual,
+							 &visual_info);
+	    if (status)
+		goto BAIL;
 
 	    rgb333_to_pseudocolor = visual_info->rgb333_to_pseudocolor;
 	}
@@ -933,16 +944,17 @@ _draw_image_surface (cairo_xlib_surface_t   *surface,
 
     status = _cairo_xlib_surface_ensure_gc (surface);
     if (status)
-	return status;
+	goto BAIL;
 
     XPutImage(surface->dpy, surface->drawable, surface->gc,
 	      &ximage, src_x, src_y, dst_x, dst_y,
 	      width, height);
 
+  BAIL:
     if (own_data)
 	free (ximage.data);
 
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
 
 static cairo_status_t
diff --git a/src/cairo-xlib-visual.c b/src/cairo-xlib-visual.c
index 882028a..a45be53 100644
--- a/src/cairo-xlib-visual.c
+++ b/src/cairo-xlib-visual.c
@@ -56,8 +56,11 @@ _color_distance (unsigned short r1, unsigned short g1, unsigned short b1,
 	    (b2 - b1) * (b2 - b1));
 }
 
-cairo_xlib_visual_info_t *
-_cairo_xlib_visual_info_create (Display *dpy, int screen, VisualID visualid)
+cairo_status_t
+_cairo_xlib_visual_info_create (Display *dpy,
+	                        int screen,
+				VisualID visualid,
+				cairo_xlib_visual_info_t **out)
 {
     cairo_xlib_visual_info_t *info;
     Colormap colormap = DefaultColormap (dpy, screen);
@@ -75,7 +78,7 @@ _cairo_xlib_visual_info_create (Display *dpy, int screen, VisualID visualid)
 
     info = malloc (sizeof (cairo_xlib_visual_info_t));
     if (info == NULL)
-	return NULL;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     info->visualid = visualid;
 
@@ -133,5 +136,13 @@ _cairo_xlib_visual_info_create (Display *dpy, int screen, VisualID visualid)
 	}
     }
 
-    return info;
+    *out = info;
+    return CAIRO_STATUS_SUCCESS;
+}
+
+void
+_cairo_xlib_visual_info_destroy (Display *dpy, cairo_xlib_visual_info_t *info)
+{
+    /* No need for XFreeColors() whilst using DefaultColormap */
+    free (info);
 }
commit 0cd42c25a6f4be1ff27ed3a9ba7fa9a91d076e0d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Mar 31 19:15:48 2008 +0100

    [cairo-svg-surface] Check surface status before extracting the svg target.
    
    We need to check and report the existent status, else we may try to
    modify the inert error object.

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 11c8f43..a900c24 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -233,10 +233,15 @@ _extract_svg_surface (cairo_surface_t		 *surface,
 {
     cairo_surface_t *target;
 
+    if (surface->status)
+	return surface->status;
+
     if (! _cairo_surface_is_paginated (surface))
 	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 
     target = _cairo_paginated_surface_get_target (surface);
+    if (target->status)
+	return target->status;
 
     if (! _cairo_surface_is_svg (target))
 	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
commit 013bbda6373d84d39e080c5e0b305581a2c6919c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Mar 31 19:15:16 2008 +0100

    [cairo-ps-surface] Check surface status before extracting the ps target.
    
    We need to check and report the existent status, else we may try to
    modify the inert error object.

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index a197ff9..e78e247 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -859,10 +859,15 @@ _extract_ps_surface (cairo_surface_t	 *surface,
 {
     cairo_surface_t *target;
 
+    if (surface->status)
+	return surface->status;
+
     if (! _cairo_surface_is_paginated (surface))
 	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 
     target = _cairo_paginated_surface_get_target (surface);
+    if (target->status)
+	return target->status;
 
     if (! _cairo_surface_is_ps (target))
 	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
commit cebb1eef431a38c7c3a96ae60a5bee188f41dc0b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Mar 31 19:09:21 2008 +0100

    [cairo-svg-surface] Missing status check.
    
    Check and, if necessary, propagate the error status - do not allow the
    status to be overwritten, potentially masking the original error.

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index c218bc5..11c8f43 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -2109,6 +2109,9 @@ _cairo_svg_surface_stroke (void			*abstract_dst,
     _cairo_output_stream_printf (surface->xml_node, "<path style=\"fill: none; ");
     status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, op,
 						   source, stroke_style, ctm_inverse);
+    if (status)
+	return status;
+
     _cairo_output_stream_printf (surface->xml_node, "\" ");
 
     status = _cairo_svg_surface_emit_path (surface->xml_node, path, ctm_inverse);
commit 94db91b65ef42228c963f2d6d82da085f9148895
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Mar 31 15:47:45 2008 +0100

    [cairo-pdf-surface] Do not mask error during cleanup.
    
    Be careful to preserve the original error status whilst on the common
    cleanup path for _cairo_pdf_surface_emit_meta_surface().

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 5e9e298..53af765 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -1501,7 +1501,7 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t  *surface,
     cairo_paginated_mode_t old_paginated_mode;
     cairo_clip_t *old_clip;
     cairo_rectangle_int_t meta_extents;
-    cairo_status_t status;
+    cairo_status_t status, status2;
     int alpha = 0;
 
     status = _cairo_surface_get_extents (meta_surface, &meta_extents);
@@ -1555,9 +1555,9 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t  *surface,
     surface->height = old_height;
     surface->paginated_mode = old_paginated_mode;
     surface->cairo_to_pdf = old_cairo_to_pdf;
-    status = _cairo_surface_set_clip (&surface->base, old_clip);
-    if (status)
-	return status;
+    status2 = _cairo_surface_set_clip (&surface->base, old_clip);
+    if (status == CAIRO_STATUS_SUCCESS)
+	status = status2;
 
     _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
 						  &surface->cairo_to_pdf);
commit 3580b99a8f99db207b54529f5ac7d0e4325cc123
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Mar 31 14:25:17 2008 +0100

    [cairo-pdf-surface] Check surface status before extracting the pdf target.
    
    We need to check and report the existent status, else we may try to
    modify the inert error object.

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 7a52951..5e9e298 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -393,10 +393,15 @@ _extract_pdf_surface (cairo_surface_t		 *surface,
 {
     cairo_surface_t *target;
 
+    if (surface->status)
+	return surface->status;
+
     if (! _cairo_surface_is_paginated (surface))
 	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 
     target = _cairo_paginated_surface_get_target (surface);
+    if (target->status)
+	return target->status;
 
     if (! _cairo_surface_is_pdf (target))
 	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
commit 34d734365bdc1c02cf1880804ab15af48c8d03e1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Mar 31 11:27:10 2008 +0100

    [cairo-svg-surface] Release acquired surface on error path.
    
    Ensure the surface returned from _cairo_pattern_acquire_surface() is
    released on the error path.

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 951068b..c218bc5 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -956,7 +956,7 @@ static cairo_status_t
 _cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t   *output,
 						 cairo_svg_surface_t	 *svg_surface,
 						 cairo_surface_pattern_t *pattern,
-						 int	 		  pattern_id,
+						 int			  pattern_id,
 						 const cairo_matrix_t	 *parent_matrix,
 						 const char		 *extra_attributes)
 {
@@ -975,7 +975,7 @@ _cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t   *output
 
     status = _cairo_surface_get_extents (surface, &extents);
     if (status)
-	return status;
+	goto FAIL;
 
     p2u = pattern->base.matrix;
     status = cairo_matrix_invert (&p2u);
@@ -1012,6 +1012,7 @@ _cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t   *output
     if (pattern_id != invalid_pattern_id)
 	_cairo_output_stream_printf (output, "</pattern>\n");
 
+  FAIL:
     _cairo_pattern_release_surface ((cairo_pattern_t *)pattern,
 				    surface, &surface_attr);
 
commit ba2e82d138eecb451c3d0bf53d9c349fb560f039
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Mar 31 10:55:39 2008 +0100

    [cairo-ps-surface] Check error status before potential illegal dereference.
    
    After acquiring the source image, check for the error status to ensure
    that we do not attempt to deference an invalid surface.

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 1ae2158..a197ff9 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -2142,17 +2142,23 @@ _cairo_ps_surface_acquire_surface (cairo_ps_surface_t      *surface,
 	cairo_rectangle_int_t pattern_extents;
 
 	status = _cairo_surface_get_extents (meta_surface, &pattern_extents);
+	if (status)
+	    return status;
+
 	*width = pattern_extents.width;
 	*height = pattern_extents.height;
     } else {
 	status = _cairo_surface_acquire_source_image (pattern->surface,
 						      &surface->image,
 						      &surface->image_extra);
+	if (status)
+	    return status;
+
 	*width = surface->image->width;
 	*height = surface->image->height;
     }
 
-    return status;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
commit 767add1ee356660075aaf02283f62a23ef9bcb24
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Mar 28 11:51:13 2008 +0000

    [cairo-pdf-operators] Destroy stream on error.
    
    We cannot guarantee that a newly created error stream is a static error
    object, so we need to always destroy the stream on the error path. (One
    day this may change with the global pool of error objects...)

diff --git a/src/cairo-pdf-operators.c b/src/cairo-pdf-operators.c
index 9bf577f..1dbb08c 100644
--- a/src/cairo-pdf-operators.c
+++ b/src/cairo-pdf-operators.c
@@ -371,7 +371,7 @@ _cairo_pdf_path_rectangle (pdf_path_info_t *info, cairo_box_t *box)
  * the stroke workaround will not modify the path being emitted.
  */
 static cairo_status_t
-_cairo_pdf_operators_emit_path (cairo_pdf_operators_t 	*pdf_operators,
+_cairo_pdf_operators_emit_path (cairo_pdf_operators_t	*pdf_operators,
 				cairo_path_fixed_t      *path,
 				cairo_matrix_t          *path_transform,
 				cairo_line_cap_t         line_cap)
@@ -384,7 +384,7 @@ _cairo_pdf_operators_emit_path (cairo_pdf_operators_t 	*pdf_operators,
     word_wrap = _word_wrap_stream_create (pdf_operators->stream, 72);
     status = _cairo_output_stream_get_status (word_wrap);
     if (status)
-	return status;
+	return _cairo_output_stream_destroy (word_wrap);
 
     info.output = word_wrap;
     info.path_transform = path_transform;
@@ -794,7 +794,7 @@ _cairo_pdf_operators_show_glyphs (cairo_pdf_operators_t		*pdf_operators,
     word_wrap_stream = _word_wrap_stream_create (pdf_operators->stream, 72);
     status = _cairo_output_stream_get_status (word_wrap_stream);
     if (status)
-	return status;
+	return _cairo_output_stream_destroy (word_wrap_stream);
 
     _cairo_output_stream_printf (word_wrap_stream,
 				 "BT\n");


More information about the cairo-commit mailing list