summaryrefslogtreecommitdiff
path: root/source/fitz/draw-device.c
diff options
context:
space:
mode:
authorRobin Watts <robin@peeves.(none)>2013-11-27 03:24:43 -0800
committerRobin Watts <robin.watts@artifex.com>2013-11-27 11:28:38 +0000
commita290828ad27a30b894e7bc11f77b612e8cec83a8 (patch)
treea1b28a508a237c910c518cc8c15e210bc5a1b790 /source/fitz/draw-device.c
parentb1ed116091b790223a976eca2381da2875341e10 (diff)
downloadmupdf-a290828ad27a30b894e7bc11f77b612e8cec83a8.tar.xz
Bug 694116: Solve valgrind issues in draw device.
The actual issue here is that a pixmap is dropped more times than it should be due to an error in the rendering pipeline. The problem arises because we fail to push a clip image mask, but still pop the mask off the stack later. This puts us off by 1 in the stack handling. The simplest solution to this (that will be safe no matter what mistakes are made by the caller too) is to add some simple tests in the draw device to ensure we do not free too early.
Diffstat (limited to 'source/fitz/draw-device.c')
-rw-r--r--source/fitz/draw-device.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c
index 9146b3e2..60735460 100644
--- a/source/fitz/draw-device.c
+++ b/source/fitz/draw-device.c
@@ -220,7 +220,11 @@ static void fz_knockout_end(fz_draw_device *dev)
else
fz_blend_pixmap(state[0].dest, state[1].dest, 255, blendmode, isolated, state[1].shape);
- fz_drop_pixmap(dev->ctx, state[1].dest);
+ /* The following test should not be required, but just occasionally
+ * errors can cause the stack to get out of sync, and this saves our
+ * bacon. */
+ if (state[0].dest != state[1].dest)
+ fz_drop_pixmap(dev->ctx, state[1].dest);
if (state[0].shape != state[1].shape)
{
if (state[0].shape)
@@ -1352,8 +1356,13 @@ fz_draw_pop_clip(fz_device *devp)
fz_paint_pixmap_with_mask(state[0].shape, state[1].shape, state[1].mask);
fz_drop_pixmap(dev->ctx, state[1].shape);
}
- fz_drop_pixmap(dev->ctx, state[1].mask);
- fz_drop_pixmap(dev->ctx, state[1].dest);
+ /* The following tests should not be required, but just occasionally
+ * errors can cause the stack to get out of sync, and this might save
+ * our bacon. */
+ if (state[0].mask != state[1].mask)
+ fz_drop_pixmap(dev->ctx, state[1].mask);
+ if (state[0].dest != state[1].dest)
+ fz_drop_pixmap(dev->ctx, state[1].dest);
#ifdef DUMP_GROUP_BLENDS
fz_dump_blend(dev->ctx, state[0].dest, " to get ");
if (state[0].shape)
@@ -1579,7 +1588,11 @@ fz_draw_end_group(fz_device *devp)
else
fz_blend_pixmap(state[0].dest, state[1].dest, alpha * 255, blendmode, isolated, state[1].shape);
- fz_drop_pixmap(dev->ctx, state[1].dest);
+ /* The following test should not be required, but just occasionally
+ * errors can cause the stack to get out of sync, and this might save
+ * our bacon. */
+ if (state[0].dest != state[1].dest)
+ fz_drop_pixmap(dev->ctx, state[1].dest);
if (state[0].shape != state[1].shape)
{
if (state[0].shape)
@@ -1940,8 +1953,13 @@ fz_draw_end_tile(fz_device *devp)
/* Do nothing */
}
- fz_drop_pixmap(dev->ctx, state[1].dest);
- fz_drop_pixmap(dev->ctx, state[1].shape);
+ /* The following tests should not be required, but just occasionally
+ * errors can cause the stack to get out of sync, and this might save
+ * our bacon. */
+ if (state[0].dest != state[1].dest)
+ fz_drop_pixmap(dev->ctx, state[1].dest);
+ if (state[0].shape != state[1].shape)
+ fz_drop_pixmap(dev->ctx, state[1].shape);
#ifdef DUMP_GROUP_BLENDS
fz_dump_blend(dev->ctx, state[0].dest, " to get ");
if (state[0].shape)