Commit 69d2101865c759f18ef34ff262eb1be0ae784056
1 parent
20021372
Refactor `QPDFJob::handlePageSpecs`: add `password` to `Input`, revise file-open…
…ing logic, and streamline password handling and verbose output.
Showing
3 changed files
with
15 additions
and
11 deletions
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& pdf) | @@ -2387,16 +2388,15 @@ QPDFJob::handlePageSpecs(QPDF& 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& pdf) | @@ -2404,7 +2404,7 @@ QPDFJob::handlePageSpecs(QPDF& 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& pdf) | @@ -2413,7 +2413,10 @@ QPDFJob::handlePageSpecs(QPDF& 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 |