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 2350  
2351 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 2354 for (auto& selection: m->selections) {
2355 2355 if (selection.filename == ".") {
2356 2356 selection.filename = m->infilename;
... ... @@ -2358,6 +2358,9 @@ QPDFJob::handlePageSpecs(QPDF& pdf)
2358 2358 // Force insertion
2359 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 2364 if (selection.range.empty()) {
2362 2365 selection.range = "1-z";
2363 2366 }
... ... @@ -2376,9 +2379,7 @@ QPDFJob::handlePageSpecs(QPDF& pdf)
2376 2379 }
2377 2380  
2378 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 2383 if (!input.qpdf) {
2383 2384 // Open the PDF file and store the QPDF object. Throw a std::shared_ptr to the qpdf into
2384 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 2388 // you are using this an example of how to do this with the API, you can just create two
2388 2389 // different QPDF objects to the same underlying file with the same path to achieve the
2389 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 2393 password = m->encryption_file_password;
2394 2394 }
2395 2395 doIfVerbose([&](Pipeline& v, std::string const& prefix) {
2396   - v << prefix << ": processing " << selection.filename << "\n";
  2396 + v << prefix << ": processing " << filename << "\n";
2397 2397 });
2398 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 2400 cis->stayOpen(true);
2401 2401 processInputSource(input.qpdf_p, cis, password.data(), true);
2402 2402 cis->stayOpen(false);
... ... @@ -2404,7 +2404,7 @@ QPDFJob::handlePageSpecs(QPDF&amp; pdf)
2404 2404 } else {
2405 2405 processInputSource(
2406 2406 input.qpdf_p,
2407   - std::make_shared<FileInputSource>(selection.filename.data()),
  2407 + std::make_shared<FileInputSource>(filename.data()),
2408 2408 password.data(),
2409 2409 true);
2410 2410 }
... ... @@ -2413,7 +2413,10 @@ QPDFJob::handlePageSpecs(QPDF&amp; pdf)
2413 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 2420 // Read original pages from the PDF, and parse the page range associated with this
2418 2421 // occurrence of the file.
2419 2422 selection.qpdf = m->inputs.files[selection.filename].qpdf;
... ...
libqpdf/qpdf/QPDFJob_private.hh
... ... @@ -40,6 +40,7 @@ struct QPDFJob::Selection
40 40 // filename. This is a documented work-around.
41 41 struct QPDFJob::Input
42 42 {
  43 + std::string password;
43 44 std::unique_ptr<QPDF> qpdf_p;
44 45 QPDF* qpdf;
45 46 ClosedFileInputSource* cfis{};
... ...
qpdf/qtest/qpdf/verbose-merge.out
1 1 qpdf: selecting --keep-open-files=y
2   -qpdf: processing 20-pages.pdf
3 2 qpdf: processing ./20-pages.pdf
  3 +qpdf: processing 20-pages.pdf
4 4 qpdf: processing minimal.pdf
5 5 qpdf: ./20-pages.pdf: checking for shared resources
6 6 qpdf: no shared resources found
... ...