summaryrefslogtreecommitdiff
path: root/src/cairo-surface-subsurface.c
diff options
context:
space:
mode:
authorAndrea Canciani <ranma42@gmail.com>2010-08-26 14:24:17 +0200
committerAndrea Canciani <ranma42@gmail.com>2010-08-26 14:38:34 +0200
commit72644c6df2c2da1d77ca10a755dbb44bbd960c0d (patch)
treef07bfc77e6790d82ab21818a0f0c23fcb629f530 /src/cairo-surface-subsurface.c
parentdf4465bdd11e25a1ed942bc0fc8e7dc5d43f951f (diff)
downloadcairo-72644c6df2c2da1d77ca10a755dbb44bbd960c0d.tar.gz
subsurface: Avoid invalid accesses
Whenever subsurface extents are not contained in the target extents, using the source image given by the target (with origin corrected by using an appropriate offset in the data pointer) is not a valid operation. Fallback to cloning in that case.
Diffstat (limited to 'src/cairo-surface-subsurface.c')
-rw-r--r--src/cairo-surface-subsurface.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/cairo-surface-subsurface.c b/src/cairo-surface-subsurface.c
index 858777958..9a4cedd1c 100644
--- a/src/cairo-surface-subsurface.c
+++ b/src/cairo-surface-subsurface.c
@@ -281,11 +281,13 @@ _cairo_surface_subsurface_acquire_source_image (void *abstrac
cairo_image_surface_t **image_out,
void **extra_out)
{
+ cairo_rectangle_int_t target_extents;
cairo_surface_subsurface_t *surface = abstract_surface;
cairo_image_surface_t *image;
cairo_status_t status;
struct extra *extra;
uint8_t *data;
+ cairo_bool_t ret;
if (surface->target->type == CAIRO_SURFACE_TYPE_RECORDING) {
cairo_recording_surface_t *meta = (cairo_recording_surface_t *) surface->target;
@@ -335,8 +337,16 @@ _cairo_surface_subsurface_acquire_source_image (void *abstrac
if (unlikely (status))
goto CLEANUP;
+ ret = _cairo_surface_get_extents (extra->image_extra, &target_extents);
+ assert (ret);
+
/* only copy if we need to perform sub-byte manipulation */
- if (PIXMAN_FORMAT_BPP (extra->image->pixman_format) >= 8) {
+ if (PIXMAN_FORMAT_BPP (extra->image->pixman_format) >= 8 ||
+ surface->extents.x < target_extents.x ||
+ surface->extents.y < target_extents.y ||
+ surface->extents.x + surface->extents.width > target_extents.x + target_extents.width ||
+ surface->extents.y + surface->extents.height > target_extents.y + target_extents.height) {
+
assert ((PIXMAN_FORMAT_BPP (extra->image->pixman_format) % 8) == 0);
data = extra->image->data + surface->extents.y * extra->image->stride;