Commit e076c9bf084ba5f90f52d829255e4ef04e3a8031
1 parent
ac2b3b96
Remove erroneous handling of /EFF for stream decryption
I thought /EFF was supposed to be used as a default for decrypting embedded file streams, but actually it's supposed to be advice to a conforming writer about handling new ones. This makes sense since the findAttachmentStreams code, which is not actually needed, was never right.
Showing
12 changed files
with
64 additions
and
85 deletions
TODO
| @@ -425,25 +425,13 @@ I find it useful to make reference to them in this list. | @@ -425,25 +425,13 @@ I find it useful to make reference to them in this list. | ||
| 425 | http://multivalent.sourceforge.net/Tools/pdf/Extract.html | 425 | http://multivalent.sourceforge.net/Tools/pdf/Extract.html |
| 426 | http://multivalent.sourceforge.net/Tools/pdf/Embed.html | 426 | http://multivalent.sourceforge.net/Tools/pdf/Embed.html |
| 427 | 427 | ||
| 428 | - * The description of Crypt filters is unclear with respect to how to | ||
| 429 | - use them to override /StmF for specific streams. I'm not sure | ||
| 430 | - whether qpdf will do the right thing for any specific individual | ||
| 431 | - streams that might have crypt filters, but I believe it does based | ||
| 432 | - on my testing of a limited subset. The specification seems to imply | ||
| 433 | - that only embedded file streams and metadata streams can have crypt | ||
| 434 | - filters, and there are already special cases in the code to handle | ||
| 435 | - those. Most likely, it won't be a problem, but someday someone may | ||
| 436 | - find a file that qpdf doesn't work on because of crypt filters. | ||
| 437 | - There is an example in the spec of using a crypt filter on a | ||
| 438 | - metadata stream. | ||
| 439 | - | ||
| 440 | - For now, we notice /Crypt filters and decode parameters consistent | ||
| 441 | - with the example in the PDF specification, and the right thing | ||
| 442 | - happens for metadata filters that happen to be uncompressed or | ||
| 443 | - otherwise compressed in a way we can filter. This should handle | ||
| 444 | - all normal cases, but it's more or less just a guess since I don't | ||
| 445 | - have any test files that actually use stream-specific crypt filters | ||
| 446 | - in them. | 428 | + * Qpdf does not honor /EFF when adding new file attachments. When it |
| 429 | + encrypts, it never generates streams with explicit crypt filters. | ||
| 430 | + Prior to 10.2, there was an incorrect attempt to treat /EFF as a | ||
| 431 | + default value for decrypting file attachment streams, but it is not | ||
| 432 | + supposed to mean that. Instead, it is intended for comforming | ||
| 433 | + writers to obey this when adding new attachments. Qpdf is not a | ||
| 434 | + conforming writer in that respect. | ||
| 447 | 435 | ||
| 448 | * The second xref stream for linearized files has to be padded only | 436 | * The second xref stream for linearized files has to be padded only |
| 449 | because we need file_size as computed in pass 1 to be accurate. If | 437 | because we need file_size as computed in pass 1 to be accurate. If |
include/qpdf/QPDF.hh
| @@ -814,7 +814,6 @@ class QPDF | @@ -814,7 +814,6 @@ class QPDF | ||
| 814 | int foreign_generation, | 814 | int foreign_generation, |
| 815 | qpdf_offset_t offset, | 815 | qpdf_offset_t offset, |
| 816 | size_t length, | 816 | size_t length, |
| 817 | - bool is_attachment_stream, | ||
| 818 | QPDFObjectHandle local_dict); | 817 | QPDFObjectHandle local_dict); |
| 819 | 818 | ||
| 820 | private: | 819 | private: |
| @@ -824,7 +823,6 @@ class QPDF | @@ -824,7 +823,6 @@ class QPDF | ||
| 824 | int foreign_generation; | 823 | int foreign_generation; |
| 825 | qpdf_offset_t offset; | 824 | qpdf_offset_t offset; |
| 826 | size_t length; | 825 | size_t length; |
| 827 | - bool is_attachment_stream; | ||
| 828 | QPDFObjectHandle local_dict; | 826 | QPDFObjectHandle local_dict; |
| 829 | }; | 827 | }; |
| 830 | 828 | ||
| @@ -919,7 +917,6 @@ class QPDF | @@ -919,7 +917,6 @@ class QPDF | ||
| 919 | int& act_objid, int& act_generation); | 917 | int& act_objid, int& act_generation); |
| 920 | PointerHolder<QPDFObject> resolve(int objid, int generation); | 918 | PointerHolder<QPDFObject> resolve(int objid, int generation); |
| 921 | void resolveObjectsInStream(int obj_stream_number); | 919 | void resolveObjectsInStream(int obj_stream_number); |
| 922 | - void findAttachmentStreams(); | ||
| 923 | void stopOnError(std::string const& message); | 920 | void stopOnError(std::string const& message); |
| 924 | 921 | ||
| 925 | // Calls finish() on the pipeline when done but does not delete it | 922 | // Calls finish() on the pipeline when done but does not delete it |
| @@ -938,7 +935,6 @@ class QPDF | @@ -938,7 +935,6 @@ class QPDF | ||
| 938 | int objid, int generation, | 935 | int objid, int generation, |
| 939 | qpdf_offset_t offset, size_t length, | 936 | qpdf_offset_t offset, size_t length, |
| 940 | QPDFObjectHandle dict, | 937 | QPDFObjectHandle dict, |
| 941 | - bool is_attachment_stream, | ||
| 942 | Pipeline* pipeline, | 938 | Pipeline* pipeline, |
| 943 | bool suppress_warnings, | 939 | bool suppress_warnings, |
| 944 | bool will_retry); | 940 | bool will_retry); |
| @@ -1001,7 +997,7 @@ class QPDF | @@ -1001,7 +997,7 @@ class QPDF | ||
| 1001 | PointerHolder<InputSource> file, | 997 | PointerHolder<InputSource> file, |
| 1002 | QPDF& qpdf_for_warning, Pipeline*& pipeline, | 998 | QPDF& qpdf_for_warning, Pipeline*& pipeline, |
| 1003 | int objid, int generation, | 999 | int objid, int generation, |
| 1004 | - QPDFObjectHandle& stream_dict, bool is_attachment_stream, | 1000 | + QPDFObjectHandle& stream_dict, |
| 1005 | std::vector<PointerHolder<Pipeline> >& heap); | 1001 | std::vector<PointerHolder<Pipeline> >& heap); |
| 1006 | 1002 | ||
| 1007 | // Methods to support object copying | 1003 | // Methods to support object copying |
| @@ -1422,7 +1418,6 @@ class QPDF | @@ -1422,7 +1418,6 @@ class QPDF | ||
| 1422 | PointerHolder<QPDFObjectHandle::StreamDataProvider> copied_streams; | 1418 | PointerHolder<QPDFObjectHandle::StreamDataProvider> copied_streams; |
| 1423 | // copied_stream_data_provider is owned by copied_streams | 1419 | // copied_stream_data_provider is owned by copied_streams |
| 1424 | CopiedStreamDataProvider* copied_stream_data_provider; | 1420 | CopiedStreamDataProvider* copied_stream_data_provider; |
| 1425 | - std::set<QPDFObjGen> attachment_streams; | ||
| 1426 | bool reconstructed_xref; | 1421 | bool reconstructed_xref; |
| 1427 | bool fixed_dangling_refs; | 1422 | bool fixed_dangling_refs; |
| 1428 | bool immediate_copy_from; | 1423 | bool immediate_copy_from; |
libqpdf/QPDF.cc
| @@ -18,7 +18,6 @@ | @@ -18,7 +18,6 @@ | ||
| 18 | #include <qpdf/FileInputSource.hh> | 18 | #include <qpdf/FileInputSource.hh> |
| 19 | #include <qpdf/BufferInputSource.hh> | 19 | #include <qpdf/BufferInputSource.hh> |
| 20 | #include <qpdf/OffsetInputSource.hh> | 20 | #include <qpdf/OffsetInputSource.hh> |
| 21 | -#include <qpdf/QPDFNameTreeObjectHelper.hh> | ||
| 22 | 21 | ||
| 23 | #include <qpdf/QPDFExc.hh> | 22 | #include <qpdf/QPDFExc.hh> |
| 24 | #include <qpdf/QPDF_Null.hh> | 23 | #include <qpdf/QPDF_Null.hh> |
| @@ -98,7 +97,6 @@ QPDF::ForeignStreamData::ForeignStreamData( | @@ -98,7 +97,6 @@ QPDF::ForeignStreamData::ForeignStreamData( | ||
| 98 | int foreign_generation, | 97 | int foreign_generation, |
| 99 | qpdf_offset_t offset, | 98 | qpdf_offset_t offset, |
| 100 | size_t length, | 99 | size_t length, |
| 101 | - bool is_attachment_stream, | ||
| 102 | QPDFObjectHandle local_dict) | 100 | QPDFObjectHandle local_dict) |
| 103 | : | 101 | : |
| 104 | encp(encp), | 102 | encp(encp), |
| @@ -107,7 +105,6 @@ QPDF::ForeignStreamData::ForeignStreamData( | @@ -107,7 +105,6 @@ QPDF::ForeignStreamData::ForeignStreamData( | ||
| 107 | foreign_generation(foreign_generation), | 105 | foreign_generation(foreign_generation), |
| 108 | offset(offset), | 106 | offset(offset), |
| 109 | length(length), | 107 | length(length), |
| 110 | - is_attachment_stream(is_attachment_stream), | ||
| 111 | local_dict(local_dict) | 108 | local_dict(local_dict) |
| 112 | { | 109 | { |
| 113 | } | 110 | } |
| @@ -508,7 +505,6 @@ QPDF::parse(char const* password) | @@ -508,7 +505,6 @@ QPDF::parse(char const* password) | ||
| 508 | } | 505 | } |
| 509 | 506 | ||
| 510 | initializeEncryption(); | 507 | initializeEncryption(); |
| 511 | - findAttachmentStreams(); | ||
| 512 | this->m->parsed = true; | 508 | this->m->parsed = true; |
| 513 | } | 509 | } |
| 514 | 510 | ||
| @@ -2648,8 +2644,6 @@ QPDF::replaceForeignIndirectObjects( | @@ -2648,8 +2644,6 @@ QPDF::replaceForeignIndirectObjects( | ||
| 2648 | foreign.getGeneration(), | 2644 | foreign.getGeneration(), |
| 2649 | stream->getOffset(), | 2645 | stream->getOffset(), |
| 2650 | stream->getLength(), | 2646 | stream->getLength(), |
| 2651 | - (foreign_stream_qpdf->m->attachment_streams.count( | ||
| 2652 | - foreign.getObjGen()) > 0), | ||
| 2653 | dict); | 2647 | dict); |
| 2654 | this->m->copied_stream_data_provider->registerForeignStream( | 2648 | this->m->copied_stream_data_provider->registerForeignStream( |
| 2655 | local_og, foreign_stream_data); | 2649 | local_og, foreign_stream_data); |
| @@ -2882,7 +2876,6 @@ QPDF::pipeStreamData(PointerHolder<EncryptionParameters> encp, | @@ -2882,7 +2876,6 @@ QPDF::pipeStreamData(PointerHolder<EncryptionParameters> encp, | ||
| 2882 | int objid, int generation, | 2876 | int objid, int generation, |
| 2883 | qpdf_offset_t offset, size_t length, | 2877 | qpdf_offset_t offset, size_t length, |
| 2884 | QPDFObjectHandle stream_dict, | 2878 | QPDFObjectHandle stream_dict, |
| 2885 | - bool is_attachment_stream, | ||
| 2886 | Pipeline* pipeline, | 2879 | Pipeline* pipeline, |
| 2887 | bool suppress_warnings, | 2880 | bool suppress_warnings, |
| 2888 | bool will_retry) | 2881 | bool will_retry) |
| @@ -2892,7 +2885,7 @@ QPDF::pipeStreamData(PointerHolder<EncryptionParameters> encp, | @@ -2892,7 +2885,7 @@ QPDF::pipeStreamData(PointerHolder<EncryptionParameters> encp, | ||
| 2892 | { | 2885 | { |
| 2893 | decryptStream(encp, file, qpdf_for_warning, | 2886 | decryptStream(encp, file, qpdf_for_warning, |
| 2894 | pipeline, objid, generation, | 2887 | pipeline, objid, generation, |
| 2895 | - stream_dict, is_attachment_stream, to_delete); | 2888 | + stream_dict, to_delete); |
| 2896 | } | 2889 | } |
| 2897 | 2890 | ||
| 2898 | bool success = false; | 2891 | bool success = false; |
| @@ -2968,14 +2961,11 @@ QPDF::pipeStreamData(int objid, int generation, | @@ -2968,14 +2961,11 @@ QPDF::pipeStreamData(int objid, int generation, | ||
| 2968 | bool suppress_warnings, | 2961 | bool suppress_warnings, |
| 2969 | bool will_retry) | 2962 | bool will_retry) |
| 2970 | { | 2963 | { |
| 2971 | - bool is_attachment_stream = ( | ||
| 2972 | - this->m->attachment_streams.count( | ||
| 2973 | - QPDFObjGen(objid, generation)) > 0); | ||
| 2974 | return pipeStreamData( | 2964 | return pipeStreamData( |
| 2975 | this->m->encp, this->m->file, *this, | 2965 | this->m->encp, this->m->file, *this, |
| 2976 | objid, generation, offset, length, | 2966 | objid, generation, offset, length, |
| 2977 | - stream_dict, is_attachment_stream, | ||
| 2978 | - pipeline, suppress_warnings, will_retry); | 2967 | + stream_dict, pipeline, |
| 2968 | + suppress_warnings, will_retry); | ||
| 2979 | } | 2969 | } |
| 2980 | 2970 | ||
| 2981 | bool | 2971 | bool |
| @@ -2992,36 +2982,8 @@ QPDF::pipeForeignStreamData( | @@ -2992,36 +2982,8 @@ QPDF::pipeForeignStreamData( | ||
| 2992 | foreign->encp, foreign->file, *this, | 2982 | foreign->encp, foreign->file, *this, |
| 2993 | foreign->foreign_objid, foreign->foreign_generation, | 2983 | foreign->foreign_objid, foreign->foreign_generation, |
| 2994 | foreign->offset, foreign->length, | 2984 | foreign->offset, foreign->length, |
| 2995 | - foreign->local_dict, foreign->is_attachment_stream, | ||
| 2996 | - pipeline, suppress_warnings, will_retry); | ||
| 2997 | -} | ||
| 2998 | - | ||
| 2999 | -void | ||
| 3000 | -QPDF::findAttachmentStreams() | ||
| 3001 | -{ | ||
| 3002 | - QPDFObjectHandle root = getRoot(); | ||
| 3003 | - QPDFObjectHandle names = root.getKey("/Names"); | ||
| 3004 | - if (! names.isDictionary()) | ||
| 3005 | - { | ||
| 3006 | - return; | ||
| 3007 | - } | ||
| 3008 | - QPDFObjectHandle embedded_files = names.getKey("/EmbeddedFiles"); | ||
| 3009 | - if (! embedded_files.isDictionary()) | ||
| 3010 | - { | ||
| 3011 | - return; | ||
| 3012 | - } | ||
| 3013 | - QPDFNameTreeObjectHelper ef_tree(embedded_files, *this); | ||
| 3014 | - for (auto const& i: ef_tree) | ||
| 3015 | - { | ||
| 3016 | - QPDFObjectHandle item = i.second; | ||
| 3017 | - if (item.isDictionary() && | ||
| 3018 | - item.getKey("/EF").isDictionary() && | ||
| 3019 | - item.getKey("/EF").getKey("/F").isStream()) | ||
| 3020 | - { | ||
| 3021 | - QPDFObjectHandle stream = item.getKey("/EF").getKey("/F"); | ||
| 3022 | - this->m->attachment_streams.insert(stream.getObjGen()); | ||
| 3023 | - } | ||
| 3024 | - } | 2985 | + foreign->local_dict, pipeline, |
| 2986 | + suppress_warnings, will_retry); | ||
| 3025 | } | 2987 | } |
| 3026 | 2988 | ||
| 3027 | void | 2989 | void |
libqpdf/QPDF_encryption.cc
| @@ -1022,6 +1022,20 @@ QPDF::initializeEncryption() | @@ -1022,6 +1022,20 @@ QPDF::initializeEncryption() | ||
| 1022 | this->m->encp->cf_string = interpretCF(this->m->encp, StrF); | 1022 | this->m->encp->cf_string = interpretCF(this->m->encp, StrF); |
| 1023 | if (EFF.isName()) | 1023 | if (EFF.isName()) |
| 1024 | { | 1024 | { |
| 1025 | + // qpdf does not use this for anything other than | ||
| 1026 | + // informational purposes. This is intended to instruct | ||
| 1027 | + // conforming writers on which crypt filter should be used | ||
| 1028 | + // when new file attachments are added to a PDF file, but | ||
| 1029 | + // qpdf never generates encrypted files with non-default | ||
| 1030 | + // crypt filters. Prior to 10.2, I was under the mistaken | ||
| 1031 | + // impression that this was supposed to be used for | ||
| 1032 | + // decrypting attachments, but the code was wrong in a way | ||
| 1033 | + // that turns out not to have mattered because no writers | ||
| 1034 | + // were generating files the way I was imagining. Still, | ||
| 1035 | + // providing this information could be useful when looking | ||
| 1036 | + // at a file generated by something else, such as Acrobat | ||
| 1037 | + // when specifying that only attachments should be | ||
| 1038 | + // encrypted. | ||
| 1025 | this->m->encp->cf_file = interpretCF(this->m->encp, EFF); | 1039 | this->m->encp->cf_file = interpretCF(this->m->encp, EFF); |
| 1026 | } | 1040 | } |
| 1027 | else | 1041 | else |
| @@ -1224,7 +1238,6 @@ QPDF::decryptStream(PointerHolder<EncryptionParameters> encp, | @@ -1224,7 +1238,6 @@ QPDF::decryptStream(PointerHolder<EncryptionParameters> encp, | ||
| 1224 | QPDF& qpdf_for_warning, Pipeline*& pipeline, | 1238 | QPDF& qpdf_for_warning, Pipeline*& pipeline, |
| 1225 | int objid, int generation, | 1239 | int objid, int generation, |
| 1226 | QPDFObjectHandle& stream_dict, | 1240 | QPDFObjectHandle& stream_dict, |
| 1227 | - bool is_attachment_stream, | ||
| 1228 | std::vector<PointerHolder<Pipeline> >& heap) | 1241 | std::vector<PointerHolder<Pipeline> >& heap) |
| 1229 | { | 1242 | { |
| 1230 | std::string type; | 1243 | std::string type; |
| @@ -1296,15 +1309,7 @@ QPDF::decryptStream(PointerHolder<EncryptionParameters> encp, | @@ -1296,15 +1309,7 @@ QPDF::decryptStream(PointerHolder<EncryptionParameters> encp, | ||
| 1296 | } | 1309 | } |
| 1297 | else | 1310 | else |
| 1298 | { | 1311 | { |
| 1299 | - if (is_attachment_stream) | ||
| 1300 | - { | ||
| 1301 | - QTC::TC("qpdf", "QPDF_encryption attachment stream"); | ||
| 1302 | - method = encp->cf_file; | ||
| 1303 | - } | ||
| 1304 | - else | ||
| 1305 | - { | ||
| 1306 | - method = encp->cf_stream; | ||
| 1307 | - } | 1312 | + method = encp->cf_stream; |
| 1308 | } | 1313 | } |
| 1309 | } | 1314 | } |
| 1310 | use_aes = false; | 1315 | use_aes = false; |
qpdf/qpdf.testcov
| @@ -401,7 +401,6 @@ qpdf image optimize no pipeline 0 | @@ -401,7 +401,6 @@ qpdf image optimize no pipeline 0 | ||
| 401 | qpdf image optimize no shrink 0 | 401 | qpdf image optimize no shrink 0 |
| 402 | qpdf image optimize too small 0 | 402 | qpdf image optimize too small 0 |
| 403 | QPDFFormFieldObjectHelper WinAnsi 0 | 403 | QPDFFormFieldObjectHelper WinAnsi 0 |
| 404 | -QPDF_encryption attachment stream 0 | ||
| 405 | QPDF pipe foreign encrypted stream 0 | 404 | QPDF pipe foreign encrypted stream 0 |
| 406 | QPDF copy foreign stream with provider 0 | 405 | QPDF copy foreign stream with provider 0 |
| 407 | QPDF copy foreign stream with buffer 0 | 406 | QPDF copy foreign stream with buffer 0 |
qpdf/qtest/qpdf.test
| @@ -1257,7 +1257,7 @@ $n_tests += 3; | @@ -1257,7 +1257,7 @@ $n_tests += 3; | ||
| 1257 | $td->runtest("closed input source", | 1257 | $td->runtest("closed input source", |
| 1258 | {$td->COMMAND => "test_driver 73 minimal.pdf"}, | 1258 | {$td->COMMAND => "test_driver 73 minimal.pdf"}, |
| 1259 | {$td->FILE => "test73.out", | 1259 | {$td->FILE => "test73.out", |
| 1260 | - $td->EXIT_STATUS => 0}, | 1260 | + $td->EXIT_STATUS => 2}, |
| 1261 | $td->NORMALIZE_NEWLINES); | 1261 | $td->NORMALIZE_NEWLINES); |
| 1262 | 1262 | ||
| 1263 | $td->runtest("empty object", | 1263 | $td->runtest("empty object", |
| @@ -3878,7 +3878,7 @@ $td->runtest("check encryption", | @@ -3878,7 +3878,7 @@ $td->runtest("check encryption", | ||
| 3878 | $td->NORMALIZE_NEWLINES); | 3878 | $td->NORMALIZE_NEWLINES); |
| 3879 | 3879 | ||
| 3880 | # Look at some actual V4 files | 3880 | # Look at some actual V4 files |
| 3881 | -$n_tests += 14; | 3881 | +$n_tests += 17; |
| 3882 | foreach my $d (['--force-V4', 'V4'], | 3882 | foreach my $d (['--force-V4', 'V4'], |
| 3883 | ['--cleartext-metadata', 'V4-clearmeta'], | 3883 | ['--cleartext-metadata', 'V4-clearmeta'], |
| 3884 | ['--use-aes=y', 'V4-aes'], | 3884 | ['--use-aes=y', 'V4-aes'], |
| @@ -3906,6 +3906,19 @@ $td->runtest("decrypt with crypt filter", | @@ -3906,6 +3906,19 @@ $td->runtest("decrypt with crypt filter", | ||
| 3906 | $td->runtest("check output", | 3906 | $td->runtest("check output", |
| 3907 | {$td->FILE => 'a.pdf'}, | 3907 | {$td->FILE => 'a.pdf'}, |
| 3908 | {$td->FILE => 'decrypted-crypt-filter.pdf'}); | 3908 | {$td->FILE => 'decrypted-crypt-filter.pdf'}); |
| 3909 | +$td->runtest("nontrivial crypt filter", | ||
| 3910 | + {$td->COMMAND => "qpdf --qdf --decrypt --static-id" . | ||
| 3911 | + " nontrivial-crypt-filter.pdf --password=asdfqwer a.pdf"}, | ||
| 3912 | + {$td->STRING => "", $td->EXIT_STATUS => 0}); | ||
| 3913 | +$td->runtest("check output", | ||
| 3914 | + {$td->FILE => 'a.pdf'}, | ||
| 3915 | + {$td->FILE => 'nontrivial-crypt-filter-decrypted.pdf'}); | ||
| 3916 | +$td->runtest("show nontrivial EFF", | ||
| 3917 | + {$td->COMMAND => "qpdf --show-encryption" . | ||
| 3918 | + " nontrivial-crypt-filter.pdf --password=asdfqwer"}, | ||
| 3919 | + {$td->FILE => "nontrivial-crypt-filter.out", | ||
| 3920 | + $td->EXIT_STATUS => 0}, | ||
| 3921 | + $td->NORMALIZE_NEWLINES); | ||
| 3909 | 3922 | ||
| 3910 | # Copy encryption parameters | 3923 | # Copy encryption parameters |
| 3911 | $n_tests += 10; | 3924 | $n_tests += 10; |
qpdf/qtest/qpdf/indirect-r-arg.out
| 1 | +checking indirect-r-arg.pdf | ||
| 1 | WARNING: indirect-r-arg.pdf (object 1 0, offset 76): unknown token while reading object; treating as string | 2 | WARNING: indirect-r-arg.pdf (object 1 0, offset 76): unknown token while reading object; treating as string |
| 2 | WARNING: indirect-r-arg.pdf (object 1 0, offset 62): expected dictionary key but found non-name object; inserting key /QPDFFake1 | 3 | WARNING: indirect-r-arg.pdf (object 1 0, offset 62): expected dictionary key but found non-name object; inserting key /QPDFFake1 |
| 3 | WARNING: indirect-r-arg.pdf (object 1 0, offset 62): expected dictionary key but found non-name object; inserting key /QPDFFake2 | 4 | WARNING: indirect-r-arg.pdf (object 1 0, offset 62): expected dictionary key but found non-name object; inserting key /QPDFFake2 |
| 4 | -checking indirect-r-arg.pdf | ||
| 5 | PDF Version: 1.3 | 5 | PDF Version: 1.3 |
| 6 | File is not encrypted | 6 | File is not encrypted |
| 7 | File is not linearized | 7 | File is not linearized |
qpdf/qtest/qpdf/nontrivial-crypt-filter-decrypted.pdf
0 โ 100644
No preview for this file type
qpdf/qtest/qpdf/nontrivial-crypt-filter.out
0 โ 100644
| 1 | +R = 6 | ||
| 2 | +P = -1028 | ||
| 3 | +User password = asdfqwer | ||
| 4 | +Supplied password is owner password | ||
| 5 | +Supplied password is user password | ||
| 6 | +extract for accessibility: allowed | ||
| 7 | +extract for any purpose: allowed | ||
| 8 | +print low resolution: allowed | ||
| 9 | +print high resolution: allowed | ||
| 10 | +modify document assembly: not allowed | ||
| 11 | +modify forms: allowed | ||
| 12 | +modify annotations: allowed | ||
| 13 | +modify other: allowed | ||
| 14 | +modify anything: not allowed | ||
| 15 | +stream encryption method: none | ||
| 16 | +string encryption method: none | ||
| 17 | +file encryption method: AESv3 |
qpdf/qtest/qpdf/nontrivial-crypt-filter.pdf
0 โ 100644
No preview for this file type
qpdf/qtest/qpdf/obj0-check.out
| 1 | +checking obj0.pdf | ||
| 1 | WARNING: obj0.pdf: file is damaged | 2 | WARNING: obj0.pdf: file is damaged |
| 2 | WARNING: obj0.pdf (object 1 0, offset 77): expected n n obj | 3 | WARNING: obj0.pdf (object 1 0, offset 77): expected n n obj |
| 3 | WARNING: obj0.pdf: Attempting to reconstruct cross-reference table | 4 | WARNING: obj0.pdf: Attempting to reconstruct cross-reference table |
| 4 | -checking obj0.pdf | ||
| 5 | PDF Version: 1.3 | 5 | PDF Version: 1.3 |
| 6 | File is not encrypted | 6 | File is not encrypted |
| 7 | File is not linearized | 7 | File is not linearized |
qpdf/qtest/qpdf/test73.out
| 1 | -WARNING: closed input source: object 2/0: error reading object: QPDF operation attempted after closing input source | ||
| 2 | -test 73 done | 1 | +WARNING: closed input source: object 1/0: error reading object: QPDF operation attempted after closing input source |
| 2 | +closed input source: unable to find /Root dictionary |