diff options
author | Robin Watts <robin.watts@artifex.com> | 2014-03-05 12:07:46 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2014-03-17 17:41:16 +0000 |
commit | 801c5c0781c81925ae7c7937c8595dcae780bc85 (patch) | |
tree | f3726d13534b8cff25275263a6140beb56795586 | |
parent | 2c1ec5347ae7c2b610c33f5cd0a034d9c8345d77 (diff) | |
download | mupdf-801c5c0781c81925ae7c7937c8595dcae780bc85.tar.xz |
Ensure that BDC operators get both params.
Currently, when parsing, each time we encounter a name, we throw away
the last name we had. BDC operators are called with:
/Name <object> BDC
If the <object> is a name, we lose the original /Name.
To fix this, parsing a name when we already have a name will cause
the name to be stored as an object.
This has various knock on effects throughout the code to read from
csi->obj rather than csi->name.
Also, ensure that when cleaning, we collect a list of the object
names in our new resources dictionary.
-rw-r--r-- | source/pdf/pdf-interpret.c | 9 | ||||
-rw-r--r-- | source/pdf/pdf-op-filter.c | 17 | ||||
-rw-r--r-- | source/pdf/pdf-op-run.c | 12 |
3 files changed, 32 insertions, 6 deletions
diff --git a/source/pdf/pdf-interpret.c b/source/pdf/pdf-interpret.c index f0271cf3..3984d8e6 100644 --- a/source/pdf/pdf-interpret.c +++ b/source/pdf/pdf-interpret.c @@ -324,7 +324,14 @@ pdf_process_stream(pdf_csi *csi, pdf_lexbuf *buf) break; case PDF_TOK_NAME: - fz_strlcpy(csi->name, buf->scratch, sizeof(csi->name)); + if (csi->name[0]) + { + pdf_drop_obj(csi->obj); + csi->obj = NULL; + csi->obj = pdf_new_name(csi->doc, buf->scratch); + } + else + fz_strlcpy(csi->name, buf->scratch, sizeof(csi->name)); break; case PDF_TOK_INT: diff --git a/source/pdf/pdf-op-filter.c b/source/pdf/pdf-op-filter.c index 52e38883..17bd3af0 100644 --- a/source/pdf/pdf-op-filter.c +++ b/source/pdf/pdf-op-filter.c @@ -45,23 +45,28 @@ typedef struct pdf_filter_state_s pdf_obj *resources; } pdf_filter_state; -static void insert_resource(pdf_csi *csi, pdf_filter_state *state, const char *key) +static void insert_resource_name(pdf_csi *csi, pdf_filter_state *state, const char *key, const char *name) { pdf_obj *xobj; pdf_obj *obj; - if (!state->resources) + if (!state->resources || !name || name[0] == 0) return; xobj = pdf_dict_gets(csi->rdb, key); - obj = pdf_dict_gets(xobj, csi->name); + obj = pdf_dict_gets(xobj, name); xobj = pdf_dict_gets(state->resources, key); if (xobj == NULL) { xobj = pdf_new_dict(csi->doc, 1); pdf_dict_puts_drop(state->resources, key, xobj); } - pdf_dict_putp(xobj, csi->name, obj); + pdf_dict_putp(xobj, name, obj); +} + +static void insert_resource(pdf_csi *csi, pdf_filter_state *state, const char *key) +{ + insert_resource_name(csi, state, key, csi->name); } static inline void call_op(pdf_csi *csi, pdf_filter_state *state, int op) @@ -403,6 +408,8 @@ pdf_filter_BDC(pdf_csi *csi, void *state_) { pdf_filter_state *state = (pdf_filter_state *)state_; + insert_resource_name(csi, state, "Properties", pdf_to_name(csi->obj)); + filter_flush(csi, state, 0); call_op(csi, state, PDF_OP_BDC); } @@ -460,6 +467,8 @@ pdf_filter_DP(pdf_csi *csi, void *state_) { pdf_filter_state *state = (pdf_filter_state *)state_; + insert_resource_name(csi, state, "Properties", pdf_to_name(csi->obj)); + filter_flush(csi, state, 0); call_op(csi, state, PDF_OP_DP); } diff --git a/source/pdf/pdf-op-run.c b/source/pdf/pdf-op-run.c index 22dc76f2..f6eda706 100644 --- a/source/pdf/pdf-op-run.c +++ b/source/pdf/pdf-op-run.c @@ -1697,6 +1697,10 @@ static void pdf_run_BDC(pdf_csi *csi, void *state) pdf_obj *ocg; pdf_obj *rdb = csi->rdb; + /* We only understand OC groups so far */ + if (strcmp(csi->name, "OC") != 0) + return; + /* If we are already in a hidden OCG, then we'll still be hidden - * just increment the depth so we pop back to visibility when we've * seen enough EDCs. */ @@ -1706,7 +1710,13 @@ static void pdf_run_BDC(pdf_csi *csi, void *state) return; } - ocg = pdf_dict_gets(pdf_dict_gets(rdb, "Properties"), csi->name); + if (pdf_is_name(csi->obj)) + { + ocg = pdf_dict_gets(pdf_dict_gets(rdb, "Properties"), pdf_to_name(csi->obj)); + } + else + ocg = csi->obj; + if (!ocg) { /* No Properties array, or name not found in the properties |