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