Commit 8d6cc4f450ba1a74c7d51f5b91f99a56d3ec0a39

Authored by m-holger
Committed by GitHub
2 parents c6e327df 408c72e8

Merge pull request #1660 from m-holger/i1659

Fix password handling in QPDFJob to allow multiple specifications and add tests (Fixes #1659)
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-&gt;runtest(&quot;duplicated pages password&quot;, @@ -88,6 +88,16 @@ $td-&gt;runtest(&quot;duplicated pages password&quot;,
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 " .