Commit 69d2101865c759f18ef34ff262eb1be0ae784056

Authored by m-holger
1 parent 20021372

Refactor `QPDFJob::handlePageSpecs`: add `password` to `Input`, revise file-open…

…ing logic, and streamline password handling and verbose output.
libqpdf/QPDFJob.cc
@@ -2350,7 +2350,7 @@ QPDFJob::handlePageSpecs(QPDF& pdf) @@ -2350,7 +2350,7 @@ QPDFJob::handlePageSpecs(QPDF& pdf)
2350 2350
2351 // Parse all page specifications and translate them into lists of actual pages. 2351 // Parse all page specifications and translate them into lists of actual pages.
2352 2352
2353 - // Handle "." as a shortcut for the input file 2353 + // Handle "." as a shortcut for the input file.
2354 for (auto& selection: m->selections) { 2354 for (auto& selection: m->selections) {
2355 if (selection.filename == ".") { 2355 if (selection.filename == ".") {
2356 selection.filename = m->infilename; 2356 selection.filename = m->infilename;
@@ -2358,6 +2358,9 @@ QPDFJob::handlePageSpecs(QPDF& pdf) @@ -2358,6 +2358,9 @@ QPDFJob::handlePageSpecs(QPDF& pdf)
2358 // Force insertion 2358 // Force insertion
2359 (void)m->inputs.files[selection.filename]; 2359 (void)m->inputs.files[selection.filename];
2360 } 2360 }
  2361 + if (!selection.password.empty()) {
  2362 + m->inputs.files[selection.filename].password = selection.password;
  2363 + }
2361 if (selection.range.empty()) { 2364 if (selection.range.empty()) {
2362 selection.range = "1-z"; 2365 selection.range = "1-z";
2363 } 2366 }
@@ -2376,9 +2379,7 @@ QPDFJob::handlePageSpecs(QPDF& pdf) @@ -2376,9 +2379,7 @@ QPDFJob::handlePageSpecs(QPDF& pdf)
2376 } 2379 }
2377 2380
2378 // Create a QPDF object for each file that we may take pages from. 2381 // Create a QPDF object for each file that we may take pages from.
2379 - std::map<unsigned long long, std::set<QPDFObjGen>> copied_pages;  
2380 - for (auto& selection: m->selections) {  
2381 - auto& input = m->inputs.files[selection.filename]; 2382 + for (auto& [filename, input]: m->inputs.files) {
2382 if (!input.qpdf) { 2383 if (!input.qpdf) {
2383 // Open the PDF file and store the QPDF object. Throw a std::shared_ptr to the qpdf into 2384 // Open the PDF file and store the QPDF object. Throw a std::shared_ptr to the qpdf into
2384 // a heap so that it survives through copying to the output but gets cleaned up 2385 // a heap so that it survives through copying to the output but gets cleaned up
@@ -2387,16 +2388,15 @@ QPDFJob::handlePageSpecs(QPDF&amp; pdf) @@ -2387,16 +2388,15 @@ QPDFJob::handlePageSpecs(QPDF&amp; pdf)
2387 // you are using this an example of how to do this with the API, you can just create two 2388 // you are using this an example of how to do this with the API, you can just create two
2388 // different QPDF objects to the same underlying file with the same path to achieve the 2389 // different QPDF objects to the same underlying file with the same path to achieve the
2389 // same effect. 2390 // same effect.
2390 - auto password = selection.password;  
2391 - if (!m->encryption_file.empty() && password.empty() &&  
2392 - selection.filename == m->encryption_file) { 2391 + auto password = input.password;
  2392 + if (!m->encryption_file.empty() && password.empty() && filename == m->encryption_file) {
2393 password = m->encryption_file_password; 2393 password = m->encryption_file_password;
2394 } 2394 }
2395 doIfVerbose([&](Pipeline& v, std::string const& prefix) { 2395 doIfVerbose([&](Pipeline& v, std::string const& prefix) {
2396 - v << prefix << ": processing " << selection.filename << "\n"; 2396 + v << prefix << ": processing " << filename << "\n";
2397 }); 2397 });
2398 if (!m->keep_files_open) { 2398 if (!m->keep_files_open) {
2399 - auto cis = std::make_shared<ClosedFileInputSource>(selection.filename.data()); 2399 + auto cis = std::make_shared<ClosedFileInputSource>(filename.data());
2400 cis->stayOpen(true); 2400 cis->stayOpen(true);
2401 processInputSource(input.qpdf_p, cis, password.data(), true); 2401 processInputSource(input.qpdf_p, cis, password.data(), true);
2402 cis->stayOpen(false); 2402 cis->stayOpen(false);
@@ -2404,7 +2404,7 @@ QPDFJob::handlePageSpecs(QPDF&amp; pdf) @@ -2404,7 +2404,7 @@ QPDFJob::handlePageSpecs(QPDF&amp; pdf)
2404 } else { 2404 } else {
2405 processInputSource( 2405 processInputSource(
2406 input.qpdf_p, 2406 input.qpdf_p,
2407 - std::make_shared<FileInputSource>(selection.filename.data()), 2407 + std::make_shared<FileInputSource>(filename.data()),
2408 password.data(), 2408 password.data(),
2409 true); 2409 true);
2410 } 2410 }
@@ -2413,7 +2413,10 @@ QPDFJob::handlePageSpecs(QPDF&amp; pdf) @@ -2413,7 +2413,10 @@ QPDFJob::handlePageSpecs(QPDF&amp; pdf)
2413 input.cfis->stayOpen(false); 2413 input.cfis->stayOpen(false);
2414 } 2414 }
2415 } 2415 }
  2416 + }
2416 2417
  2418 + std::map<unsigned long long, std::set<QPDFObjGen>> copied_pages;
  2419 + for (auto& selection: m->selections) {
2417 // Read original pages from the PDF, and parse the page range associated with this 2420 // Read original pages from the PDF, and parse the page range associated with this
2418 // occurrence of the file. 2421 // occurrence of the file.
2419 selection.qpdf = m->inputs.files[selection.filename].qpdf; 2422 selection.qpdf = m->inputs.files[selection.filename].qpdf;
libqpdf/qpdf/QPDFJob_private.hh
@@ -40,6 +40,7 @@ struct QPDFJob::Selection @@ -40,6 +40,7 @@ struct QPDFJob::Selection
40 // filename. This is a documented work-around. 40 // filename. This is a documented work-around.
41 struct QPDFJob::Input 41 struct QPDFJob::Input
42 { 42 {
  43 + std::string password;
43 std::unique_ptr<QPDF> qpdf_p; 44 std::unique_ptr<QPDF> qpdf_p;
44 QPDF* qpdf; 45 QPDF* qpdf;
45 ClosedFileInputSource* cfis{}; 46 ClosedFileInputSource* cfis{};
qpdf/qtest/qpdf/verbose-merge.out
1 qpdf: selecting --keep-open-files=y 1 qpdf: selecting --keep-open-files=y
2 -qpdf: processing 20-pages.pdf  
3 qpdf: processing ./20-pages.pdf 2 qpdf: processing ./20-pages.pdf
  3 +qpdf: processing 20-pages.pdf
4 qpdf: processing minimal.pdf 4 qpdf: processing minimal.pdf
5 qpdf: ./20-pages.pdf: checking for shared resources 5 qpdf: ./20-pages.pdf: checking for shared resources
6 qpdf: no shared resources found 6 qpdf: no shared resources found