aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO3
-rw-r--r--libqpdf/QPDF_json.cc25
-rw-r--r--qpdf/qpdf.testcov6
-rw-r--r--qpdf/qtest/qpdf/manual-qpdf-json.json20
4 files changed, 38 insertions, 16 deletions
diff --git a/TODO b/TODO
index eeef3413..8d96d31e 100644
--- a/TODO
+++ b/TODO
@@ -97,6 +97,9 @@ General things to remember:
* Add json to the large file tests.
+* Document that keys other than "qpdf-v2" are ignored so people can
+ stash their own stuff.
+
JSON to PDF:
Have --json-input and --update-from-json. With --json-input, the json
diff --git a/libqpdf/QPDF_json.cc b/libqpdf/QPDF_json.cc
index c421ce41..b7fe4368 100644
--- a/libqpdf/QPDF_json.cc
+++ b/libqpdf/QPDF_json.cc
@@ -170,7 +170,7 @@ QPDF::JSONReactor::containerEnd(JSON const& value)
}
} else if (state == st_objects) {
if (parse_error) {
- // ignore
+ QTC::TC("qpdf", "QPDF_json don't check object after parse error");
} else if (cur_object == "trailer") {
if (!saw_value) {
QTC::TC("qpdf", "QPDF_json trailer no value");
@@ -279,9 +279,9 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value)
this->saw_qpdf = true;
nestedState(key, value, st_qpdf);
} else {
- // Ignore all other fields for forward compatibility.
- // Don't use nestedState since this can be any type.
- // QXXXQ QTC
+ // Ignore all other fields. We explicitly allow people to
+ // add other top-level keys for their own use.
+ QTC::TC("qpdf", "QPDF_json ignoring unknown top-level key");
next_state = st_ignore;
}
} else if (state == st_qpdf) {
@@ -304,8 +304,9 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value)
this->saw_objects = true;
nestedState(key, value, st_objects);
} else {
- // ignore unknown keys for forward compatibility
- // QXXXQ QTC
+ // ignore unknown keys for forward compatibility and to
+ // skip keys we don't care about like "maxobjectid".
+ QTC::TC("qpdf", "QPDF_json ignore second-level key");
next_state = st_ignore;
}
} else if (state == st_objects) {
@@ -351,7 +352,7 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value)
}
} else {
// Ignore unknown keys for forward compatibility
- // QXXXQ QTC
+ QTC::TC("qpdf", "QPDF_json ignore unknown key in object_top");
next_state = st_ignore;
}
if (replacement.isInitialized()) {
@@ -373,7 +374,7 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value)
parse_error = true;
} else {
// Ignore unknown keys for forward compatibility
- // QXXXQ QTC
+ QTC::TC("qpdf", "QPDF_json ignore unknown key in trailer");
next_state = st_ignore;
}
} else if (state == st_stream) {
@@ -430,7 +431,7 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value)
}
} else {
// Ignore unknown keys for forward compatibility.
- // QXXXQ QTC
+ QTC::TC("qpdf", "QPDF_json ignore unknown key in stream");
next_state = st_ignore;
}
} else if (state == st_object) {
@@ -549,12 +550,6 @@ QPDF::importJSON(std::shared_ptr<InputSource> is, bool must_be_complete)
if (reactor.anyErrors()) {
throw std::runtime_error(is->getName() + ": errors found in JSON");
}
- // QXXXQ
- // std::cout << "trailer:\n" << getTrailer().unparse() << std::endl;
- // for (auto& oh: getAllObjects()) {
- // std::cout << oh.unparse() << ":" << std::endl;
- // std::cout << oh.unparseResolved() << std::endl;
- // }
}
void
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index a7dfa05c..9b1910fb 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -669,3 +669,9 @@ QPDF_json value stream both or neither 0
QPDFJob need json-stream-prefix for stdout 0
QPDFJob write json to stdout 0
QPDFJob write json to file 0
+QPDF_json don't check object after parse error 0
+QPDF_json ignoring unknown top-level key 0
+QPDF_json ignore second-level key 0
+QPDF_json ignore unknown key in object_top 0
+QPDF_json ignore unknown key in trailer 0
+QPDF_json ignore unknown key in stream 0
diff --git a/qpdf/qtest/qpdf/manual-qpdf-json.json b/qpdf/qtest/qpdf/manual-qpdf-json.json
index c67be939..579c88f9 100644
--- a/qpdf/qtest/qpdf/manual-qpdf-json.json
+++ b/qpdf/qtest/qpdf/manual-qpdf-json.json
@@ -1,6 +1,17 @@
{
+ "comment": [
+ "We allow and ignore other top-level keys"
+ ],
"qpdf-v2": {
"pdfversion": "2.0",
+ "maybe-future-key": {
+ "x": [
+ "Lots of times we ignore things",
+ "for forward-compatibility so we don't have",
+ "to change the version number if we add stuff",
+ "in the future"
+ ]
+ },
"objects": {
"obj:3 0 R": {
"value": {
@@ -19,7 +30,8 @@
"/ProcSet": "5 0 R"
},
"/Type": "/Page"
- }
+ },
+ "ignore": "this is ignored"
},
"obj:2 0 R": {
"value": {
@@ -28,6 +40,10 @@
"3 0 R"
],
"/Type": "/Pages"
+ },
+ "ignore": {
+ "potato": "salad",
+ "this": ["is ignored too"]
}
},
"obj:1 0 R": {
@@ -38,6 +54,7 @@
},
"obj:4 0 R": {
"stream": {
+ "what-is-this": "doesn't matter",
"dict": {},
"data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoUG90YXRvKSBUagpFVAo="
}
@@ -58,6 +75,7 @@
}
},
"trailer": {
+ "even-here-we-ignore": "stuff",
"value": {
"/QTest": "7 0 R",
"/Root": "1 0 R",