Commit 408c72e81682d71e15ef293790913c17ba5e0ec1
1 parent
5dbcd9c9
Fix password handling in QPDFJob to allow multiple specifications and add tests
Fixes #1659
Showing
4 changed files
with
23 additions
and
3 deletions
libqpdf/QPDFJob.cc
| ... | ... | @@ -2505,9 +2505,13 @@ void |
| 2505 | 2505 | QPDFJob::Selection::password(std::string password) |
| 2506 | 2506 | { |
| 2507 | 2507 | auto& in = input(); |
| 2508 | - if (!in.password.empty()) { | |
| 2508 | + if (password_provided) { | |
| 2509 | 2509 | usage("--password already specified for this file"); |
| 2510 | 2510 | } |
| 2511 | + if (!(in.password.empty() || in.password == password)) { | |
| 2512 | + usage("different --password already specified for this file"); | |
| 2513 | + } | |
| 2514 | + password_provided = true; | |
| 2511 | 2515 | in.password = password; |
| 2512 | 2516 | } |
| 2513 | 2517 | ... | ... |
libqpdf/qpdf/QPDFJob_private.hh
| ... | ... | @@ -29,6 +29,7 @@ struct QPDFJob::Selection |
| 29 | 29 | std::pair<const std::string, QPDFJob::Input>* in_entry{nullptr}; |
| 30 | 30 | std::string range; // An empty range means all pages. |
| 31 | 31 | std::vector<int> selected_pages; |
| 32 | + bool password_provided{false}; | |
| 32 | 33 | }; |
| 33 | 34 | |
| 34 | 35 | // A single input PDF. | ... | ... |
manual/release-notes.rst
| ... | ... | @@ -13,8 +13,13 @@ more detail. |
| 13 | 13 | |
| 14 | 14 | .. x.y.z: not yet released |
| 15 | 15 | |
| 16 | - | |
| 17 | 16 | 12.3.2: not yet released |
| 17 | + - Bug fixes | |
| 18 | + | |
| 19 | + - Fix bug introduced in 12.3.0. If the :qpdf:ref:`--password` was specified | |
| 20 | + for the same file multiple times a usage error was thrown. Specifying | |
| 21 | + the the password multiple times is common within the :qpdf:ref:`--pages` | |
| 22 | + option when using the QPDFJob interface. | |
| 18 | 23 | |
| 19 | 24 | 12.3.1: January 19, 2026 |
| 20 | 25 | - Bug fixes | ... | ... |
qpdf/qtest/arg-parsing.test
| ... | ... | @@ -15,7 +15,7 @@ cleanup(); |
| 15 | 15 | |
| 16 | 16 | my $td = new TestDriver('arg-parsing'); |
| 17 | 17 | |
| 18 | -my $n_tests = 33; | |
| 18 | +my $n_tests = 35; | |
| 19 | 19 | |
| 20 | 20 | $td->runtest("required argument", |
| 21 | 21 | {$td->COMMAND => "qpdf --password minimal.pdf"}, |
| ... | ... | @@ -88,6 +88,16 @@ $td->runtest("duplicated pages password", |
| 88 | 88 | {$td->REGEXP => ".*password already specified.*", |
| 89 | 89 | $td->EXIT_STATUS => 2}, |
| 90 | 90 | $td->NORMALIZE_NEWLINES); |
| 91 | +$td->runtest("inconsistent pages passwords", | |
| 92 | + {$td->COMMAND => "qpdf --pages . --password=z --range=1 . --password=y --range=2 --"}, | |
| 93 | + {$td->REGEXP => ".*different --password already specified.*", | |
| 94 | + $td->EXIT_STATUS => 2}, | |
| 95 | + $td->NORMALIZE_NEWLINES); | |
| 96 | +$td->runtest("consistent pages passwords", | |
| 97 | + {$td->COMMAND => "qpdf --pages . --password=z --range=1 . --password=z --range=2 --"}, | |
| 98 | + {$td->REGEXP => ".*an input file name is required.*", | |
| 99 | + $td->EXIT_STATUS => 2}, | |
| 100 | + $td->NORMALIZE_NEWLINES); | |
| 91 | 101 | $td->runtest("v1-only objects json-key", |
| 92 | 102 | {$td->COMMAND => "qpdf --json=2 --json-key=objects minimal.pdf"}, |
| 93 | 103 | {$td->REGEXP => ".*\"objects\" and \"objectinfo\" are " . | ... | ... |