summaryrefslogtreecommitdiffstats
path: root/libqpdf/QPDFJob.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2022-07-31 02:53:30 +0200
committerJay Berkenbilt <ejb@ql.org>2022-07-31 21:17:01 +0200
commit69820847af93cce0e400638999fee4d2cbb68db6 (patch)
tree2ade9466ffec2d57c381096e9bcdabd083d258a8 /libqpdf/QPDFJob.cc
parentd01c4f8819ea93797784c19ecdd623eb41f2a8b4 (diff)
downloadqpdf-69820847af93cce0e400638999fee4d2cbb68db6.tar.zst
Change the output of --json to use "qpdf" instead of "objects"
Diffstat (limited to 'libqpdf/QPDFJob.cc')
-rw-r--r--libqpdf/QPDFJob.cc80
1 files changed, 58 insertions, 22 deletions
diff --git a/libqpdf/QPDFJob.cc b/libqpdf/QPDFJob.cc
index e09c0d74..e5914ddd 100644
--- a/libqpdf/QPDFJob.cc
+++ b/libqpdf/QPDFJob.cc
@@ -417,7 +417,7 @@ QPDFJob::Members::Members() :
check_is_encrypted(false),
check_requires_password(false),
json_input(false),
- json_output(0)
+ json_output(false)
{
}
@@ -728,8 +728,15 @@ QPDFJob::checkConfiguration()
" overwrite the input file");
}
- if (m->json_keys.count("objectinfo")) {
- usage("json key \"objectinfo\" is only valid for json version 1");
+ if (m->json_version == 1) {
+ if (m->json_keys.count("qpdf")) {
+ usage("json key \"qpdf\" is only valid for json version > 1");
+ }
+ } else {
+ if (m->json_keys.count("objectinfo") || m->json_keys.count("objects")) {
+ usage("json keys \"objects\" and \"objectinfo\" are only valid for"
+ " json version 1");
+ }
}
}
@@ -1568,12 +1575,12 @@ QPDFJob::json_schema(int json_version, std::set<std::string>* keys)
// The list of selectable top-level keys id duplicated in the
// following places: job.yml, QPDFJob::json_schema, and
// QPDFJob::doJSON.
- if (all_keys || keys->count("objects")) {
- schema.addDictionaryMember("objects", JSON::parse(R"({
+ if (json_version == 1) {
+ if (all_keys || keys->count("objects")) {
+ schema.addDictionaryMember("objects", JSON::parse(R"({
"<n n R|trailer>": "json representation of object"
})"));
- }
- if (json_version == 1) {
+ }
if (all_keys || keys->count("objectinfo")) {
JSON objectinfo =
schema.addDictionaryMember("objectinfo", JSON::parse(R"({
@@ -1586,6 +1593,19 @@ QPDFJob::json_schema(int json_version, std::set<std::string>* keys)
}
})"));
}
+ } else {
+ if (all_keys || keys->count("qpdf")) {
+ schema.addDictionaryMember("qpdf", JSON::parse(R"([{
+ "jsonversion": "numeric JSON version",
+ "pdfversion": "PDF version as x.y",
+ "pushedinheritedpageresources": "whether inherited attributes were pushed to the page level",
+ "calledgetallpages": "whether getAllPages was called",
+ "maxobjectid": "highest object ID in output, ignored on input"
+},
+{
+ "<obj:n n R|trailer>": "json representation of object"
+}])"));
+ }
}
if (all_keys || keys->count("pages")) {
JSON page = schema.addDictionaryMember("pages", JSON::parse(R"([
@@ -1812,9 +1832,14 @@ QPDFJob::doJSON(QPDF& pdf, Pipeline* p)
// We do objects last so their information is consistent with
// repairing the page tree. To see the original file with any page
// tree problems and the page tree not flattened, select
- // objects/objectinfo without other keys.
- if (all_keys || m->json_keys.count("objects")) {
- doJSONObjects(p, first, pdf);
+ // qpdf/objects/objectinfo without other keys.
+ if (all_keys || m->json_keys.count("objects") ||
+ m->json_keys.count("qpdf")) {
+ if (this->m->json_version == 1) {
+ doJSONObjects(p, first, pdf);
+ } else {
+ writeJSON(p, pdf, false, first);
+ }
}
if (this->m->json_version == 1) {
// "objectinfo" is not needed for version >1 since you can
@@ -2274,7 +2299,8 @@ QPDFJob::addAttachments(QPDF& pdf)
}
message = pdf.getFilename() +
" already has attachments with the following keys: " + message +
- "; use --replace to replace or --key to specify a different key";
+ "; use --replace to replace or --key to specify a different "
+ "key";
throw std::runtime_error(message);
}
}
@@ -2925,10 +2951,12 @@ QPDFJob::maybeFixWritePassword(int R, std::string& password)
<< this->m->message_prefix << ": WARNING: "
<< "supplied password looks like a Unicode"
<< " password with characters not allowed in"
- << " passwords for 40-bit and 128-bit encryption;"
+ << " passwords for 40-bit and 128-bit "
+ "encryption;"
<< " most readers will not be able to open this"
<< " file with the supplied password."
- << " (Use --password-mode=bytes to suppress this"
+ << " (Use --password-mode=bytes to suppress "
+ "this"
<< " warning and use the password anyway.)\n";
}
} else if ((R >= 5) && (!is_valid_utf8)) {
@@ -2978,13 +3006,15 @@ QPDFJob::setEncryptionOptions(QPDF& pdf, QPDFWriter& w)
QTC::TC("qpdf", "QPDFJob weak crypto error");
*this->m->log->getError()
<< this->m->message_prefix
- << ": refusing to write a file with RC4, a weak cryptographic "
+ << ": refusing to write a file with RC4, a weak "
+ "cryptographic "
"algorithm\n"
<< "Please use 256-bit keys for better security.\n"
<< "Pass --allow-weak-crypto to enable writing insecure "
"files.\n"
<< "See also "
- "https://qpdf.readthedocs.io/en/stable/weak-crypto.html\n";
+ "https://qpdf.readthedocs.io/en/stable/"
+ "weak-crypto.html\n";
throw std::runtime_error(
"refusing to write a file with weak crypto");
}
@@ -3293,7 +3323,8 @@ QPDFJob::writeOutfile(QPDF& pdf)
m->outfilename = nullptr;
}
if (this->m->json_output) {
- writeJSON(pdf);
+ bool unused = true;
+ writeJSON(nullptr, pdf, true, unused);
} else {
// QPDFWriter must have block scope so the output file will be
// closed after write() finishes.
@@ -3347,7 +3378,7 @@ QPDFJob::writeOutfile(QPDF& pdf)
}
void
-QPDFJob::writeJSON(QPDF& pdf)
+QPDFJob::writeJSON(Pipeline* p, QPDF& pdf, bool complete, bool& first_key)
{
// File pipeline must have block scope so it will be closed
// after write.
@@ -3369,7 +3400,12 @@ QPDFJob::writeJSON(QPDF& pdf)
"name is unknown");
} else {
QTC::TC("qpdf", "QPDFJob write json to stdout");
- fp = this->m->log->getInfo();
+ if (p == nullptr) {
+ fp = this->m->log->getInfo();
+ }
+ }
+ if (p == nullptr) {
+ p = fp.get();
}
std::set<std::string> json_objects;
if (this->m->json_objects.count("trailer")) {
@@ -3382,10 +3418,10 @@ QPDFJob::writeJSON(QPDF& pdf)
json_objects.insert(s.str());
}
pdf.writeJSON(
- this->m->json_output,
- fp.get(),
- true,
- true,
+ this->m->json_version,
+ p,
+ complete,
+ first_key,
this->m->decode_level,
this->m->json_stream_data,
file_prefix,