[cairo-commit] 2 commits - src/cairo-composite-rectangles.c

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun Aug 1 11:10:42 UTC 2021


 src/cairo-composite-rectangles.c |   83 +++++++++++++++++++++++++++++++--------
 1 file changed, 66 insertions(+), 17 deletions(-)

New commits:
commit 6a916648d5dde42236b8ee55b1a40e78ef732b27
Merge: d88dd1794 7176cc8f0
Author: Heiko Lewin <hlewin at gmx.de>
Date:   Sun Aug 1 11:10:40 2021 +0000

    Merge branch 'fix_clip_leak' into 'master'
    
    Fix clip leak
    
    See merge request cairo/cairo!158

commit 7176cc8f0f8600185a6480d3117892742007e368
Author: Heiko Lewin <hlewin at gmx.de>
Date:   Sun Aug 1 11:10:40 2021 +0000

    Fix clip leak

diff --git a/src/cairo-composite-rectangles.c b/src/cairo-composite-rectangles.c
index f102eddbc..10f30da92 100644
--- a/src/cairo-composite-rectangles.c
+++ b/src/cairo-composite-rectangles.c
@@ -44,7 +44,11 @@
 
 void _cairo_composite_rectangles_fini (cairo_composite_rectangles_t *extents)
 {
+    /* If adding further free() code here, make sure those fields are inited by
+     * _cairo_composite_rectangles_init IN ALL CASES
+     */
     _cairo_clip_destroy (extents->clip);
+    extents->clip = NULL;
 }
 
 static void
@@ -76,14 +80,16 @@ _cairo_composite_rectangles_init (cairo_composite_rectangles_t *extents,
 				  const cairo_pattern_t *source,
 				  const cairo_clip_t *clip)
 {
+    /* Always set the clip so that a _cairo_composite_rectangles_init can ALWAYS be
+     * balanced by a _cairo_composite_rectangles_fini */
+    extents->clip = NULL;
+
     if (_cairo_clip_is_all_clipped (clip))
 	return FALSE;
-
     extents->surface = surface;
     extents->op = op;
 
     _cairo_surface_get_extents (surface, &extents->destination);
-    extents->clip = NULL;
 
     extents->unbounded = extents->destination;
     if (clip && ! _cairo_rectangle_intersect (&extents->unbounded,
@@ -122,25 +128,28 @@ _cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extent
     if (! _cairo_composite_rectangles_init (extents,
 					    surface, op, source, clip))
     {
-	return CAIRO_INT_STATUS_NOTHING_TO_DO;
+	goto NOTHING_TO_DO;
     }
 
     extents->mask = extents->destination;
 
     extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
     if (_cairo_clip_is_all_clipped (extents->clip))
-	return CAIRO_INT_STATUS_NOTHING_TO_DO;
+	goto NOTHING_TO_DO;
 
     if (! _cairo_rectangle_intersect (&extents->unbounded,
 				      _cairo_clip_get_extents (extents->clip)))
-	return CAIRO_INT_STATUS_NOTHING_TO_DO;
+	goto NOTHING_TO_DO;
 
     if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID)
 	_cairo_pattern_sampled_area (&extents->source_pattern.base,
 				     &extents->bounded,
 				     &extents->source_sample_area);
 
-    return CAIRO_STATUS_SUCCESS;
+    return CAIRO_INT_STATUS_SUCCESS;
+NOTHING_TO_DO:
+    _cairo_composite_rectangles_fini(extents);
+    return CAIRO_INT_STATUS_NOTHING_TO_DO;
 }
 
 static cairo_int_status_t
@@ -188,7 +197,7 @@ _cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents,
 	}
     }
 
-    return CAIRO_STATUS_SUCCESS;
+    return CAIRO_INT_STATUS_SUCCESS;
 }
 
 cairo_int_status_t
@@ -323,9 +332,11 @@ _cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents
 					   const cairo_pattern_t	*mask,
 					   const cairo_clip_t		*clip)
 {
+    cairo_int_status_t status;
     if (! _cairo_composite_rectangles_init (extents,
 					    surface, op, source, clip))
     {
+	_cairo_composite_rectangles_fini(extents);
 	return CAIRO_INT_STATUS_NOTHING_TO_DO;
     }
 
@@ -333,7 +344,11 @@ _cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents
     _cairo_composite_reduce_pattern (mask, &extents->mask_pattern);
     _cairo_pattern_get_extents (&extents->mask_pattern.base, &extents->mask, surface->is_vector);
 
-    return _cairo_composite_rectangles_intersect (extents, clip);
+    status = _cairo_composite_rectangles_intersect (extents, clip);
+    if(status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
+	_cairo_composite_rectangles_fini(extents);
+    }
+    return status;
 }
 
 cairo_int_status_t
