summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2014-03-05 12:07:46 +0000
committerRobin Watts <robin.watts@artifex.com>2014-03-17 17:41:16 +0000
commit801c5c0781c81925ae7c7937c8595dcae780bc85 (patch)
treef3726d13534b8cff25275263a6140beb56795586
parent2c1ec5347ae7c2b610c33f5cd0a034d9c8345d77 (diff)
downloadmupdf-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.c9
-rw-r--r--source/pdf/pdf-op-filter.c17
-rw-r--r--source/pdf/pdf-op-run.c12
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