From 2f1b581f54713c899f3b03af1e0ac8c38c36c385 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Thu, 11 Dec 2008 10:34:37 -0500 Subject: [PATCH] [quartz] Create a copy instead of increasing the reference The pattern could be stack allocated so we can't take a reference to it. Some testing of quartz shows that it doesn't deal with malloc failure particularily well. In the best case CGFunctionCreate returns NULL, in the worst case it just crashes. Quartz does seem to be able to handle a NULL CGFunctionRef, so returning NULL if we fail to copy the pattern avoids complicating the code to deal with propagating the failure and shouldn't cause any additional crashes. Based on a patch by Paolo Bonzini. --- src/cairo-quartz-surface.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c index 9dc5eaae4..34661853c 100644 --- a/src/cairo-quartz-surface.c +++ b/src/cairo-quartz-surface.c @@ -682,13 +682,19 @@ ComputeGradientValue (void *info, const float *in, float *out) static CGFunctionRef CreateGradientFunction (const cairo_gradient_pattern_t *gpat) { + cairo_pattern_t *pat; float input_value_range[2] = { 0.f, 1.f }; float output_value_ranges[8] = { 0.f, 1.f, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f }; CGFunctionCallbacks callbacks = { 0, ComputeGradientValue, (CGFunctionReleaseInfoCallback) cairo_pattern_destroy }; - return CGFunctionCreate (cairo_pattern_reference (&gpat->base), + if (_cairo_pattern_create_copy (&pat, &gpat->base)) + /* quartz doesn't deal very well with malloc failing, so there's + * not much point in us trying either */ + return NULL; + + return CGFunctionCreate (pat, 1, input_value_range, 4, @@ -702,6 +708,7 @@ CreateRepeatingGradientFunction (cairo_quartz_surface_t *surface, CGPoint *start, CGPoint *end, CGAffineTransform matrix) { + cairo_pattern_t *pat; float input_value_range[2]; float output_value_ranges[8] = { 0.f, 1.f, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f }; CGFunctionCallbacks callbacks = { @@ -766,7 +773,12 @@ CreateRepeatingGradientFunction (cairo_quartz_surface_t *surface, input_value_range[0] = 0.0 - 1.0 * rep_start; input_value_range[1] = 1.0 + 1.0 * rep_end; - return CGFunctionCreate (cairo_pattern_reference (&gpat->base), + if (_cairo_pattern_create_copy (&pat, &gpat->base)) + /* quartz doesn't deal very well with malloc failing, so there's + * not much point in us trying either */ + return NULL; + + return CGFunctionCreate (pat, 1, input_value_range, 4,