Commit bde98044f4acd5ce0e1965ad28a6854c31aa29a1
1 parent
f83bddf8
Improve password handling
Use --encryption-file-password, if given, in addition to --password as a source for passwords for files specified in --pages.
Showing
5 changed files
with
41 additions
and
27 deletions
manual/qpdf-manual.xml
| ... | ... | @@ -586,20 +586,16 @@ make |
| 586 | 586 | </para> |
| 587 | 587 | <para> |
| 588 | 588 | For each file that pages should be taken from, specify the file, a |
| 589 | - password needed to open the file (if needed), and a page range. | |
| 590 | - If the primary input file file requires a password, that password | |
| 591 | - must be specified outside the <option>--pages</option> option and | |
| 592 | - does not need to be repeated inside the <option>--pages</option>. | |
| 593 | - The same file can be repeated multiple times. If a file that is | |
| 594 | - repeated has a password, the password only has to be given the | |
| 595 | - first time. All non-page data (info, outlines, page numbers, | |
| 596 | - etc.) are taken from the primary input file. To discard these, | |
| 597 | - use <option>--empty</option> as the primary input. One subtlety | |
| 598 | - about specifying passwords is that specifying a password as | |
| 599 | - <option>--encryption-file-password</option> doesn't prevent you | |
| 600 | - from having to repeat that password of that is also one of the | |
| 601 | - input files. If in doubt, it's never an error to specify the | |
| 602 | - password multiple times. | |
| 589 | + password needed to open the file (if any), and a page range. The | |
| 590 | + password needs to be given only once per file. If any of the | |
| 591 | + input files are the same as the primary input file or the file | |
| 592 | + used to copy encryption parameters (if specified), you do not need | |
| 593 | + to repeat the password here. The same file can be repeated | |
| 594 | + multiple times. If a file that is repeated has a password, the | |
| 595 | + password only has to be given the first time. All non-page data | |
| 596 | + (info, outlines, page numbers, etc.) are taken from the primary | |
| 597 | + input file. To discard these, use <option>--empty</option> as the | |
| 598 | + primary input. | |
| 603 | 599 | </para> |
| 604 | 600 | <para> |
| 605 | 601 | It is not presently possible to specify the same page from the | ... | ... |
qpdf/qpdf.cc
| ... | ... | @@ -152,13 +152,14 @@ starting point, but its pages are replaced with pages as specified.\n\ |
| 152 | 152 | --pages file [ --password=password ] page-range ... --\n\ |
| 153 | 153 | \n\ |
| 154 | 154 | For each file that pages should be taken from, specify the file, a\n\ |
| 155 | -password needed to open the file (if needed), and a page range. The\n\ | |
| 156 | -password needs to be given only once per file. If the input file file\n\ | |
| 157 | -requires a password, that password must be specified outside the\n\ | |
| 158 | ---pages option and does not need to be repeated. The same file can be\n\ | |
| 159 | -repeated multiple times. All non-page data (info, outlines, page numbers,\n\ | |
| 160 | -etc. are taken from the primary input file. To discard this, use --empty\n\ | |
| 161 | -as the primary input.\n\ | |
| 155 | +password needed to open the file (if any), and a page range. The\n\ | |
| 156 | +password needs to be given only once per file. If any of the input\n\ | |
| 157 | +files are the same as the primary input file or the file used to copy\n\ | |
| 158 | +encryption parameters (if specified), you do not need to repeat the\n\ | |
| 159 | +password here. The same file can be repeated multiple times. All\n\ | |
| 160 | +non-page data (info, outlines, page numbers, etc. are taken from the\n\ | |
| 161 | +primary input file. To discard this, use --empty as the primary\n\ | |
| 162 | +input.\n\ | |
| 162 | 163 | \n\ |
| 163 | 164 | The page range is a set of numbers separated by commas, ranges of\n\ |
| 164 | 165 | numbers separated dashes, or combinations of those. The character\n\ |
| ... | ... | @@ -880,13 +881,13 @@ int main(int argc, char* argv[]) |
| 880 | 881 | exit(0); |
| 881 | 882 | } |
| 882 | 883 | |
| 883 | - char const* password = ""; | |
| 884 | + char const* password = 0; | |
| 884 | 885 | bool linearize = false; |
| 885 | 886 | bool decrypt = false; |
| 886 | 887 | |
| 887 | 888 | bool copy_encryption = false; |
| 888 | 889 | char const* encryption_file = 0; |
| 889 | - char const* encryption_file_password = ""; | |
| 890 | + char const* encryption_file_password = 0; | |
| 890 | 891 | |
| 891 | 892 | bool encrypt = false; |
| 892 | 893 | std::string user_password; |
| ... | ... | @@ -1282,7 +1283,7 @@ int main(int argc, char* argv[]) |
| 1282 | 1283 | if (filter && |
| 1283 | 1284 | (! obj.pipeStreamData(0, true, false, false))) |
| 1284 | 1285 | { |
| 1285 | - QTC::TC("qpdf", "unable to filter"); | |
| 1286 | + QTC::TC("qpdf", "qpdf unable to filter"); | |
| 1286 | 1287 | std::cerr << "Unable to filter stream data." |
| 1287 | 1288 | << std::endl; |
| 1288 | 1289 | exit(EXIT_ERROR); |
| ... | ... | @@ -1445,8 +1446,15 @@ int main(int argc, char* argv[]) |
| 1445 | 1446 | PointerHolder<QPDF> qpdf_ph = new QPDF(); |
| 1446 | 1447 | page_heap.push_back(qpdf_ph); |
| 1447 | 1448 | QPDF* qpdf = qpdf_ph.getPointer(); |
| 1449 | + char const* password = page_spec.password; | |
| 1450 | + if (encryption_file && (password == 0) && | |
| 1451 | + (page_spec.filename == encryption_file)) | |
| 1452 | + { | |
| 1453 | + QTC::TC("qpdf", "qpdf pages encryption password"); | |
| 1454 | + password = encryption_file_password; | |
| 1455 | + } | |
| 1448 | 1456 | qpdf->processFile( |
| 1449 | - page_spec.filename.c_str(), page_spec.password); | |
| 1457 | + page_spec.filename.c_str(), password); | |
| 1450 | 1458 | page_spec_qpdfs[page_spec.filename] = qpdf; |
| 1451 | 1459 | } |
| 1452 | 1460 | ... | ... |
qpdf/qpdf.testcov
| ... | ... | @@ -113,7 +113,7 @@ QPDFObjectHandle indirect to unknown 0 |
| 113 | 113 | QPDF_Stream pipeStreamData with null pipeline 0 |
| 114 | 114 | QPDFWriter not recompressing /FlateDecode 0 |
| 115 | 115 | QPDF_encryption xref stream from encrypted file 0 |
| 116 | -unable to filter 0 | |
| 116 | +qpdf unable to filter 0 | |
| 117 | 117 | QPDF_String non-trivial UTF-16 0 |
| 118 | 118 | QPDF xref overwrite object 0 |
| 119 | 119 | QPDF decoding error warning 0 |
| ... | ... | @@ -237,3 +237,4 @@ QPDFWriter foreign object 0 |
| 237 | 237 | QPDFWriter copy use_aes 1 |
| 238 | 238 | QPDFObjectHandle indirect without context 0 |
| 239 | 239 | QPDFObjectHandle trailing data in parse 0 |
| 240 | +qpdf pages encryption password 0 | ... | ... |
qpdf/qtest/qpdf.test
| ... | ... | @@ -424,7 +424,7 @@ foreach my $d (@nrange_tests) |
| 424 | 424 | |
| 425 | 425 | # ---------- |
| 426 | 426 | $td->notify("--- Merging and Splitting ---"); |
| 427 | -$n_tests += 4; | |
| 427 | +$n_tests += 6; | |
| 428 | 428 | |
| 429 | 429 | # Select pages from the same file multiple times including selecting |
| 430 | 430 | # twice from an encrypted file and specifying the password only the |
| ... | ... | @@ -460,6 +460,15 @@ $td->runtest("merge three files", |
| 460 | 460 | $td->runtest("check output", |
| 461 | 461 | {$td->FILE => "a.pdf"}, |
| 462 | 462 | {$td->FILE => "merge-three-files-2.pdf"}); |
| 463 | +$td->runtest("avoid respecification of password", | |
| 464 | + {$td->COMMAND => | |
| 465 | + "qpdf --empty a.pdf --copy-encryption=20-pages.pdf" . | |
| 466 | + " --encryption-file-password=user" . | |
| 467 | + " --pages 20-pages.pdf 1,z -- --static-id"}, | |
| 468 | + {$td->STRING => "", $td->EXIT_STATUS => 0}); | |
| 469 | +$td->runtest("check output", | |
| 470 | + {$td->FILE => "a.pdf"}, | |
| 471 | + {$td->FILE => "pages-copy-encryption.pdf"}); | |
| 463 | 472 | # ---------- |
| 464 | 473 | $td->notify("--- PDF From Scratch ---"); |
| 465 | 474 | $n_tests += 2; | ... | ... |
qpdf/qtest/qpdf/pages-copy-encryption.pdf
0 → 100644
No preview for this file type