pkgsrc-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[pkgsrc/trunk]: pkgsrc/graphics/cairo cairo: fix segfault in quartz backend (...
details: https://anonhg.NetBSD.org/pkgsrc/rev/d4fb299639f0
branches: trunk
changeset: 379188:d4fb299639f0
user: tnn <tnn%pkgsrc.org@localhost>
date: Thu May 12 17:13:55 2022 +0000
description:
cairo: fix segfault in quartz backend (via upstream)
diffstat:
graphics/cairo/Makefile | 4 +-
graphics/cairo/distinfo | 4 +-
graphics/cairo/patches/patch-src_cairo-quartz-image-surface.c | 110 ++++++
graphics/cairo/patches/patch-src_cairo-quartz-surface.c | 175 ++++++++++
4 files changed, 290 insertions(+), 3 deletions(-)
diffs (truncated from 324 to 300 lines):
diff -r 65597659357d -r d4fb299639f0 graphics/cairo/Makefile
--- a/graphics/cairo/Makefile Thu May 12 15:45:54 2022 +0000
+++ b/graphics/cairo/Makefile Thu May 12 17:13:55 2022 +0000
@@ -1,8 +1,8 @@
-# $NetBSD: Makefile,v 1.150 2022/04/05 10:06:41 riastradh Exp $
+# $NetBSD: Makefile,v 1.151 2022/05/12 17:13:55 tnn Exp $
.include "../../graphics/cairo/Makefile.common"
-PKGREVISION= 5
+PKGREVISION= 6
TEST_TARGET= check
diff -r 65597659357d -r d4fb299639f0 graphics/cairo/distinfo
--- a/graphics/cairo/distinfo Thu May 12 15:45:54 2022 +0000
+++ b/graphics/cairo/distinfo Thu May 12 17:13:55 2022 +0000
@@ -1,4 +1,4 @@
-$NetBSD: distinfo,v 1.94 2022/04/07 10:57:57 riastradh Exp $
+$NetBSD: distinfo,v 1.95 2022/05/12 17:13:55 tnn Exp $
BLAKE2s (cairo-1.16.0.tar.xz) = fba95926f57ad97d9c0c197c355ef646fd3cf9d17d1eb3270d343eef5d7bfa40
SHA512 (cairo-1.16.0.tar.xz) = 9eb27c4cf01c0b8b56f2e15e651f6d4e52c99d0005875546405b64f1132aed12fbf84727273f493d84056a13105e065009d89e94a8bfaf2be2649e232b82377f
@@ -13,5 +13,7 @@
SHA1 (patch-perf_cairo-perf-trace.c) = 0f8cb89493a202b58b22e6244fe1c1bcc0a34b88
SHA1 (patch-src_cairo-ft-font.c) = 97288d79380473869f1049c1d8955a2f6fa3d178
SHA1 (patch-src_cairo-image-compositor.c) = 83337d8211083d77b061c43b69da2b61080776d9
+SHA1 (patch-src_cairo-quartz-image-surface.c) = f3963afb665d70189c18de02b943313b7f7b6dcd
+SHA1 (patch-src_cairo-quartz-surface.c) = 870ff264a0046adad5a3c93e76da4684d6a365eb
SHA1 (patch-src_cairo-type1-subset.c) = 741de4ec29cc4805aa51cbb4d89947a58dca0646
SHA1 (patch-util_cairo-trace_trace.c) = 0979e99a2aeaeb711a9b7636a0e6ba5048f26077
diff -r 65597659357d -r d4fb299639f0 graphics/cairo/patches/patch-src_cairo-quartz-image-surface.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graphics/cairo/patches/patch-src_cairo-quartz-image-surface.c Thu May 12 17:13:55 2022 +0000
@@ -0,0 +1,110 @@
+$NetBSD: patch-src_cairo-quartz-image-surface.c,v 1.1 2022/05/12 17:13:55 tnn Exp $
+
+Ref and destroy the cairo surface handed off to CoreGraphics.
+https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/52
+
+--- src/cairo-quartz-image-surface.c.orig 2018-08-17 01:10:53.000000000 +0000
++++ src/cairo-quartz-image-surface.c
+@@ -50,10 +50,9 @@
+ #define SURFACE_ERROR_INVALID_FORMAT (_cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_INVALID_FORMAT)))
+
+ static void
+-DataProviderReleaseCallback (void *info, const void *data, size_t size)
++DataProviderReleaseCallback (void *image_info, const void *data, size_t size)
+ {
+- cairo_surface_t *surface = (cairo_surface_t *) info;
+- cairo_surface_destroy (surface);
++ free (image_info);
+ }
+
+ static cairo_surface_t *
+@@ -88,9 +87,8 @@ _cairo_quartz_image_surface_finish (void
+ {
+ cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface;
+
+- /* the imageSurface will be destroyed by the data provider's release callback */
+ CGImageRelease (surface->image);
+-
++ cairo_surface_destroy (surface->imageSurface);
+ return CAIRO_STATUS_SUCCESS;
+ }
+
+@@ -147,24 +145,29 @@ _cairo_quartz_image_surface_flush (void
+ cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface;
+ CGImageRef oldImage = surface->image;
+ CGImageRef newImage = NULL;
+-
++ void *image_data;
++ const unsigned int size = surface->imageSurface->height * surface->imageSurface->stride;
+ if (flags)
+ return CAIRO_STATUS_SUCCESS;
+
+ /* XXX only flush if the image has been modified. */
+
+- /* To be released by the ReleaseCallback */
+- cairo_surface_reference ((cairo_surface_t*) surface->imageSurface);
++ image_data = _cairo_malloc_ab ( surface->imageSurface->height,
++ surface->imageSurface->stride);
++ if (unlikely (!image_data))
++ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
++ memcpy (image_data, surface->imageSurface->data,
++ surface->imageSurface->height * surface->imageSurface->stride);
+ newImage = CairoQuartzCreateCGImage (surface->imageSurface->format,
+ surface->imageSurface->width,
+ surface->imageSurface->height,
+ surface->imageSurface->stride,
+- surface->imageSurface->data,
++ image_data,
+ TRUE,
+ NULL,
+ DataProviderReleaseCallback,
+- surface->imageSurface);
++ image_data);
+
+ surface->image = newImage;
+ CGImageRelease (oldImage);
+@@ -308,7 +311,7 @@ cairo_quartz_image_surface_create (cairo
+ cairo_image_surface_t *image_surface;
+ int width, height, stride;
+ cairo_format_t format;
+- unsigned char *data;
++ void *image_data;
+
+ if (surface->status)
+ return surface;
+@@ -321,7 +324,6 @@ cairo_quartz_image_surface_create (cairo
+ height = image_surface->height;
+ stride = image_surface->stride;
+ format = image_surface->format;
+- data = image_surface->data;
+
+ if (!_cairo_quartz_verify_surface_size(width, height))
+ return SURFACE_ERROR_INVALID_SIZE;
+@@ -338,20 +340,19 @@ cairo_quartz_image_surface_create (cairo
+
+ memset (qisurf, 0, sizeof(cairo_quartz_image_surface_t));
+
+- /* In case the create_cgimage fails, this ref will
+- * be released via the callback (which will be called in
+- * case of failure.)
+- */
+- cairo_surface_reference (surface);
++ image_data = _cairo_malloc_ab (height, stride);
++ if (unlikely (!image_data))
++ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
++ memcpy (image_data, image_surface->data, height * stride);
+ image = CairoQuartzCreateCGImage (format,
+ width, height,
+ stride,
+- data,
++ image_data,
+ TRUE,
+ NULL,
+ DataProviderReleaseCallback,
+- image_surface);
++ image_data);
+
+ if (!image) {
+ free (qisurf);
diff -r 65597659357d -r d4fb299639f0 graphics/cairo/patches/patch-src_cairo-quartz-surface.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graphics/cairo/patches/patch-src_cairo-quartz-surface.c Thu May 12 17:13:55 2022 +0000
@@ -0,0 +1,175 @@
+$NetBSD: patch-src_cairo-quartz-surface.c,v 1.1 2022/05/12 17:13:55 tnn Exp $
+
+Ref and destroy the cairo surface handed off to CoreGraphics.
+https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/52
+
+--- src/cairo-quartz-surface.c.orig 2018-08-17 01:10:53.000000000 +0000
++++ src/cairo-quartz-surface.c
+@@ -778,20 +778,10 @@ CairoQuartzCreateGradientFunction (const
+ &gradient_callbacks);
+ }
+
+-/* Obtain a CGImageRef from a #cairo_surface_t * */
+-
+-typedef struct {
+- cairo_surface_t *surface;
+- cairo_image_surface_t *image_out;
+- void *image_extra;
+-} quartz_source_image_t;
+-
+ static void
+ DataProviderReleaseCallback (void *info, const void *data, size_t size)
+ {
+- quartz_source_image_t *source_img = info;
+- _cairo_surface_release_source_image (source_img->surface, source_img->image_out, source_img->image_extra);
+- free (source_img);
++ free (info);
+ }
+
+ static cairo_status_t
+@@ -803,8 +793,9 @@ _cairo_surface_to_cgimage (cairo_surface
+ CGImageRef *image_out)
+ {
+ cairo_status_t status;
+- quartz_source_image_t *source_img;
+ cairo_image_surface_t *image_surface;
++ void *image_data, *image_extra;
++ cairo_bool_t acquired = FALSE;
+
+ if (source->backend && source->backend->type == CAIRO_SURFACE_TYPE_QUARTZ_IMAGE) {
+ cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) source;
+@@ -826,19 +817,12 @@ _cairo_surface_to_cgimage (cairo_surface
+ }
+ }
+
+- source_img = _cairo_malloc (sizeof (quartz_source_image_t));
+- if (unlikely (source_img == NULL))
+- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+-
+- source_img->surface = source;
+-
+ if (source->type == CAIRO_SURFACE_TYPE_RECORDING) {
+ image_surface = (cairo_image_surface_t *)
+ cairo_image_surface_create (format, extents->width, extents->height);
+ if (unlikely (image_surface->base.status)) {
+ status = image_surface->base.status;
+ cairo_surface_destroy (&image_surface->base);
+- free (source_img);
+ return status;
+ }
+
+@@ -848,46 +832,61 @@ _cairo_surface_to_cgimage (cairo_surface
+ NULL);
+ if (unlikely (status)) {
+ cairo_surface_destroy (&image_surface->base);
+- free (source_img);
+ return status;
+ }
+
+- source_img->image_out = image_surface;
+- source_img->image_extra = NULL;
+-
+ cairo_matrix_init_identity (matrix);
+ }
+ else {
+- status = _cairo_surface_acquire_source_image (source_img->surface,
+- &source_img->image_out,
+- &source_img->image_extra);
+- if (unlikely (status)) {
+- free (source_img);
++ status = _cairo_surface_acquire_source_image (source, &image_surface,
++ &image_extra);
++ if (unlikely (status))
+ return status;
+- }
++ acquired = TRUE;
+ }
+
+- if (source_img->image_out->width == 0 || source_img->image_out->height == 0) {
++ if (image_surface->width == 0 || image_surface->height == 0) {
+ *image_out = NULL;
+- DataProviderReleaseCallback (source_img,
+- source_img->image_out->data,
+- source_img->image_out->height * source_img->image_out->stride);
+- } else {
+- *image_out = CairoQuartzCreateCGImage (source_img->image_out->format,
+- source_img->image_out->width,
+- source_img->image_out->height,
+- source_img->image_out->stride,
+- source_img->image_out->data,
+- TRUE,
+- NULL,
+- DataProviderReleaseCallback,
+- source_img);
+-
+- /* TODO: differentiate memory error and unsupported surface type */
+- if (unlikely (*image_out == NULL))
+- status = CAIRO_INT_STATUS_UNSUPPORTED;
++ if (acquired)
++ _cairo_surface_release_source_image (source, image_surface, image_extra);
++ else
++ cairo_surface_destroy (&image_surface->base);
++
++ return status;
+ }
+
++ image_data = _cairo_malloc_ab (image_surface->height, image_surface->stride);
++ if (unlikely (!image_data))
++ {
++ if (acquired)
++ _cairo_surface_release_source_image (source, image_surface, image_extra);
++ else
++ cairo_surface_destroy (&image_surface->base);
++
++ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
++ }
++
++ memcpy (image_data, image_surface->data,
++ image_surface->height * image_surface->stride);
++ *image_out = CairoQuartzCreateCGImage (image_surface->format,
++ image_surface->width,
++ image_surface->height,
++ image_surface->stride,
++ image_data,
++ TRUE,
++ NULL,
++ DataProviderReleaseCallback,
++ image_data);
++
++ /* TODO: differentiate memory error and unsupported surface type */
++ if (unlikely (*image_out == NULL))
++ status = CAIRO_INT_STATUS_UNSUPPORTED;
++
++ if (acquired)
++ _cairo_surface_release_source_image (source, image_surface, image_extra);
++ else
++ cairo_surface_destroy (&image_surface->base);
++
+ return status;
+ }
+
+@@ -2273,11 +2272,13 @@ _cairo_quartz_surface_create_internal (C
Home |
Main Index |
Thread Index |
Old Index