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,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&amp; length) @@ -991,7 +987,7 @@ QPDFWriter::adjustAESStreamLength(size_t&amp; 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