Commit 78fc0d1b3b65b4c77e3836f3a3dd585aeb83fdfa
1 parent
c5efd0c3
Refactor `QPDF_encryption::decryptStream`: streamline handling of `/Type` and `/…
…DecodeParms` using `Name`, `Dictionary`, and `Array` for improved clarity and consistency, and remove unused test coverage entries.
Showing
2 changed files
with
20 additions
and
39 deletions
libqpdf/QPDF_encryption.cc
| ... | ... | @@ -931,12 +931,7 @@ QPDF::decryptStream( |
| 931 | 931 | bool is_root_metadata, |
| 932 | 932 | std::unique_ptr<Pipeline>& decrypt_pipeline) |
| 933 | 933 | { |
| 934 | - std::string type; | |
| 935 | - if (stream_dict.getKey("/Type").isName()) { | |
| 936 | - type = stream_dict.getKey("/Type").getName(); | |
| 937 | - } | |
| 938 | - if (type == "/XRef") { | |
| 939 | - QTC::TC("qpdf", "QPDF_encryption xref stream from encrypted file"); | |
| 934 | + if (Name(stream_dict["/Type"]) == "/XRef") { | |
| 940 | 935 | return; |
| 941 | 936 | } |
| 942 | 937 | bool use_aes = false; |
| ... | ... | @@ -945,26 +940,20 @@ QPDF::decryptStream( |
| 945 | 940 | std::string method_source = "/StmF from /Encrypt dictionary"; |
| 946 | 941 | |
| 947 | 942 | if (stream_dict.getKey("/Filter").isOrHasName("/Crypt")) { |
| 948 | - if (stream_dict.getKey("/DecodeParms").isDictionary()) { | |
| 949 | - QPDFObjectHandle decode_parms = stream_dict.getKey("/DecodeParms"); | |
| 950 | - if (decode_parms.isDictionaryOfType("/CryptFilterDecodeParms")) { | |
| 951 | - QTC::TC("qpdf", "QPDF_encryption stream crypt filter"); | |
| 952 | - method = encp->interpretCF(decode_parms.getKey("/Name")); | |
| 943 | + if (Dictionary decode_parms = stream_dict["/DecodeParms"]) { | |
| 944 | + if (Name(decode_parms["/Type"]) == "/CryptFilterDecodeParms") { | |
| 945 | + method = encp->interpretCF(decode_parms["/Name"]); | |
| 953 | 946 | method_source = "stream's Crypt decode parameters"; |
| 954 | 947 | } |
| 955 | - } else if ( | |
| 956 | - stream_dict.getKey("/DecodeParms").isArray() && | |
| 957 | - stream_dict.getKey("/Filter").isArray()) { | |
| 958 | - auto filter = stream_dict.getKey("/Filter"); | |
| 959 | - auto decode = stream_dict.getKey("/DecodeParms"); | |
| 948 | + } else { | |
| 949 | + Array filter = stream_dict["/Filter"]; | |
| 950 | + Array decode = stream_dict.getKey("/DecodeParms"); | |
| 960 | 951 | if (filter.size() == decode.size()) { |
| 961 | - int i = 0; | |
| 962 | - for (auto const& item: filter.as_array()) { | |
| 963 | - if (item.isNameAndEquals("/Crypt")) { | |
| 964 | - auto crypt_params = decode.getArrayItem(i); | |
| 965 | - if (crypt_params.isDictionary() && | |
| 966 | - crypt_params.getKey("/Name").isName()) { | |
| 967 | - method = encp->interpretCF(crypt_params.getKey("/Name")); | |
| 952 | + size_t i = 0; | |
| 953 | + for (Name item: filter) { | |
| 954 | + if (item == "/Crypt") { | |
| 955 | + if (Name name = decode[i]["/Name"]) { | |
| 956 | + method = encp->interpretCF(name); | |
| 968 | 957 | method_source = "stream's Crypt decode parameters (array)"; |
| 969 | 958 | } |
| 970 | 959 | break; |
| ... | ... | @@ -976,8 +965,7 @@ QPDF::decryptStream( |
| 976 | 965 | } |
| 977 | 966 | |
| 978 | 967 | if (method == e_unknown) { |
| 979 | - if ((!encp->encrypt_metadata) && is_root_metadata) { | |
| 980 | - QTC::TC("qpdf", "QPDF_encryption cleartext metadata"); | |
| 968 | + if (!encp->encrypt_metadata && is_root_metadata) { | |
| 981 | 969 | method = e_none; |
| 982 | 970 | } else { |
| 983 | 971 | method = encp->cf_stream; |
| ... | ... | @@ -1002,13 +990,13 @@ QPDF::decryptStream( |
| 1002 | 990 | |
| 1003 | 991 | default: |
| 1004 | 992 | // filter local to this stream. |
| 1005 | - qpdf_for_warning.warn(QPDFExc( | |
| 1006 | - qpdf_e_damaged_pdf, | |
| 1007 | - file->getName(), | |
| 1008 | - "", | |
| 1009 | - file->getLastOffset(), | |
| 1010 | - "unknown encryption filter for streams (check " + method_source + | |
| 1011 | - "); streams may be decrypted improperly")); | |
| 993 | + qpdf_for_warning.warn( | |
| 994 | + {qpdf_e_damaged_pdf, | |
| 995 | + file->getName(), | |
| 996 | + "", | |
| 997 | + file->getLastOffset(), | |
| 998 | + "unknown encryption filter for streams (check " + method_source + | |
| 999 | + "); streams may be decrypted improperly"}); | |
| 1012 | 1000 | // To avoid repeated warnings, reset cf_stream. Assume we'd want to use AES if V == 4. |
| 1013 | 1001 | encp->cf_stream = e_aes; |
| 1014 | 1002 | use_aes = true; |
| ... | ... | @@ -1017,11 +1005,9 @@ QPDF::decryptStream( |
| 1017 | 1005 | } |
| 1018 | 1006 | std::string key = getKeyForObject(encp, og, use_aes); |
| 1019 | 1007 | if (use_aes) { |
| 1020 | - QTC::TC("qpdf", "QPDF_encryption aes decode stream"); | |
| 1021 | 1008 | decrypt_pipeline = |
| 1022 | 1009 | std::make_unique<Pl_AES_PDF>("AES stream decryption", pipeline, false, key); |
| 1023 | 1010 | } else { |
| 1024 | - QTC::TC("qpdf", "QPDF_encryption rc4 decode stream"); | |
| 1025 | 1011 | decrypt_pipeline = std::make_unique<Pl_RC4>("RC4 stream decryption", pipeline, key); |
| 1026 | 1012 | } |
| 1027 | 1013 | pipeline = decrypt_pipeline.get(); | ... | ... |
qpdf/qpdf.testcov
| ... | ... | @@ -96,7 +96,6 @@ QPDF recovered stream length 0 |
| 96 | 96 | QPDF found wrong endstream in recovery 0 |
| 97 | 97 | QPDF_Stream pipeStreamData with null pipeline 0 |
| 98 | 98 | QPDFWriter not recompressing /FlateDecode 0 |
| 99 | -QPDF_encryption xref stream from encrypted file 0 | |
| 100 | 99 | QPDFJob unable to filter 0 |
| 101 | 100 | QUtil non-trivial UTF-16 0 |
| 102 | 101 | QPDF xref overwrite invalid objgen 0 |
| ... | ... | @@ -141,16 +140,12 @@ qpdf-c called qpdf_set_minimum_pdf_version 0 |
| 141 | 140 | qpdf-c called qpdf_force_pdf_version 0 |
| 142 | 141 | qpdf-c called qpdf_init_write multiple times 0 |
| 143 | 142 | QPDF_encryption rc4 decode string 0 |
| 144 | -QPDF_encryption rc4 decode stream 0 | |
| 145 | 143 | QPDFWriter not compressing metadata 0 |
| 146 | 144 | QPDF_encryption aes decode string 0 |
| 147 | -QPDF_encryption cleartext metadata 0 | |
| 148 | -QPDF_encryption aes decode stream 0 | |
| 149 | 145 | QPDFWriter forcing object stream disable 0 |
| 150 | 146 | QPDFWriter forced version disabled encryption 0 |
| 151 | 147 | qpdf-c called qpdf_set_r4_encryption_parameters_insecure 0 |
| 152 | 148 | qpdf-c called qpdf_set_static_aes_IV 0 |
| 153 | -QPDF_encryption stream crypt filter 0 | |
| 154 | 149 | QPDF ERR object stream with wrong type 0 |
| 155 | 150 | QPDF object gone after xref reconstruction 0 |
| 156 | 151 | qpdf-c called qpdf_has_error 0 | ... | ... |