From 73dc2c4e272f52dfffb2c268f4e8ee5ff0d57639 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 23 Nov 2011 12:05:43 +0000 Subject: [PATCH] image: Only unwrap a subsurface if the sample is fully contained In order to handle out-of-bounds sampling of a subsurface target we need to first avoid incorrectly unwrapping it. Fixes crash in subsurface-outside-target Signed-off-by: Chris Wilson --- src/cairo-image-source.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/cairo-image-source.c b/src/cairo-image-source.c index fde4475db..646c20afc 100644 --- a/src/cairo-image-source.c +++ b/src/cairo-image-source.c @@ -767,7 +767,6 @@ _pixman_image_for_surface (cairo_image_surface_t *dst, #if PIXMAN_HAS_ATOMIC_OPS /* avoid allocating a 'pattern' image if we can reuse the original */ - *ix = *iy = 0; if (extend == CAIRO_EXTEND_NONE && _cairo_matrix_is_pixman_translation (&pattern->base.matrix, pattern->base.filter, @@ -826,23 +825,26 @@ _pixman_image_for_surface (cairo_image_surface_t *dst, /* Avoid sub-byte offsets, force a copy in that case. */ if (PIXMAN_FORMAT_BPP (source->pixman_format) >= 8) { - void *data = source->data - + sub->extents.x * PIXMAN_FORMAT_BPP(source->pixman_format)/8 - + sub->extents.y * source->stride; - pixman_image = pixman_image_create_bits (source->pixman_format, - sub->extents.width, - sub->extents.height, - data, - source->stride); - if (unlikely (pixman_image == NULL)) - return NULL; + if (is_contained) { + void *data = source->data + + sub->extents.x * PIXMAN_FORMAT_BPP(source->pixman_format)/8 + + sub->extents.y * source->stride; + pixman_image = pixman_image_create_bits (source->pixman_format, + sub->extents.width, + sub->extents.height, + data, + source->stride); + if (unlikely (pixman_image == NULL)) + return NULL; + } else { + /* XXX for a simple translation and EXTEND_NONE we can + * fix up the pattern matrix instead. + */ + } } } } -#if PIXMAN_HAS_ATOMIC_OPS - *ix = *iy = 0; -#endif if (pixman_image == NULL) { struct acquire_source_cleanup *cleanup; cairo_image_surface_t *image;