summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pdf/mupdf.h1
-rw-r--r--pdf/pdf_interpret.c51
-rw-r--r--pdf/pdf_page.c2
-rw-r--r--pdf/pdf_xobject.c3
4 files changed, 36 insertions, 21 deletions
diff --git a/pdf/mupdf.h b/pdf/mupdf.h
index 1ec9d4f2..fa7cd2f8 100644
--- a/pdf/mupdf.h
+++ b/pdf/mupdf.h
@@ -211,6 +211,7 @@ struct pdf_xobject_s
fz_colorspace *colorspace;
fz_obj *resources;
fz_buffer *contents;
+ fz_obj *me;
};
pdf_xobject *pdf_load_xobject(pdf_xref *xref, fz_obj *obj);
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)
diff --git a/pdf/pdf_page.c b/pdf/pdf_page.c
index 536cd5ac..7ccf78a3 100644
--- a/pdf/pdf_page.c
+++ b/pdf/pdf_page.c
@@ -66,7 +66,7 @@ pdf_load_page_tree_node(pdf_xref *xref, fz_obj *node, struct info info)
pdf_load_page_tree_node(xref, obj, info);
}
}
- else
+ else if (fz_is_dict(node))
{
dict = fz_resolve_indirect(node);
diff --git a/pdf/pdf_xobject.c b/pdf/pdf_xobject.c
index b56996cd..61daf9a4 100644
--- a/pdf/pdf_xobject.c
+++ b/pdf/pdf_xobject.c
@@ -24,6 +24,7 @@ pdf_free_xobject_imp(fz_context *ctx, fz_storable *xobj_)
fz_drop_obj(xobj->resources);
if (xobj->contents)
fz_drop_buffer(ctx, xobj->contents);
+ fz_drop_obj(xobj->me);
fz_free(ctx, xobj);
}
@@ -52,6 +53,7 @@ pdf_load_xobject(pdf_xref *xref, fz_obj *dict)
form->resources = NULL;
form->contents = NULL;
form->colorspace = NULL;
+ form->me = NULL;
/* Store item immediately, to avoid possible recursion if objects refer back to this one */
fz_store_item(ctx, dict, form, pdf_xobject_size(form));
@@ -104,6 +106,7 @@ pdf_load_xobject(pdf_xref *xref, fz_obj *dict)
pdf_drop_xobject(ctx, form);
fz_throw(ctx, "cannot load xobject content stream (%d %d R)", fz_to_num(dict), fz_to_gen(dict));
}
+ form->me = fz_keep_obj(dict);
return form;
}