summaryrefslogtreecommitdiff
path: root/pdf
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2012-11-29 17:21:36 +0000
committerRobin Watts <robin.watts@artifex.com>2012-11-30 13:25:53 +0000
commit5c5a13b31da451e47fe2df48aacf1d00377aaf64 (patch)
tree2c8a3f4f58ae4c14f7724c838d8067bec150a358 /pdf
parenta6b0a8273f2eb15fd5924501b6ad03e30f2c8d0a (diff)
downloadmupdf-5c5a13b31da451e47fe2df48aacf1d00377aaf64.tar.xz
Bug 693290: Fix for potential infinite recursion reading xrefs.
Fix an issue spotted by zeniko. The patch is slightly modified from his supplied one to avoid problems with repeated freeing of the buffer, and to avoid abusing fz_buffer, but is largely based on his work. Many thanks.
Diffstat (limited to 'pdf')
-rw-r--r--pdf/pdf_xref.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/pdf/pdf_xref.c b/pdf/pdf_xref.c
index 5182a263..4f19428d 100644
--- a/pdf/pdf_xref.c
+++ b/pdf/pdf_xref.c
@@ -422,8 +422,17 @@ pdf_read_xref(pdf_document *xref, int ofs, pdf_lexbuf *buf)
return trailer;
}
+typedef struct ofs_list_s ofs_list;
+
+struct ofs_list_s
+{
+ int max;
+ int len;
+ int *list;
+};
+
static void
-pdf_read_xref_sections(pdf_document *xref, int ofs, pdf_lexbuf *buf)
+do_read_xref_sections(pdf_document *xref, int ofs, pdf_lexbuf *buf, ofs_list *offsets)
{
pdf_obj *trailer = NULL;
fz_context *ctx = xref->ctx;
@@ -438,6 +447,25 @@ pdf_read_xref_sections(pdf_document *xref, int ofs, pdf_lexbuf *buf)
{
do
{
+ int i;
+ /* Avoid potential infinite recursion */
+ for (i = 0; i < offsets->len; i ++)
+ {
+ if (offsets->list[i] == ofs)
+ break;
+ }
+ if (i < offsets->len)
+ {
+ fz_warn(ctx, "ignoring xref recursion with offset %d", ofs);
+ break;
+ }
+ if (offsets->len == offsets->max)
+ {
+ offsets->list = fz_resize_array(ctx, offsets->list, offsets->max*2, sizeof(int));
+ offsets->max *= 2;
+ }
+ offsets->list[offsets->len++] = ofs;
+
trailer = pdf_read_xref(xref, ofs, buf);
/* FIXME: do we overwrite free entries properly? */
@@ -452,7 +480,7 @@ pdf_read_xref_sections(pdf_document *xref, int ofs, pdf_lexbuf *buf)
/* We only recurse if we have both xrefstm and prev.
* Hopefully this happens infrequently. */
if (xrefstmofs && prevofs)
- pdf_read_xref_sections(xref, xrefstmofs, buf);
+ do_read_xref_sections(xref, xrefstmofs, buf, offsets);
if (prevofs)
ofs = prevofs;
else if (xrefstmofs)
@@ -469,6 +497,29 @@ pdf_read_xref_sections(pdf_document *xref, int ofs, pdf_lexbuf *buf)
}
}
+static void
+pdf_read_xref_sections(pdf_document *xref, int ofs, pdf_lexbuf *buf)
+{
+ fz_context *ctx = xref->ctx;
+ ofs_list list;
+
+ list.len = 0;
+ list.max = 10;
+ list.list = fz_malloc_array(ctx, 10, sizeof(int));
+ fz_try(ctx)
+ {
+ do_read_xref_sections(xref, ofs, buf, &list);
+ }
+ fz_always(ctx)
+ {
+ fz_free(ctx, list.list);
+ }
+ fz_catch(ctx)
+ {
+ fz_rethrow(ctx);
+ }
+}
+
/*
* load xref tables from pdf
*