summaryrefslogtreecommitdiff
path: root/pdf/pdf_interpret.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2012-01-13 17:58:19 +0000
committerRobin Watts <robin.watts@artifex.com>2012-01-13 17:58:19 +0000
commitb0dd445c76ec8d36648c9f8c9c10b738e963908e (patch)
tree66d06f41ea6887e554223cd96a0cb00128cfdd20 /pdf/pdf_interpret.c
parentb203c82007a8f5e321e2e2b74b8b3ee58a425ba5 (diff)
downloadmupdf-b0dd445c76ec8d36648c9f8c9c10b738e963908e.tar.xz
Avoid infinite loops with XObjects.
Every xobject keeps a reference to the object from whence it came. This is marked/unmarked as it is executed. Thanks to Zeniko for spotting the potential problem.
Diffstat (limited to 'pdf/pdf_interpret.c')
-rw-r--r--pdf/pdf_interpret.c51
1 files changed, 31 insertions, 20 deletions
diff --git a/pdf/pdf_interpret.c b/pdf/pdf_interpret.c
index 0cfcdfae..2cfa5d99 100644
--- a/pdf/pdf_interpret.c
+++ b/pdf/pdf_interpret.c
@@ -1275,24 +1275,31 @@ static void
pdf_run_xobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj, fz_matrix transform)
{
fz_context *ctx = csi->dev->ctx;
- pdf_gstate *gstate;
+ pdf_gstate *gstate = NULL;
fz_matrix oldtopctm;
- int oldtop;
+ int oldtop = 0;
int popmask;
- int caught = 0;
-
- pdf_gsave(csi);
- gstate = csi->gstate + csi->gtop;
- oldtop = csi->gtop;
- popmask = 0;
+ /* Avoid infinite recursion */
+ if (xobj == NULL || fz_dict_mark(xobj->me))
+ return;
- /* apply xobject's transform matrix */
- transform = fz_concat(xobj->matrix, transform);
- gstate->ctm = fz_concat(transform, gstate->ctm);
+ fz_var(gstate);
+ fz_var(oldtop);
+ fz_var(popmask);
fz_try(ctx)
{
+ pdf_gsave(csi);
+
+ gstate = csi->gstate + csi->gtop;
+ oldtop = csi->gtop;
+ popmask = 0;
+
+ /* apply xobject's transform matrix */
+ transform = fz_concat(xobj->matrix, transform);
+ gstate->ctm = fz_concat(transform, gstate->ctm);
+
/* apply soft mask, create transparency group and reset state */
if (xobj->transparency)
{
@@ -1343,20 +1350,24 @@ pdf_run_xobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj, fz_matrix tr
pdf_run_buffer(csi, resources, xobj->contents);
/* RJW: "cannot interpret XObject stream" */
}
- fz_catch(ctx)
+ fz_always(ctx)
{
- caught = 1;
- }
-
- csi->top_ctm = oldtopctm;
+ if (gstate)
+ {
+ csi->top_ctm = oldtopctm;
- while (oldtop < csi->gtop)
- pdf_grestore(csi);
+ while (oldtop < csi->gtop)
+ pdf_grestore(csi);
- pdf_grestore(csi);
+ pdf_grestore(csi);
+ }
- if (caught)
+ fz_dict_unmark(xobj->me);
+ }
+ fz_catch(ctx)
+ {
fz_rethrow(ctx);
+ }
/* wrap up transparency stacks */
if (xobj->transparency)