summaryrefslogtreecommitdiff
path: root/src/cairo-composite-rectangles.c
diff options
context:
space:
mode:
authorHeiko Lewin <hlewin@gmx.de>2021-08-01 11:10:40 +0000
committerHeiko Lewin <hlewin@gmx.de>2021-08-01 11:10:40 +0000
commit7176cc8f0f8600185a6480d3117892742007e368 (patch)
tree8220834492025c6d74f444c8c9326cf13e2f417c /src/cairo-composite-rectangles.c
parentd88dd1794e17c1ef9c63dd8c1adf54c7f7c89811 (diff)
downloadcairo-7176cc8f0f8600185a6480d3117892742007e368.tar.gz
Fix clip leak
Diffstat (limited to 'src/cairo-composite-rectangles.c')
-rw-r--r--src/cairo-composite-rectangles.c83
1 files changed, 66 insertions, 17 deletions
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