Commit 8d6cc4f450ba1a74c7d51f5b91f99a56d3ec0a39
Committed by
GitHub
Merge pull request #1660 from m-holger/i1659
Fix password handling in QPDFJob to allow multiple specifications and add tests (Fixes #1659)
Showing
8 changed files
with
31 additions
and
9 deletions
CMakeLists.txt
| @@ -7,7 +7,7 @@ cmake_minimum_required(VERSION 3.16) | @@ -7,7 +7,7 @@ cmake_minimum_required(VERSION 3.16) | ||
| 7 | # also find the version number here. generate_auto_job also reads the | 7 | # also find the version number here. generate_auto_job also reads the |
| 8 | # version from here. | 8 | # version from here. |
| 9 | project(qpdf | 9 | project(qpdf |
| 10 | - VERSION 12.3.1 | 10 | + VERSION 12.3.2 |
| 11 | LANGUAGES C CXX) | 11 | LANGUAGES C CXX) |
| 12 | 12 | ||
| 13 | # Honor CMAKE_REQUIRED_LIBRARIES when checking for include files. This | 13 | # Honor CMAKE_REQUIRED_LIBRARIES when checking for include files. This |
include/qpdf/DLL.h
| @@ -27,12 +27,12 @@ | @@ -27,12 +27,12 @@ | ||
| 27 | /* The first version of qpdf to include the version constants is 10.6.0. */ | 27 | /* The first version of qpdf to include the version constants is 10.6.0. */ |
| 28 | #define QPDF_MAJOR_VERSION 12 | 28 | #define QPDF_MAJOR_VERSION 12 |
| 29 | #define QPDF_MINOR_VERSION 3 | 29 | #define QPDF_MINOR_VERSION 3 |
| 30 | -#define QPDF_PATCH_VERSION 1 | 30 | +#define QPDF_PATCH_VERSION 2 |
| 31 | 31 | ||
| 32 | #ifdef QPDF_FUTURE | 32 | #ifdef QPDF_FUTURE |
| 33 | -# define QPDF_VERSION "12.3.1+future" | 33 | +# define QPDF_VERSION "12.3.2+future" |
| 34 | #else | 34 | #else |
| 35 | -# define QPDF_VERSION "12.3.1" | 35 | +# define QPDF_VERSION "12.3.2" |
| 36 | #endif | 36 | #endif |
| 37 | 37 | ||
| 38 | /* | 38 | /* |
job.sums
| 1 | # Generated by generate_auto_job | 1 | # Generated by generate_auto_job |
| 2 | -CMakeLists.txt 7ff9aa661d492874c4a14819401031656fb4386a4430f433b6f127e7d4fa5fe3 | 2 | +CMakeLists.txt 9ed8b0574b60d0625004b4f578089166d10c3d2f2bfc61edf94c105020d82264 |
| 3 | generate_auto_job 8e3175a515aa8837d8a01bba0346b04b3d777d70330ba5b7d52f691316054a34 | 3 | generate_auto_job 8e3175a515aa8837d8a01bba0346b04b3d777d70330ba5b7d52f691316054a34 |
| 4 | include/qpdf/auto_job_c_att.hh 4c2b171ea00531db54720bf49a43f8b34481586ae7fb6cbf225099ee42bc5bb4 | 4 | include/qpdf/auto_job_c_att.hh 4c2b171ea00531db54720bf49a43f8b34481586ae7fb6cbf225099ee42bc5bb4 |
| 5 | include/qpdf/auto_job_c_copy_att.hh 50609012bff14fd82f0649185940d617d05d530cdc522185c7f3920a561ccb42 | 5 | include/qpdf/auto_job_c_copy_att.hh 50609012bff14fd82f0649185940d617d05d530cdc522185c7f3920a561ccb42 |
| @@ -17,5 +17,5 @@ libqpdf/qpdf/auto_job_json_init.hh 33934c23235c760a1fc1375c74f4fd52c8f5accf655c5 | @@ -17,5 +17,5 @@ libqpdf/qpdf/auto_job_json_init.hh 33934c23235c760a1fc1375c74f4fd52c8f5accf655c5 | ||
| 17 | libqpdf/qpdf/auto_job_schema.hh 81b8d57f05f5125a722912b6ee5e10fc6b02ae68e040108b75f32fc6527c02b1 | 17 | libqpdf/qpdf/auto_job_schema.hh 81b8d57f05f5125a722912b6ee5e10fc6b02ae68e040108b75f32fc6527c02b1 |
| 18 | manual/_ext/qpdf.py 6add6321666031d55ed4aedf7c00e5662bba856dfcd66ccb526563bffefbb580 | 18 | manual/_ext/qpdf.py 6add6321666031d55ed4aedf7c00e5662bba856dfcd66ccb526563bffefbb580 |
| 19 | manual/cli.rst efbce4b34fefbe1f46fca9c9693af245a7f7e2b63c0853c464569087aa49cb18 | 19 | manual/cli.rst efbce4b34fefbe1f46fca9c9693af245a7f7e2b63c0853c464569087aa49cb18 |
| 20 | -manual/qpdf.1 5a944d1d3684fc240fbb5a80885a364a31dcfa1cdd9bcdcb30885db09b335a3e | 20 | +manual/qpdf.1 0783e8741f21ed28b3d3d2c5e07beb7eef6e227dd82bd0b316a17875f39f1589 |
| 21 | manual/qpdf.1.in 436ecc85d45c4c9e2dbd1725fb7f0177fb627179469f114561adf3cb6cbb677b | 21 | manual/qpdf.1.in 436ecc85d45c4c9e2dbd1725fb7f0177fb627179469f114561adf3cb6cbb677b |
libqpdf/QPDFJob.cc
| @@ -2505,9 +2505,13 @@ void | @@ -2505,9 +2505,13 @@ void | ||
| 2505 | QPDFJob::Selection::password(std::string password) | 2505 | QPDFJob::Selection::password(std::string password) |
| 2506 | { | 2506 | { |
| 2507 | auto& in = input(); | 2507 | auto& in = input(); |
| 2508 | - if (!in.password.empty()) { | 2508 | + if (password_provided) { |
| 2509 | usage("--password already specified for this file"); | 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 | in.password = password; | 2515 | in.password = password; |
| 2512 | } | 2516 | } |
| 2513 | 2517 |
libqpdf/qpdf/QPDFJob_private.hh
| @@ -29,6 +29,7 @@ struct QPDFJob::Selection | @@ -29,6 +29,7 @@ struct QPDFJob::Selection | ||
| 29 | std::pair<const std::string, QPDFJob::Input>* in_entry{nullptr}; | 29 | std::pair<const std::string, QPDFJob::Input>* in_entry{nullptr}; |
| 30 | std::string range; // An empty range means all pages. | 30 | std::string range; // An empty range means all pages. |
| 31 | std::vector<int> selected_pages; | 31 | std::vector<int> selected_pages; |
| 32 | + bool password_provided{false}; | ||
| 32 | }; | 33 | }; |
| 33 | 34 | ||
| 34 | // A single input PDF. | 35 | // A single input PDF. |
manual/qpdf.1
| @@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
| 3 | .\" Edits will be automatically overwritten if the build is | 3 | .\" Edits will be automatically overwritten if the build is |
| 4 | .\" run in maintainer mode. | 4 | .\" run in maintainer mode. |
| 5 | .\" | 5 | .\" |
| 6 | -.TH QPDF "1" "" "qpdf version 12.3.1" "User Commands" | 6 | +.TH QPDF "1" "" "qpdf version 12.3.2" "User Commands" |
| 7 | .SH NAME | 7 | .SH NAME |
| 8 | qpdf \- PDF transformation software | 8 | qpdf \- PDF transformation software |
| 9 | .SH SYNOPSIS | 9 | .SH SYNOPSIS |
manual/release-notes.rst
| @@ -13,6 +13,13 @@ more detail. | @@ -13,6 +13,13 @@ more detail. | ||
| 13 | 13 | ||
| 14 | .. x.y.z: not yet released | 14 | .. x.y.z: not yet released |
| 15 | 15 | ||
| 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. | ||
| 16 | 23 | ||
| 17 | 12.3.1: January 19, 2026 | 24 | 12.3.1: January 19, 2026 |
| 18 | - Bug fixes | 25 | - Bug fixes |
qpdf/qtest/arg-parsing.test
| @@ -15,7 +15,7 @@ cleanup(); | @@ -15,7 +15,7 @@ cleanup(); | ||
| 15 | 15 | ||
| 16 | my $td = new TestDriver('arg-parsing'); | 16 | my $td = new TestDriver('arg-parsing'); |
| 17 | 17 | ||
| 18 | -my $n_tests = 33; | 18 | +my $n_tests = 35; |
| 19 | 19 | ||
| 20 | $td->runtest("required argument", | 20 | $td->runtest("required argument", |
| 21 | {$td->COMMAND => "qpdf --password minimal.pdf"}, | 21 | {$td->COMMAND => "qpdf --password minimal.pdf"}, |
| @@ -88,6 +88,16 @@ $td->runtest("duplicated pages password", | @@ -88,6 +88,16 @@ $td->runtest("duplicated pages password", | ||
| 88 | {$td->REGEXP => ".*password already specified.*", | 88 | {$td->REGEXP => ".*password already specified.*", |
| 89 | $td->EXIT_STATUS => 2}, | 89 | $td->EXIT_STATUS => 2}, |
| 90 | $td->NORMALIZE_NEWLINES); | 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 | $td->runtest("v1-only objects json-key", | 101 | $td->runtest("v1-only objects json-key", |
| 92 | {$td->COMMAND => "qpdf --json=2 --json-key=objects minimal.pdf"}, | 102 | {$td->COMMAND => "qpdf --json=2 --json-key=objects minimal.pdf"}, |
| 93 | {$td->REGEXP => ".*\"objects\" and \"objectinfo\" are " . | 103 | {$td->REGEXP => ".*\"objects\" and \"objectinfo\" are " . |