diff options
author | Robin Watts <robin.watts@artifex.com> | 2012-01-06 11:38:43 +0000 |
---|---|---|
committer | Robin Watts <robin@ghostscript.com> | 2012-01-06 13:49:24 +0000 |
commit | 09f1a3d3d863099c103100ed10c8cec82ea7aed3 (patch) | |
tree | e5eaa31b5b2efc0c9e9537649e7e681ed428e8c0 /fitz/base_object.c | |
parent | a0203aeba59a207db78a312b9b3aacf97b2802f5 (diff) | |
download | mupdf-09f1a3d3d863099c103100ed10c8cec82ea7aed3.tar.xz |
Add 'marking' functions for dictionaries.
In various places in the code, we add markers (".seen") to
dictionaries as we traverse them to ensure that we don't
go into infinite loops.
Adding a dictionary entry is bad as it's a) an expensive
operation, b) a potentially destructive one, and c) produces another
possible point of failure (as mallocs can fail).
Instead, add a flag to each dict to allow them to be marked/unmarked
and use that instead.
Thanks to Zeniko for pointing out various places that could usefully
be protected against infinite recursion.
Diffstat (limited to 'fitz/base_object.c')
-rw-r--r-- | fitz/base_object.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/fitz/base_object.c b/fitz/base_object.c index 8464a971..41fcbd4b 100644 --- a/fitz/base_object.c +++ b/fitz/base_object.c @@ -41,6 +41,7 @@ struct fz_obj_s } a; struct { char sorted; + char marked; int len; int cap; struct keyval *items; @@ -549,6 +550,7 @@ fz_new_dict(fz_context *ctx, int initialcap) obj->kind = FZ_DICT; obj->u.d.sorted = 0; + obj->u.d.marked = 0; obj->u.d.len = 0; obj->u.d.cap = initialcap > 1 ? initialcap : 10; @@ -642,7 +644,7 @@ fz_dict_get_val(fz_obj *obj, int i) static int fz_dict_finds(fz_obj *obj, char *key, int *location) { - if (obj->u.d.sorted) + if (obj->u.d.sorted && obj->u.d.len > 0) { int l = 0; int r = obj->u.d.len - 1; @@ -763,7 +765,7 @@ fz_dict_put(fz_obj *obj, fz_obj *key, fz_obj *val) fz_dict_grow(obj); i = location; - if (obj->u.d.sorted) + if (obj->u.d.sorted && obj->u.d.len > 0) memmove(&obj->u.d.items[i + 1], &obj->u.d.items[i], (obj->u.d.len - i) * sizeof(struct keyval)); @@ -825,6 +827,36 @@ fz_sort_dict(fz_obj *obj) } } +int +fz_dict_marked(fz_obj *obj) +{ + obj = fz_resolve_indirect(obj); + if (!fz_is_dict(obj)) + return 0; + return obj->u.d.marked; +} + +int +fz_dict_mark(fz_obj *obj) +{ + int marked; + obj = fz_resolve_indirect(obj); + if (!fz_is_dict(obj)) + return 0; + marked = obj->u.d.marked; + obj->u.d.marked = 1; + return marked; +} + +void +fz_dict_unmark(fz_obj *obj) +{ + obj = fz_resolve_indirect(obj); + if (!fz_is_dict(obj)) + return; + obj->u.d.marked = 0; +} + static void fz_free_array(fz_obj *obj) { |