From 408c72e81682d71e15ef293790913c17ba5e0ec1 Mon Sep 17 00:00:00 2001 From: m-holger Date: Fri, 23 Jan 2026 19:15:21 +0000 Subject: [PATCH] Fix password handling in QPDFJob to allow multiple specifications and add tests --- libqpdf/QPDFJob.cc | 6 +++++- libqpdf/qpdf/QPDFJob_private.hh | 1 + manual/release-notes.rst | 7 ++++++- qpdf/qtest/arg-parsing.test | 12 +++++++++++- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/libqpdf/QPDFJob.cc b/libqpdf/QPDFJob.cc index db6718a..c972706 100644 --- a/libqpdf/QPDFJob.cc +++ b/libqpdf/QPDFJob.cc @@ -2505,9 +2505,13 @@ void QPDFJob::Selection::password(std::string password) { auto& in = input(); - if (!in.password.empty()) { + if (password_provided) { usage("--password already specified for this file"); } + if (!(in.password.empty() || in.password == password)) { + usage("different --password already specified for this file"); + } + password_provided = true; in.password = password; } diff --git a/libqpdf/qpdf/QPDFJob_private.hh b/libqpdf/qpdf/QPDFJob_private.hh index 86e4007..bc36fdb 100644 --- a/libqpdf/qpdf/QPDFJob_private.hh +++ b/libqpdf/qpdf/QPDFJob_private.hh @@ -29,6 +29,7 @@ struct QPDFJob::Selection std::pair* in_entry{nullptr}; std::string range; // An empty range means all pages. std::vector selected_pages; + bool password_provided{false}; }; // A single input PDF. diff --git a/manual/release-notes.rst b/manual/release-notes.rst index f7888c8..72c385b 100644 --- a/manual/release-notes.rst +++ b/manual/release-notes.rst @@ -13,8 +13,13 @@ more detail. .. x.y.z: not yet released - 12.3.2: not yet released + - Bug fixes + + - Fix bug introduced in 12.3.0. If the :qpdf:ref:`--password` was specified + for the same file multiple times a usage error was thrown. Specifying + the the password multiple times is common within the :qpdf:ref:`--pages` + option when using the QPDFJob interface. 12.3.1: January 19, 2026 - Bug fixes diff --git a/qpdf/qtest/arg-parsing.test b/qpdf/qtest/arg-parsing.test index a5eefd3..2546b2c 100644 --- a/qpdf/qtest/arg-parsing.test +++ b/qpdf/qtest/arg-parsing.test @@ -15,7 +15,7 @@ cleanup(); my $td = new TestDriver('arg-parsing'); -my $n_tests = 33; +my $n_tests = 35; $td->runtest("required argument", {$td->COMMAND => "qpdf --password minimal.pdf"}, @@ -88,6 +88,16 @@ $td->runtest("duplicated pages password", {$td->REGEXP => ".*password already specified.*", $td->EXIT_STATUS => 2}, $td->NORMALIZE_NEWLINES); +$td->runtest("inconsistent pages passwords", + {$td->COMMAND => "qpdf --pages . --password=z --range=1 . --password=y --range=2 --"}, + {$td->REGEXP => ".*different --password already specified.*", + $td->EXIT_STATUS => 2}, + $td->NORMALIZE_NEWLINES); +$td->runtest("consistent pages passwords", + {$td->COMMAND => "qpdf --pages . --password=z --range=1 . --password=z --range=2 --"}, + {$td->REGEXP => ".*an input file name is required.*", + $td->EXIT_STATUS => 2}, + $td->NORMALIZE_NEWLINES); $td->runtest("v1-only objects json-key", {$td->COMMAND => "qpdf --json=2 --json-key=objects minimal.pdf"}, {$td->REGEXP => ".*\"objects\" and \"objectinfo\" are " . -- libgit2 0.21.4