diff options
author | Robin Watts <robin.watts@artifex.com> | 2012-11-29 17:21:36 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2012-11-30 13:25:53 +0000 |
commit | 5c5a13b31da451e47fe2df48aacf1d00377aaf64 (patch) | |
tree | 2c8a3f4f58ae4c14f7724c838d8067bec150a358 /pdf | |
parent | a6b0a8273f2eb15fd5924501b6ad03e30f2c8d0a (diff) | |
download | mupdf-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.c | 55 |
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 * |