summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin@peeved.(none)>2014-01-17 11:16:32 -0800
committerRobin Watts <robin.watts@artifex.com>2014-01-17 23:57:50 +0000
commit01f0a0db15faf4bffaa2556ced74868572dac7f5 (patch)
tree53c523d20be45db2edac3d96e50a8a5b1e4e4a77
parent63869ca1b53eb485dc0c8b5e53679825826ec076 (diff)
downloadmupdf-01f0a0db15faf4bffaa2556ced74868572dac7f5.tar.xz
Bug 694899: Avoid using invalid gstate pointer.
When we call pdf_begin_group, this can go away and do lots of drawing. This can result in the gstate stack growing, which can involve a realloc. Any gstate pointer we are holding must therefore be recalculated after such a call. The neatest way to do this is to get pdf_begin_group to return the gstate pointer, thus making it hard to forget to do. This solves: e2a1dda5393f4cb8a446fd8edd9d94f9_asan_heap-uaf_b938cf_2075_2393.pdf Thanks to Mateusz Jurczyk and Gynvael Coldwind of the Google Security Team for providing the example files.
-rw-r--r--source/pdf/pdf-interpret.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/source/pdf/pdf-interpret.c b/source/pdf/pdf-interpret.c
index eeb2f371..52a3a61d 100644
--- a/source/pdf/pdf-interpret.c
+++ b/source/pdf/pdf-interpret.c
@@ -409,13 +409,15 @@ end_softmask(pdf_csi *csi, softmask_save *save)
fz_pop_clip(csi->dev);
}
-static void
+static pdf_gstate *
pdf_begin_group(pdf_csi *csi, const fz_rect *bbox, softmask_save *softmask)
{
pdf_gstate *gstate = begin_softmask(csi, softmask);
if (gstate->blendmode)
fz_begin_group(csi->dev, bbox, 1, 0, gstate->blendmode, 1);
+
+ return csi->gstate + csi->gtop;
}
static void
@@ -442,7 +444,7 @@ pdf_show_shade(pdf_csi *csi, fz_shade *shd)
fz_bound_shade(ctx, shd, &gstate->ctm, &bbox);
- pdf_begin_group(csi, &bbox, &softmask);
+ gstate = pdf_begin_group(csi, &bbox, &softmask);
/* FIXME: The gstate->ctm in the next line may be wrong; maybe
* it should be the parent gstates ctm? */
@@ -477,7 +479,7 @@ pdf_show_image(pdf_csi *csi, fz_image *image)
fz_clip_image_mask(csi->dev, image->mask, &bbox, &image_ctm);
}
else
- pdf_begin_group(csi, &bbox, &softmask);
+ gstate = pdf_begin_group(csi, &bbox, &softmask);
if (!image->colorspace)
{
@@ -567,7 +569,7 @@ pdf_show_path(pdf_csi *csi, int doclose, int dofill, int dostroke, int even_odd)
dostroke = dofill = 0;
if (dofill || dostroke)
- pdf_begin_group(csi, &bbox, &softmask);
+ gstate = pdf_begin_group(csi, &bbox, &softmask);
if (dofill && dostroke)
{
@@ -709,7 +711,7 @@ pdf_flush_text(pdf_csi *csi)
if (text->len == 0)
break;
- pdf_begin_group(csi, &tb, &softmask);
+ gstate = pdf_begin_group(csi, &tb, &softmask);
if (doinvisible)
fz_ignore_text(csi->dev, text, &gstate->ctm);