From 36352e40109a5393ad23db76a0685df2c4c77889 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 19 Jul 2015 16:03:49 +0100 Subject: [PATCH] script: Plug a memory leak using recording surfaces and vector glyph When we pushed and popped the current context around the use of a recording surface or vector glyph, we neglected to drop any references accrued whilst inside the push-group and so leaked the memory used by the source inside the recording surface etc. Massimo wrote the same patch as me, but without introducing the new context handling functions (which I think help explain the intentions/requirements). Reported-by: Massimo Valentini Signed-off-by: Chris Wilson --- src/cairo-script-surface.c | 52 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/src/cairo-script-surface.c b/src/cairo-script-surface.c index a4cefde..744a3d5 100644 --- a/src/cairo-script-surface.c +++ b/src/cairo-script-surface.c @@ -204,9 +204,20 @@ static void _cairo_script_implicit_context_init (cairo_script_implicit_context_t *cr); static void +_cairo_script_implicit_context_save (cairo_script_implicit_context_t *cr, + cairo_script_implicit_context_t *save); + +static void +_cairo_script_implicit_context_restore (cairo_script_implicit_context_t *cr, + cairo_script_implicit_context_t *save); + +static void _cairo_script_implicit_context_reset (cairo_script_implicit_context_t *cr); static void +_cairo_script_implicit_context_fini (cairo_script_implicit_context_t *cr); + +static void _bitmap_release_id (struct _bitmap *b, unsigned long token) { struct _bitmap **prev = NULL; @@ -1125,7 +1136,7 @@ static cairo_status_t _emit_recording_surface_pattern (cairo_script_surface_t *surface, cairo_recording_surface_t *source) { - cairo_script_implicit_context_t old_cr; + cairo_script_implicit_context_t saved_cr; cairo_script_context_t *ctx = to_context (surface); cairo_script_surface_t *similar; cairo_surface_t *snapshot; @@ -1168,11 +1179,9 @@ _emit_recording_surface_pattern (cairo_script_surface_t *surface, target_push (similar); similar->emitted = TRUE; - - old_cr = surface->cr; - _cairo_script_implicit_context_init (&surface->cr); + _cairo_script_implicit_context_save (&surface->cr, &saved_cr); status = _cairo_recording_surface_replay (&source->base, &similar->base); - surface->cr = old_cr; + _cairo_script_implicit_context_restore(&surface->cr, &saved_cr); if (unlikely (status)) { cairo_surface_destroy (&similar->base); @@ -3018,7 +3027,7 @@ _emit_scaled_glyph_vector (cairo_script_surface_t *surface, cairo_scaled_glyph_t *scaled_glyph) { cairo_script_context_t *ctx = to_context (surface); - cairo_script_implicit_context_t old_cr; + cairo_script_implicit_context_t saved_cr; cairo_status_t status; unsigned long index; @@ -3049,11 +3058,10 @@ _emit_scaled_glyph_vector (cairo_script_surface_t *surface, scaled_font->scale_inverse.y0); } - old_cr = surface->cr; - _cairo_script_implicit_context_init (&surface->cr); + _cairo_script_implicit_context_save (&surface->cr, &saved_cr); status = _cairo_recording_surface_replay (scaled_glyph->recording_surface, &surface->base); - surface->cr = old_cr; + _cairo_script_implicit_context_restore (&surface->cr, &saved_cr); _cairo_output_stream_puts (ctx->stream, "} >> set\n"); @@ -3619,15 +3627,37 @@ _cairo_script_implicit_context_init (cairo_script_implicit_context_t *cr) } static void +_cairo_script_implicit_context_save (cairo_script_implicit_context_t *cr, + cairo_script_implicit_context_t *save) +{ + *save = cr; + _cairo_script_implicit_context_init (cr); + +} + +static cairo_status_t +_cairo_script_implicit_context_restore (cairo_script_implicit_context_t *cr, + const cairo_script_implicit_context_t *save) +{ + _cairo_script_implicit_context_fini (cr); + *cr = *save; +} + +static void _cairo_script_implicit_context_reset (cairo_script_implicit_context_t *cr) { + _cairo_script_implicit_context_fini (cr); + _cairo_script_implicit_context_init (cr); +} + +static void +_cairo_script_implicit_context_fini (cairo_script_implicit_context_t *cr) +{ free (cr->current_style.dash); cr->current_style.dash = NULL; _cairo_pattern_fini (&cr->current_source.base); _cairo_path_fixed_fini (&cr->current_path); - - _cairo_script_implicit_context_init (cr); } static cairo_script_surface_t * -- 2.1.4