summaryrefslogtreecommitdiff
path: root/fitz
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2012-01-06 11:38:43 +0000
committerRobin Watts <robin@ghostscript.com>2012-01-06 13:49:24 +0000
commit09f1a3d3d863099c103100ed10c8cec82ea7aed3 (patch)
treee5eaa31b5b2efc0c9e9537649e7e681ed428e8c0 /fitz
parenta0203aeba59a207db78a312b9b3aacf97b2802f5 (diff)
downloadmupdf-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')
-rw-r--r--fitz/base_object.c36
-rw-r--r--fitz/fitz.h5
2 files changed, 39 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)
{
diff --git a/fitz/fitz.h b/fitz/fitz.h
index 61e59fa4..fe0e4d6b 100644
--- a/fitz/fitz.h
+++ b/fitz/fitz.h
@@ -438,6 +438,11 @@ int fz_is_indirect(fz_obj *obj);
int fz_objcmp(fz_obj *a, fz_obj *b);
+/* dict marking and unmarking functions - to avoid infinite recursions */
+int fz_dict_marked(fz_obj *obj);
+int fz_dict_mark(fz_obj *obj);
+void fz_dict_unmark(fz_obj *obj);
+
/* safe, silent failure, no error reporting on type mismatches */
int fz_to_bool(fz_obj *obj);
int fz_to_int(fz_obj *obj);