Commit fcdbc8a102ca258d105ebd2f41bbf17b29c817fd
1 parent
c4e56fa5
Move doFinalChecks to QPDFJob::checkConfiguration
Showing
3 changed files
with
99 additions
and
72 deletions
include/qpdf/QPDFJob.hh
| ... | ... | @@ -85,6 +85,14 @@ class QPDFJob |
| 85 | 85 | QPDF_DLL |
| 86 | 86 | void setOutputStreams(std::ostream* out_stream, std::ostream* err_stream); |
| 87 | 87 | |
| 88 | + // Check to make sure no contradictory options have been | |
| 89 | + // specified. This is called automatically after initializing from | |
| 90 | + // argv or json and is also called by run, but you can call it | |
| 91 | + // manually as well. It throws a Usage exception if there are any | |
| 92 | + // errors. | |
| 93 | + QPDF_DLL | |
| 94 | + void checkConfiguration(); | |
| 95 | + | |
| 88 | 96 | // Returns true if output is created by the specified job. |
| 89 | 97 | QPDF_DLL |
| 90 | 98 | bool createsOutput() const; | ... | ... |
libqpdf/QPDFJob.cc
| ... | ... | @@ -530,6 +530,93 @@ QPDFJob::createsOutput() const |
| 530 | 530 | return ((o.outfilename != nullptr) || o.replace_input); |
| 531 | 531 | } |
| 532 | 532 | |
| 533 | +void | |
| 534 | +QPDFJob::checkConfiguration() | |
| 535 | +{ | |
| 536 | + auto usage = [](char const* msg){ | |
| 537 | + throw std::runtime_error(msg); | |
| 538 | + }; | |
| 539 | + | |
| 540 | + QPDFJob& o = *this; // QXXXQ | |
| 541 | + // QXXXQ messages are CLI-centric | |
| 542 | + if (o.replace_input) | |
| 543 | + { | |
| 544 | + if (o.outfilename) | |
| 545 | + { | |
| 546 | + usage("--replace-input may not be used when" | |
| 547 | + " an output file is specified"); | |
| 548 | + } | |
| 549 | + else if (o.split_pages) | |
| 550 | + { | |
| 551 | + usage("--split-pages may not be used with --replace-input"); | |
| 552 | + } | |
| 553 | + } | |
| 554 | + if (o.infilename == 0) | |
| 555 | + { | |
| 556 | + usage("an input file name is required"); | |
| 557 | + } | |
| 558 | + else if (o.require_outfile && (o.outfilename == 0) && (! o.replace_input)) | |
| 559 | + { | |
| 560 | + usage("an output file name is required; use - for standard output"); | |
| 561 | + } | |
| 562 | + else if ((! o.require_outfile) && | |
| 563 | + ((o.outfilename != 0) || o.replace_input)) | |
| 564 | + { | |
| 565 | + usage("no output file may be given for this option"); | |
| 566 | + } | |
| 567 | + if (o.check_requires_password && o.check_is_encrypted) | |
| 568 | + { | |
| 569 | + usage("--requires-password and --is-encrypted may not be given" | |
| 570 | + " together"); | |
| 571 | + } | |
| 572 | + | |
| 573 | + if (o.encrypt && (! o.allow_insecure) && | |
| 574 | + (o.owner_password.empty() && | |
| 575 | + (! o.user_password.empty()) && | |
| 576 | + (o.keylen == 256))) | |
| 577 | + { | |
| 578 | + // Note that empty owner passwords for R < 5 are copied from | |
| 579 | + // the user password, so this lack of security is not an issue | |
| 580 | + // for those files. Also we are consider only the ability to | |
| 581 | + // open the file without a password to be insecure. We are not | |
| 582 | + // concerned about whether the viewer enforces security | |
| 583 | + // settings when the user and owner password match. | |
| 584 | + usage("A PDF with a non-empty user password and an empty owner" | |
| 585 | + " password encrypted with a 256-bit key is insecure as it" | |
| 586 | + " can be opened without a password. If you really want to" | |
| 587 | + " do this, you must also give the --allow-insecure option" | |
| 588 | + " before the -- that follows --encrypt."); | |
| 589 | + } | |
| 590 | + | |
| 591 | + if (o.require_outfile && o.outfilename && | |
| 592 | + (strcmp(o.outfilename.get(), "-") == 0)) | |
| 593 | + { | |
| 594 | + if (o.split_pages) | |
| 595 | + { | |
| 596 | + usage("--split-pages may not be used when" | |
| 597 | + " writing to standard output"); | |
| 598 | + } | |
| 599 | + if (o.verbose) | |
| 600 | + { | |
| 601 | + usage("--verbose may not be used when" | |
| 602 | + " writing to standard output"); | |
| 603 | + } | |
| 604 | + if (o.progress) | |
| 605 | + { | |
| 606 | + usage("--progress may not be used when" | |
| 607 | + " writing to standard output"); | |
| 608 | + } | |
| 609 | + } | |
| 610 | + | |
| 611 | + if ((! o.split_pages) && | |
| 612 | + QUtil::same_file(o.infilename.get(), o.outfilename.get())) | |
| 613 | + { | |
| 614 | + QTC::TC("qpdf", "qpdf same file error"); | |
| 615 | + usage("input file and output file are the same;" | |
| 616 | + " use --replace-input to intentionally overwrite the input file"); | |
| 617 | + } | |
| 618 | +} | |
| 619 | + | |
| 533 | 620 | bool |
| 534 | 621 | QPDFJob::suppressWarnings() |
| 535 | 622 | { | ... | ... |
libqpdf/QPDFJob_argv.cc
| ... | ... | @@ -1474,81 +1474,13 @@ ArgParser::parseOptions() |
| 1474 | 1474 | void |
| 1475 | 1475 | ArgParser::doFinalChecks() |
| 1476 | 1476 | { |
| 1477 | - if (o.replace_input) | |
| 1478 | - { | |
| 1479 | - if (o.outfilename) | |
| 1480 | - { | |
| 1481 | - usage("--replace-input may not be used when" | |
| 1482 | - " an output file is specified"); | |
| 1483 | - } | |
| 1484 | - else if (o.split_pages) | |
| 1485 | - { | |
| 1486 | - usage("--split-pages may not be used with --replace-input"); | |
| 1487 | - } | |
| 1488 | - } | |
| 1489 | - if (o.infilename == 0) | |
| 1490 | - { | |
| 1491 | - usage("an input file name is required"); | |
| 1492 | - } | |
| 1493 | - else if (o.require_outfile && (o.outfilename == 0) && (! o.replace_input)) | |
| 1494 | - { | |
| 1495 | - usage("an output file name is required; use - for standard output"); | |
| 1496 | - } | |
| 1497 | - else if ((! o.require_outfile) && | |
| 1498 | - ((o.outfilename != 0) || o.replace_input)) | |
| 1499 | - { | |
| 1500 | - usage("no output file may be given for this option"); | |
| 1501 | - } | |
| 1502 | - if (o.check_requires_password && o.check_is_encrypted) | |
| 1503 | - { | |
| 1504 | - usage("--requires-password and --is-encrypted may not be given" | |
| 1505 | - " together"); | |
| 1506 | - } | |
| 1507 | - | |
| 1508 | - if (o.encrypt && (! o.allow_insecure) && | |
| 1509 | - (o.owner_password.empty() && | |
| 1510 | - (! o.user_password.empty()) && | |
| 1511 | - (o.keylen == 256))) | |
| 1512 | - { | |
| 1513 | - // Note that empty owner passwords for R < 5 are copied from | |
| 1514 | - // the user password, so this lack of security is not an issue | |
| 1515 | - // for those files. Also we are consider only the ability to | |
| 1516 | - // open the file without a password to be insecure. We are not | |
| 1517 | - // concerned about whether the viewer enforces security | |
| 1518 | - // settings when the user and owner password match. | |
| 1519 | - usage("A PDF with a non-empty user password and an empty owner" | |
| 1520 | - " password encrypted with a 256-bit key is insecure as it" | |
| 1521 | - " can be opened without a password. If you really want to" | |
| 1522 | - " do this, you must also give the --allow-insecure option" | |
| 1523 | - " before the -- that follows --encrypt."); | |
| 1524 | - } | |
| 1525 | - | |
| 1526 | - if (o.require_outfile && o.outfilename && | |
| 1527 | - (strcmp(o.outfilename.get(), "-") == 0)) | |
| 1477 | + try | |
| 1528 | 1478 | { |
| 1529 | - if (o.split_pages) | |
| 1530 | - { | |
| 1531 | - usage("--split-pages may not be used when" | |
| 1532 | - " writing to standard output"); | |
| 1533 | - } | |
| 1534 | - if (o.verbose) | |
| 1535 | - { | |
| 1536 | - usage("--verbose may not be used when" | |
| 1537 | - " writing to standard output"); | |
| 1538 | - } | |
| 1539 | - if (o.progress) | |
| 1540 | - { | |
| 1541 | - usage("--progress may not be used when" | |
| 1542 | - " writing to standard output"); | |
| 1543 | - } | |
| 1479 | + o.checkConfiguration(); | |
| 1544 | 1480 | } |
| 1545 | - | |
| 1546 | - if ((! o.split_pages) && | |
| 1547 | - QUtil::same_file(o.infilename.get(), o.outfilename.get())) | |
| 1481 | + catch (std::runtime_error& e) | |
| 1548 | 1482 | { |
| 1549 | - QTC::TC("qpdf", "qpdf same file error"); | |
| 1550 | - usage("input file and output file are the same;" | |
| 1551 | - " use --replace-input to intentionally overwrite the input file"); | |
| 1483 | + usage(e.what()); | |
| 1552 | 1484 | } |
| 1553 | 1485 | } |
| 1554 | 1486 | ... | ... |