diff options
author | Robin Watts <robin.watts@artifex.com> | 2012-01-13 17:58:19 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2012-01-13 17:58:19 +0000 |
commit | b0dd445c76ec8d36648c9f8c9c10b738e963908e (patch) | |
tree | 66d06f41ea6887e554223cd96a0cb00128cfdd20 /pdf/pdf_interpret.c | |
parent | b203c82007a8f5e321e2e2b74b8b3ee58a425ba5 (diff) | |
download | mupdf-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.c | 51 |
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) |