Commit 12f7a4461b18b4be94002fa0043fd0e98e80a274

Authored by Jay Berkenbilt
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.
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&amp; j) @@ -226,6 +228,24 @@ Handlers::handle(JSON&amp; 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
  1 +{
  2 + "overlay": {
  3 + "to": "1-z"
  4 + }
  5 +}
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 );