Commit fad1399fd34df0e600a30b983e0542f816b770ca
1 parent
2055837e
Refactor `QPDFWriter` to replace `m->encrypted` with `m->encryption`, streamline…
… encryption handling, and reduce redundancy across methods.
Showing
1 changed file
with
41 additions
and
45 deletions
libqpdf/QPDFWriter.cc
| ... | ... | @@ -81,7 +81,6 @@ class QPDFWriter::Members |
| 81 | 81 | bool static_id{false}; |
| 82 | 82 | bool suppress_original_object_ids{false}; |
| 83 | 83 | bool direct_stream_lengths{true}; |
| 84 | - bool encrypted{false}; | |
| 85 | 84 | bool preserve_encryption{true}; |
| 86 | 85 | bool linearized{false}; |
| 87 | 86 | bool pclm{false}; |
| ... | ... | @@ -713,39 +712,37 @@ QPDFWriter::copyEncryptionParameters(QPDF& qpdf) |
| 713 | 712 | void |
| 714 | 713 | QPDFWriter::disableIncompatibleEncryption(int major, int minor, int extension_level) |
| 715 | 714 | { |
| 716 | - if (!m->encrypted) { | |
| 715 | + if (!m->encryption) { | |
| 717 | 716 | return; |
| 718 | 717 | } |
| 719 | - | |
| 720 | - bool disable = false; | |
| 721 | 718 | if (compareVersions(major, minor, 1, 3) < 0) { |
| 722 | - disable = true; | |
| 723 | - } else { | |
| 724 | - int V = QUtil::string_to_int(m->encryption_dictionary["/V"].c_str()); | |
| 725 | - int R = QUtil::string_to_int(m->encryption_dictionary["/R"].c_str()); | |
| 726 | - if (compareVersions(major, minor, 1, 4) < 0) { | |
| 727 | - if ((V > 1) || (R > 2)) { | |
| 728 | - disable = true; | |
| 729 | - } | |
| 730 | - } else if (compareVersions(major, minor, 1, 5) < 0) { | |
| 731 | - if ((V > 2) || (R > 3)) { | |
| 732 | - disable = true; | |
| 733 | - } | |
| 734 | - } else if (compareVersions(major, minor, 1, 6) < 0) { | |
| 735 | - if (m->encrypt_use_aes) { | |
| 736 | - disable = true; | |
| 737 | - } | |
| 738 | - } else if ( | |
| 739 | - (compareVersions(major, minor, 1, 7) < 0) || | |
| 740 | - ((compareVersions(major, minor, 1, 7) == 0) && extension_level < 3)) { | |
| 741 | - if ((V >= 5) || (R >= 5)) { | |
| 742 | - disable = true; | |
| 743 | - } | |
| 719 | + m->encryption = nullptr; | |
| 720 | + return; | |
| 721 | + } | |
| 722 | + int V = m->encryption->getV(); | |
| 723 | + int R = m->encryption->getR(); | |
| 724 | + if (compareVersions(major, minor, 1, 4) < 0) { | |
| 725 | + if (V > 1 || R > 2) { | |
| 726 | + m->encryption = nullptr; | |
| 727 | + } | |
| 728 | + } else if (compareVersions(major, minor, 1, 5) < 0) { | |
| 729 | + if (V > 2 || R > 3) { | |
| 730 | + m->encryption = nullptr; | |
| 731 | + } | |
| 732 | + } else if (compareVersions(major, minor, 1, 6) < 0) { | |
| 733 | + if (m->encrypt_use_aes) { | |
| 734 | + m->encryption = nullptr; | |
| 735 | + } | |
| 736 | + } else if ( | |
| 737 | + (compareVersions(major, minor, 1, 7) < 0) || | |
| 738 | + ((compareVersions(major, minor, 1, 7) == 0) && extension_level < 3)) { | |
| 739 | + if (V >= 5 || R >= 5) { | |
| 740 | + m->encryption = nullptr; | |
| 744 | 741 | } |
| 745 | 742 | } |
| 746 | - if (disable) { | |
| 743 | + | |
| 744 | + if (!m->encryption) { | |
| 747 | 745 | QTC::TC("qpdf", "QPDFWriter forced version disabled encryption"); |
| 748 | - m->encrypted = false; | |
| 749 | 746 | } |
| 750 | 747 | } |
| 751 | 748 | |
| ... | ... | @@ -828,7 +825,6 @@ QPDFWriter::setEncryptionParametersInternal( |
| 828 | 825 | " /Length " + std::string((V < 5) ? "16" : "32") + " >> >>"; |
| 829 | 826 | } |
| 830 | 827 | |
| 831 | - m->encrypted = true; | |
| 832 | 828 | if (V < 5) { |
| 833 | 829 | m->encryption_key = enc.compute_encryption_key(user_password); |
| 834 | 830 | } else { |
| ... | ... | @@ -839,7 +835,7 @@ QPDFWriter::setEncryptionParametersInternal( |
| 839 | 835 | void |
| 840 | 836 | QPDFWriter::setDataKey(int objid) |
| 841 | 837 | { |
| 842 | - if (m->encrypted) { | |
| 838 | + if (m->encryption) { | |
| 843 | 839 | m->cur_data_key = QPDF::compute_data_key( |
| 844 | 840 | m->encryption_key, |
| 845 | 841 | objid, |
| ... | ... | @@ -981,7 +977,7 @@ QPDFWriter::PipelinePopper::~PipelinePopper() |
| 981 | 977 | void |
| 982 | 978 | QPDFWriter::adjustAESStreamLength(size_t& length) |
| 983 | 979 | { |
| 984 | - if (m->encrypted && (!m->cur_data_key.empty()) && m->encrypt_use_aes) { | |
| 980 | + if (m->encryption && !m->cur_data_key.empty() && m->encrypt_use_aes) { | |
| 985 | 981 | // Stream length will be padded with 1 to 16 bytes to end up as a multiple of 16. It will |
| 986 | 982 | // also be prepended by 16 bits of random data. |
| 987 | 983 | length += 32 - (length & 0xf); |
| ... | ... | @@ -991,7 +987,7 @@ QPDFWriter::adjustAESStreamLength(size_t& length) |
| 991 | 987 | void |
| 992 | 988 | QPDFWriter::pushEncryptionFilter(PipelinePopper& pp) |
| 993 | 989 | { |
| 994 | - if (m->encrypted && (!m->cur_data_key.empty())) { | |
| 990 | + if (m->encryption && !m->cur_data_key.empty()) { | |
| 995 | 991 | Pipeline* p = nullptr; |
| 996 | 992 | if (m->encrypt_use_aes) { |
| 997 | 993 | p = new Pl_AES_PDF( |
| ... | ... | @@ -1234,7 +1230,7 @@ QPDFWriter::writeTrailer( |
| 1234 | 1230 | |
| 1235 | 1231 | if (which != t_lin_second) { |
| 1236 | 1232 | // Write reference to encryption dictionary |
| 1237 | - if (m->encrypted) { | |
| 1233 | + if (m->encryption) { | |
| 1238 | 1234 | writeString(" /Encrypt "); |
| 1239 | 1235 | writeString(std::to_string(m->encryption_dict_objid)); |
| 1240 | 1236 | writeString(" 0 R"); |
| ... | ... | @@ -1283,7 +1279,7 @@ QPDFWriter::willFilterStream( |
| 1283 | 1279 | bool normalize = false; |
| 1284 | 1280 | bool uncompress = false; |
| 1285 | 1281 | if (filter_on_write && is_root_metadata && |
| 1286 | - (!m->encrypted || !m->encryption->getEncryptMetadata())) { | |
| 1282 | + (!m->encryption || !m->encryption->getEncryptMetadata())) { | |
| 1287 | 1283 | QTC::TC("qpdf", "QPDFWriter not compressing metadata"); |
| 1288 | 1284 | filter = true; |
| 1289 | 1285 | compress_stream = false; |
| ... | ... | @@ -1571,7 +1567,7 @@ QPDFWriter::unparseObject( |
| 1571 | 1567 | QPDFObjectHandle stream_dict = object.getDict(); |
| 1572 | 1568 | |
| 1573 | 1569 | m->cur_stream_length = stream_data.size(); |
| 1574 | - if (is_metadata && m->encrypted && !m->encryption->getEncryptMetadata()) { | |
| 1570 | + if (is_metadata && m->encryption && !m->encryption->getEncryptMetadata()) { | |
| 1575 | 1571 | // Don't encrypt stream data for the metadata stream |
| 1576 | 1572 | m->cur_data_key.clear(); |
| 1577 | 1573 | } |
| ... | ... | @@ -1593,8 +1589,8 @@ QPDFWriter::unparseObject( |
| 1593 | 1589 | } |
| 1594 | 1590 | } else if (tc == ::ot_string) { |
| 1595 | 1591 | std::string val; |
| 1596 | - if (m->encrypted && (!(flags & f_in_ostream)) && (!(flags & f_no_encryption)) && | |
| 1597 | - (!m->cur_data_key.empty())) { | |
| 1592 | + if (m->encryption && !(flags & f_in_ostream) && !(flags & f_no_encryption) && | |
| 1593 | + !m->cur_data_key.empty()) { | |
| 1598 | 1594 | val = object.getStringValue(); |
| 1599 | 1595 | if (m->encrypt_use_aes) { |
| 1600 | 1596 | Pl_Buffer bufpl("encrypted string"); |
| ... | ... | @@ -1777,7 +1773,7 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) |
| 1777 | 1773 | writeStringQDF("\n"); |
| 1778 | 1774 | writeStringNoQDF(" "); |
| 1779 | 1775 | writeString(">>\nstream\n"); |
| 1780 | - if (m->encrypted) { | |
| 1776 | + if (m->encryption) { | |
| 1781 | 1777 | QTC::TC("qpdf", "QPDFWriter encrypt object stream"); |
| 1782 | 1778 | } |
| 1783 | 1779 | { |
| ... | ... | @@ -2134,7 +2130,7 @@ QPDFWriter::doWriteSetup() |
| 2134 | 2130 | if (m->pclm) { |
| 2135 | 2131 | m->stream_decode_level = qpdf_dl_none; |
| 2136 | 2132 | m->compress_streams = false; |
| 2137 | - m->encrypted = false; | |
| 2133 | + m->encryption = nullptr; | |
| 2138 | 2134 | } |
| 2139 | 2135 | |
| 2140 | 2136 | if (m->qdf_mode) { |
| ... | ... | @@ -2149,7 +2145,7 @@ QPDFWriter::doWriteSetup() |
| 2149 | 2145 | } |
| 2150 | 2146 | } |
| 2151 | 2147 | |
| 2152 | - if (m->encrypted) { | |
| 2148 | + if (m->encryption) { | |
| 2153 | 2149 | // Encryption has been explicitly set |
| 2154 | 2150 | m->preserve_encryption = false; |
| 2155 | 2151 | } else if (m->normalize_content || !m->compress_streams || m->pclm || m->qdf_mode) { |
| ... | ... | @@ -2213,7 +2209,7 @@ QPDFWriter::doWriteSetup() |
| 2213 | 2209 | } |
| 2214 | 2210 | } |
| 2215 | 2211 | |
| 2216 | - if (m->linearized || m->encrypted) { | |
| 2212 | + if (m->linearized || m->encryption) { | |
| 2217 | 2213 | // The document catalog is not allowed to be compressed in linearized files either. It |
| 2218 | 2214 | // also appears that Adobe Reader 8.0.0 has a bug that prevents it from being able to |
| 2219 | 2215 | // handle encrypted files with compressed document catalogs, so we disable them in that |
| ... | ... | @@ -2382,7 +2378,7 @@ QPDFWriter::writeHintStream(int hint_id) |
| 2382 | 2378 | writeString(std::to_string(hlen)); |
| 2383 | 2379 | writeString(" >>\nstream\n"); |
| 2384 | 2380 | |
| 2385 | - if (m->encrypted) { | |
| 2381 | + if (m->encryption) { | |
| 2386 | 2382 | QTC::TC("qpdf", "QPDFWriter encrypted hint stream"); |
| 2387 | 2383 | } |
| 2388 | 2384 | char last_char = hint_buffer.empty() ? '\0' : hint_buffer.back(); |
| ... | ... | @@ -2653,7 +2649,7 @@ QPDFWriter::writeLinearized() |
| 2653 | 2649 | int part4_first_obj = m->next_objid; |
| 2654 | 2650 | m->next_objid += QIntC::to_int(part4.size()); |
| 2655 | 2651 | int after_part4 = m->next_objid; |
| 2656 | - if (m->encrypted) { | |
| 2652 | + if (m->encryption) { | |
| 2657 | 2653 | m->encryption_dict_objid = m->next_objid++; |
| 2658 | 2654 | } |
| 2659 | 2655 | int hint_id = m->next_objid++; |
| ... | ... | @@ -2838,7 +2834,7 @@ QPDFWriter::writeLinearized() |
| 2838 | 2834 | } |
| 2839 | 2835 | writeObject(cur_object); |
| 2840 | 2836 | if (cur_object.getObjectID() == part4_end_marker) { |
| 2841 | - if (m->encrypted) { | |
| 2837 | + if (m->encryption) { | |
| 2842 | 2838 | writeEncryptionDictionary(); |
| 2843 | 2839 | } |
| 2844 | 2840 | if (pass == 1) { |
| ... | ... | @@ -3062,7 +3058,7 @@ QPDFWriter::writeStandard() |
| 3062 | 3058 | } |
| 3063 | 3059 | |
| 3064 | 3060 | // Write out the encryption dictionary, if any |
| 3065 | - if (m->encrypted) { | |
| 3061 | + if (m->encryption) { | |
| 3066 | 3062 | writeEncryptionDictionary(); |
| 3067 | 3063 | } |
| 3068 | 3064 | ... | ... |