summaryrefslogtreecommitdiff
path: root/pdf/pdf_xref.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2012-01-13 19:31:14 +0000
committerRobin Watts <robin.watts@artifex.com>2012-01-13 20:13:09 +0000
commite5213366409d28029cfa137f2c19d6ab4a828c4a (patch)
tree943a09dbf0c30770a638b0c3634a2ccc53f0c009 /pdf/pdf_xref.c
parentb0dd445c76ec8d36648c9f8c9c10b738e963908e (diff)
downloadmupdf-e5213366409d28029cfa137f2c19d6ab4a828c4a.tar.xz
Rework pdf_resolve_indirect to make it idempotent.
pdf_resolve_indirect(x) = pdf_resolve_indirect(pdf_resolve_indirect(x)) now - as long as it doesn't throw an exception. Update the rest of the code to minimise unnecessary function calls. Previously, we were calling one function to find out if an object was a dict, only for that to call a function to see if it needed to resolve the object, then calling another function to actually get the dict, only to have that call the function to check for the dict needing resolving again!
Diffstat (limited to 'pdf/pdf_xref.c')
-rw-r--r--pdf/pdf_xref.c42
1 files changed, 24 insertions, 18 deletions
diff --git a/pdf/pdf_xref.c b/pdf/pdf_xref.c
index bd13d07a..2411c21e 100644
--- a/pdf/pdf_xref.c
+++ b/pdf/pdf_xref.c
@@ -1023,29 +1023,35 @@ fz_obj *
pdf_resolve_indirect(fz_obj *ref)
{
int sanity = 10;
+ int num;
+ int gen;
+ fz_context *ctx = NULL; /* Avoid warning for stupid compilers */
+ pdf_xref *xref;
- while (fz_is_indirect(ref) && sanity--)
+ while (fz_is_indirect(ref))
{
- pdf_xref *xref = fz_get_indirect_xref(ref);
- if (xref)
+ if (--sanity == 0)
+ fz_throw(ctx, "Too many indirections (possible indirection cycle involving %d %d R)", num, gen);
+ xref = fz_get_indirect_xref(ref);
+ if (!xref)
+ return NULL;
+ ctx = xref->ctx;
+ num = fz_to_num(ref);
+ gen = fz_to_gen(ref);
+ fz_try(ctx)
{
- int num = fz_to_num(ref);
- int gen = fz_to_gen(ref);
- fz_context *ctx = xref->ctx;
- fz_try(ctx)
- {
- pdf_cache_object(xref, num, gen);
- }
- fz_catch(ctx)
- {
- fz_warn(ctx, "cannot load object (%d %d R) into cache", num, gen);
- return ref;
- }
- if (!xref->table[num].obj)
- return ref;
- ref = xref->table[num].obj;
+ pdf_cache_object(xref, num, gen);
+ }
+ fz_catch(ctx)
+ {
+ fz_warn(ctx, "cannot load object (%d %d R) into cache", num, gen);
+ return NULL;
}
+ if (!xref->table[num].obj)
+ return NULL;
+ ref = xref->table[num].obj;
}
+
return ref;
}