Commit 12f7a4461b18b4be94002fa0043fd0e98e80a274
1 parent
6488b156
Handle pages/under/overlay JSON file in begin
...since they have to be handled before other options. It was working because, in both cases, `file` was alphabetically before the other keys, but this implementation gives a stronger guarantee.
Showing
5 changed files
with
50 additions
and
7 deletions
libqpdf/QPDFJob_json.cc
| @@ -57,6 +57,8 @@ namespace | @@ -57,6 +57,8 @@ namespace | ||
| 57 | bare_handler_t bindBare(void (Handlers::*f)()); | 57 | bare_handler_t bindBare(void (Handlers::*f)()); |
| 58 | json_handler_t bindJSON(void (Handlers::*f)(JSON)); | 58 | json_handler_t bindJSON(void (Handlers::*f)(JSON)); |
| 59 | 59 | ||
| 60 | + void beginUnderOverlay(JSON const& j); | ||
| 61 | + | ||
| 60 | std::list<std::shared_ptr<JSONHandler>> json_handlers; | 62 | std::list<std::shared_ptr<JSONHandler>> json_handlers; |
| 61 | bool partial; | 63 | bool partial; |
| 62 | JSONHandler* jh{nullptr}; // points to last of json_handlers | 64 | JSONHandler* jh{nullptr}; // points to last of json_handlers |
| @@ -226,6 +228,24 @@ Handlers::handle(JSON& j) | @@ -226,6 +228,24 @@ Handlers::handle(JSON& j) | ||
| 226 | } | 228 | } |
| 227 | 229 | ||
| 228 | void | 230 | void |
| 231 | +Handlers::beginUnderOverlay(JSON const& j) | ||
| 232 | +{ | ||
| 233 | + // File has to be processed before items, so handle it here. | ||
| 234 | + bool file_seen = false; | ||
| 235 | + std::string file; | ||
| 236 | + j.forEachDictItem([&](std::string const& key, JSON const& value) { | ||
| 237 | + if (key == "file") { | ||
| 238 | + file_seen = value.getString(file); | ||
| 239 | + } | ||
| 240 | + }); | ||
| 241 | + if (!file_seen) { | ||
| 242 | + QTC::TC("qpdf", "QPDFJob json over/under no file"); | ||
| 243 | + usage("file is required in underlay/overlay specification"); | ||
| 244 | + } | ||
| 245 | + c_uo->file(file); | ||
| 246 | +} | ||
| 247 | + | ||
| 248 | +void | ||
| 229 | Handlers::setupInputFile() | 249 | Handlers::setupInputFile() |
| 230 | { | 250 | { |
| 231 | addParameter([this](char const* p) { c_main->inputFile(p); }); | 251 | addParameter([this](char const* p) { c_main->inputFile(p); }); |
| @@ -468,16 +488,17 @@ void | @@ -468,16 +488,17 @@ void | ||
| 468 | Handlers::beginPages(JSON j) | 488 | Handlers::beginPages(JSON j) |
| 469 | { | 489 | { |
| 470 | bool file_seen = false; | 490 | bool file_seen = false; |
| 491 | + std::string file; | ||
| 471 | j.forEachDictItem([&](std::string const& key, JSON const& value) { | 492 | j.forEachDictItem([&](std::string const& key, JSON const& value) { |
| 472 | if (key == "file") { | 493 | if (key == "file") { |
| 473 | - std::string v; | ||
| 474 | - file_seen = value.getString(v); | 494 | + file_seen = value.getString(file); |
| 475 | } | 495 | } |
| 476 | }); | 496 | }); |
| 477 | if (!file_seen) { | 497 | if (!file_seen) { |
| 478 | QTC::TC("qpdf", "QPDFJob json pages no file"); | 498 | QTC::TC("qpdf", "QPDFJob json pages no file"); |
| 479 | usage("file is required in page specification"); | 499 | usage("file is required in page specification"); |
| 480 | } | 500 | } |
| 501 | + c_pages->file(file); | ||
| 481 | } | 502 | } |
| 482 | 503 | ||
| 483 | void | 504 | void |
| @@ -489,7 +510,8 @@ Handlers::endPages() | @@ -489,7 +510,8 @@ Handlers::endPages() | ||
| 489 | void | 510 | void |
| 490 | Handlers::setupPagesFile() | 511 | Handlers::setupPagesFile() |
| 491 | { | 512 | { |
| 492 | - addParameter([this](char const* p) { c_pages->file(p); }); | 513 | + // This is handled in beginPages since file() has to be called first. |
| 514 | + ignoreItem(); | ||
| 493 | } | 515 | } |
| 494 | 516 | ||
| 495 | void | 517 | void |
| @@ -499,9 +521,10 @@ Handlers::setupPagesPassword() | @@ -499,9 +521,10 @@ Handlers::setupPagesPassword() | ||
| 499 | } | 521 | } |
| 500 | 522 | ||
| 501 | void | 523 | void |
| 502 | -Handlers::beginOverlay(JSON) | 524 | +Handlers::beginOverlay(JSON j) |
| 503 | { | 525 | { |
| 504 | this->c_uo = c_main->overlay(); | 526 | this->c_uo = c_main->overlay(); |
| 527 | + beginUnderOverlay(j); | ||
| 505 | } | 528 | } |
| 506 | 529 | ||
| 507 | void | 530 | void |
| @@ -514,7 +537,8 @@ Handlers::endOverlay() | @@ -514,7 +537,8 @@ Handlers::endOverlay() | ||
| 514 | void | 537 | void |
| 515 | Handlers::setupOverlayFile() | 538 | Handlers::setupOverlayFile() |
| 516 | { | 539 | { |
| 517 | - addParameter([this](char const* p) { c_uo->file(p); }); | 540 | + // This is handled in beginOverlay since file() has to be called first. |
| 541 | + ignoreItem(); | ||
| 518 | } | 542 | } |
| 519 | 543 | ||
| 520 | void | 544 | void |
| @@ -524,9 +548,10 @@ Handlers::setupOverlayPassword() | @@ -524,9 +548,10 @@ Handlers::setupOverlayPassword() | ||
| 524 | } | 548 | } |
| 525 | 549 | ||
| 526 | void | 550 | void |
| 527 | -Handlers::beginUnderlay(JSON) | 551 | +Handlers::beginUnderlay(JSON j) |
| 528 | { | 552 | { |
| 529 | this->c_uo = c_main->underlay(); | 553 | this->c_uo = c_main->underlay(); |
| 554 | + beginUnderOverlay(j); | ||
| 530 | } | 555 | } |
| 531 | 556 | ||
| 532 | void | 557 | void |
| @@ -539,7 +564,8 @@ Handlers::endUnderlay() | @@ -539,7 +564,8 @@ Handlers::endUnderlay() | ||
| 539 | void | 564 | void |
| 540 | Handlers::setupUnderlayFile() | 565 | Handlers::setupUnderlayFile() |
| 541 | { | 566 | { |
| 542 | - addParameter([this](char const* p) { c_uo->file(p); }); | 567 | + // This is handled in beginUnderlay since file() has to be called first. |
| 568 | + ignoreItem(); | ||
| 543 | } | 569 | } |
| 544 | 570 | ||
| 545 | void | 571 | void |
qpdf/qpdf.testcov
| @@ -691,3 +691,4 @@ QPDFPageDocumentHelper flatten resources missing or invalid 0 | @@ -691,3 +691,4 @@ QPDFPageDocumentHelper flatten resources missing or invalid 0 | ||
| 691 | QPDF recover xref stream 0 | 691 | QPDF recover xref stream 0 |
| 692 | QPDFJob misplaced page range 0 | 692 | QPDFJob misplaced page range 0 |
| 693 | QPDFJob duplicated range 0 | 693 | QPDFJob duplicated range 0 |
| 694 | +QPDFJob json over/under no file 0 |
qpdf/qtest/qpdf/bad-json-overlay-no-file.json
0 → 100644
qpdf/qtest/qpdf/bad-overlay-no-file-json.out
0 → 100644
| 1 | + | ||
| 2 | +qpdf: error with job-json file bad-json-overlay-no-file.json: file is required in underlay/overlay specification | ||
| 3 | +Run qpdf --job-json-help for information on the file format. | ||
| 4 | + | ||
| 5 | +For help: | ||
| 6 | + qpdf --help=usage usage information | ||
| 7 | + qpdf --help=topic help on a topic | ||
| 8 | + qpdf --help=--option help on an option | ||
| 9 | + qpdf --help general help and a topic list | ||
| 10 | + |
qpdf/qtest/qpdfjob.test
| @@ -26,6 +26,7 @@ my @bad_json = ( | @@ -26,6 +26,7 @@ my @bad_json = ( | ||
| 26 | "encrypt-missing-password", | 26 | "encrypt-missing-password", |
| 27 | "encrypt-no-key-length", | 27 | "encrypt-no-key-length", |
| 28 | "pages-no-file", | 28 | "pages-no-file", |
| 29 | + "overlay-no-file", | ||
| 29 | "schema-error", | 30 | "schema-error", |
| 30 | "json-error" | 31 | "json-error" |
| 31 | ); | 32 | ); |