Commit fcdbc8a102ca258d105ebd2f41bbf17b29c817fd

Authored by Jay Berkenbilt
1 parent c4e56fa5

Move doFinalChecks to QPDFJob::checkConfiguration

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  
... ...