@@ -346,15 +361,21 @@ _cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *exten
 					     const cairo_matrix_t	*ctm,
 					     const cairo_clip_t		*clip)
 {
+    cairo_int_status_t status;
     if (! _cairo_composite_rectangles_init (extents,
 					    surface, op, source, clip))
     {
+	_cairo_composite_rectangles_fini(extents);
 	return CAIRO_INT_STATUS_NOTHING_TO_DO;
     }
 
     _cairo_path_fixed_approximate_stroke_extents (path, style, ctm, surface->is_vector, &extents->mask);
 
-    return _cairo_composite_rectangles_intersect (extents, clip);
+    status = _cairo_composite_rectangles_intersect (extents, clip);
+    if(status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
+	_cairo_composite_rectangles_fini(extents);
+    }
+    return status;
 }
 
 cairo_int_status_t
@@ -365,15 +386,21 @@ _cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents
 					   const cairo_path_fixed_t		*path,
 					   const cairo_clip_t		*clip)
 {
+    cairo_int_status_t status;
     if (! _cairo_composite_rectangles_init (extents,
 					    surface, op, source, clip))
     {
+	_cairo_composite_rectangles_fini(extents);
 	return CAIRO_INT_STATUS_NOTHING_TO_DO;
     }
 
     _cairo_path_fixed_approximate_fill_extents (path, &extents->mask);
 
-    return _cairo_composite_rectangles_intersect (extents, clip);
+    status = _cairo_composite_rectangles_intersect (extents, clip);
+        if(status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
+    _cairo_composite_rectangles_fini(extents);
+    }
+    return status;
 }
 
 cairo_int_status_t
@@ -384,14 +411,20 @@ _cairo_composite_rectangles_init_for_polygon (cairo_composite_rectangles_t *exte
 					      const cairo_polygon_t	*polygon,
 					      const cairo_clip_t		*clip)
 {
+    cairo_int_status_t status;
     if (! _cairo_composite_rectangles_init (extents,
 					    surface, op, source, clip))
     {
+	_cairo_composite_rectangles_fini(extents);
 	return CAIRO_INT_STATUS_NOTHING_TO_DO;
     }
 
     _cairo_box_round_to_rectangle (&polygon->extents, &extents->mask);
-    return _cairo_composite_rectangles_intersect (extents, clip);
+    status = _cairo_composite_rectangles_intersect (extents, clip);
+    if(status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
+	_cairo_composite_rectangles_fini(extents);
+    }
+    return status;
 }
 
 cairo_int_status_t
@@ -403,16 +436,22 @@ _cairo_composite_rectangles_init_for_boxes (cairo_composite_rectangles_t *extent
 					      const cairo_clip_t		*clip)
 {
     cairo_box_t box;
+    cairo_int_status_t status;
 
     if (! _cairo_composite_rectangles_init (extents,
 					    surface, op, source, clip))
     {
+	_cairo_composite_rectangles_fini(extents);
 	return CAIRO_INT_STATUS_NOTHING_TO_DO;
     }
 
     _cairo_boxes_extents (boxes, &box);
     _cairo_box_round_to_rectangle (&box, &extents->mask);
-    return _cairo_composite_rectangles_intersect (extents, clip);
+    status = _cairo_composite_rectangles_intersect (extents, clip);
+    if(status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
+	_cairo_composite_rectangles_fini(extents);
+    }
+    return status;
 }
 
 cairo_int_status_t
@@ -427,9 +466,12 @@ _cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *exten
 					     cairo_bool_t		*overlap)
 {
     cairo_status_t status;
+    cairo_int_status_t int_status;
 
-    if (! _cairo_composite_rectangles_init (extents, surface, op, source, clip))
+    if (! _cairo_composite_rectangles_init (extents, surface, op, source, clip)) {
+	_cairo_composite_rectangles_fini(extents);
 	return CAIRO_INT_STATUS_NOTHING_TO_DO;
+    }
 
     /* Computing the exact bbox and the overlap is expensive.
      * First perform a cheap test to see if the glyphs are all clipped out.
@@ -439,17 +481,20 @@ _cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *exten
 						      glyphs, num_glyphs,
 						      &extents->mask))
     {
-	if (! _cairo_rectangle_intersect (&extents->bounded, &extents->mask))
+	if (! _cairo_rectangle_intersect (&extents->bounded, &extents->mask)) {
+	    _cairo_composite_rectangles_fini(extents);
 	    return CAIRO_INT_STATUS_NOTHING_TO_DO;
+	}
     }
 
     status = _cairo_scaled_font_glyph_device_extents (scaled_font,
 						      glyphs, num_glyphs,
 						      &extents->mask,
 						      overlap);
-    if (unlikely (status))
+    if (unlikely (status)) {
+	_cairo_composite_rectangles_fini(extents);
 	return status;
-
+    }
     if (overlap && *overlap &&
 	scaled_font->options.antialias == CAIRO_ANTIALIAS_NONE &&
 	_cairo_pattern_is_opaque_solid (&extents->source_pattern.base))
@@ -457,7 +502,11 @@ _cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *exten
 	*overlap = FALSE;
     }
 
-    return _cairo_composite_rectangles_intersect (extents, clip);
+    int_status = _cairo_composite_rectangles_intersect (extents, clip);
+    if (int_status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
+	_cairo_composite_rectangles_fini(extents);
+    }
+    return int_status;
 }
 
 cairo_bool_t


More information about the cairo-commit mailing list