diff options
author | Heiko Lewin <hlewin@gmx.de> | 2021-08-01 11:10:40 +0000 |
---|---|---|
committer | Heiko Lewin <hlewin@gmx.de> | 2021-08-01 11:10:40 +0000 |
commit | 7176cc8f0f8600185a6480d3117892742007e368 (patch) | |
tree | 8220834492025c6d74f444c8c9326cf13e2f417c /src/cairo-composite-rectangles.c | |
parent | d88dd1794e17c1ef9c63dd8c1adf54c7f7c89811 (diff) | |
download | cairo-7176cc8f0f8600185a6480d3117892742007e368.tar.gz |
Fix clip leak
Diffstat (limited to 'src/cairo-composite-rectangles.c')
-rw-r--r-- | src/cairo-composite-rectangles.c | 83 |
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 |