From 68e31e77a241d2233eeff6b317981b06f209ac67 Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Wed, 19 Oct 2022 14:19:54 +0100 Subject: [PATCH] Explicitly retain pattern surface's CGLayer reference The CGLayer used here is owned by the source pattern surface; if we don't bump its retain count here, then when _cairo_quartz_teardown_state calls CGLayerRelease, we'll be unexpectedly releasing the original pattern's reference. The test suite doesn't appear to hit this code path, but I believe the current code has the potential for a double-release of the pattern's CGLayer. (An alternative fix would be to put the call to CGLayerRelease inside the !DO_LAYER conditional in the teardown function. But in principle it seems like holding a strong reference is the right thing to do.) --- src/cairo-quartz-surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c index 6676dc960..3e7228300 100644 --- a/src/cairo-quartz-surface.c +++ b/src/cairo-quartz-surface.c @@ -1007,6 +1007,7 @@ _cairo_quartz_setup_pattern_source (cairo_quartz_drawing_state_t *state, _cairo_quartz_cairo_matrix_to_quartz (&m, &state->transform); state->rect = CGRectMake (0, 0, quartz_surf->extents.width, quartz_surf->extents.height); state->layer = quartz_surf->cgLayer; + CGLayerRetain (state->layer); // Will be released by _cairo_quartz_teardown_state state->action = DO_LAYER; return CAIRO_STATUS_SUCCESS; } @@ -1174,7 +1175,6 @@ _cairo_quartz_setup_state (cairo_quartz_drawing_state_t *state, state->shading = NULL; state->cgDrawContext = NULL; state->cgMaskContext = NULL; - state->layer = NULL; status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); if (unlikely (status))