Commit fad1399fd34df0e600a30b983e0542f816b770ca

Authored by m-holger
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&amp; 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  
... ...