Commit 9aef15899ece1235583e5520ccb64ca315affe79

Authored by m-holger
1 parent f52b9848

Refactor `QPDFWriter`: move encryption-related methods and flags to `QPDFWriter:…

…:Members`, update related logic, and remove obsolete declarations.
include/qpdf/QPDFWriter.hh
@@ -22,9 +22,17 @@ @@ -22,9 +22,17 @@
22 22
23 #include <qpdf/DLL.h> 23 #include <qpdf/DLL.h>
24 #include <qpdf/Types.h> 24 #include <qpdf/Types.h>
  25 +#include <qpdf/Constants.h>
  26 +
  27 +#include <qpdf/Buffer.hh>
  28 +#include <qpdf/PDFVersion.hh>
  29 +#include <qpdf/Pipeline.hh>
  30 +#include <qpdf/Pl_Buffer.hh>
  31 +#include <qpdf/QPDFObjGen.hh>
  32 +#include <qpdf/QPDFObjectHandle.hh>
  33 +#include <qpdf/QPDFXRefEntry.hh>
25 34
26 #include <bitset> 35 #include <bitset>
27 -#include <concepts>  
28 #include <cstdio> 36 #include <cstdio>
29 #include <functional> 37 #include <functional>
30 #include <list> 38 #include <list>
@@ -35,24 +43,7 @@ @@ -35,24 +43,7 @@
35 #include <string_view> 43 #include <string_view>
36 #include <vector> 44 #include <vector>
37 45
38 -#include <qpdf/Constants.h>  
39 -  
40 -#include <qpdf/Buffer.hh>  
41 -#include <qpdf/PDFVersion.hh>  
42 -#include <qpdf/Pipeline.hh>  
43 -#include <qpdf/Pl_Buffer.hh>  
44 -#include <qpdf/QPDFObjGen.hh>  
45 -#include <qpdf/QPDFObjectHandle.hh>  
46 -#include <qpdf/QPDFXRefEntry.hh>  
47 -  
48 -namespace qpdf::pl  
49 -{  
50 - struct Link;  
51 -}  
52 -  
53 class QPDF; 46 class QPDF;
54 -class Pl_Count;  
55 -class Pl_MD5;  
56 47
57 // This class implements a simple writer for saving QPDF objects to new PDF files. See comments 48 // This class implements a simple writer for saving QPDF objects to new PDF files. See comments
58 // through the header file for additional details. 49 // through the header file for additional details.
@@ -449,31 +440,8 @@ class QPDFWriter @@ -449,31 +440,8 @@ class QPDFWriter
449 class NewObjTable; 440 class NewObjTable;
450 441
451 private: 442 private:
452 - // flags used by unparseObject  
453 - static int const f_stream = 1 << 0;  
454 - static int const f_filtered = 1 << 1;  
455 - static int const f_in_ostream = 1 << 2;  
456 - static int const f_hex_string = 1 << 3;  
457 - static int const f_no_encryption = 1 << 4;  
458 -  
459 - enum trailer_e { t_normal, t_lin_first, t_lin_second };  
460 -  
461 - void interpretR3EncryptionParameters(  
462 - bool allow_accessibility,  
463 - bool allow_extract,  
464 - bool allow_assemble,  
465 - bool allow_annotate_and_form,  
466 - bool allow_form_filling,  
467 - bool allow_modify_other,  
468 - qpdf_r3_print_e print,  
469 - qpdf_r3_modify_e modify);  
470 - void setEncryptionParameters(char const* user_password, char const* owner_password);  
471 - void setEncryptionMinimumVersion();  
472 -  
473 class Members; 443 class Members;
474 444
475 - // Keep all member variables inside the Members object, which we dynamically allocate. This  
476 - // makes it possible to add new private members without breaking binary compatibility.  
477 std::shared_ptr<Members> m; 445 std::shared_ptr<Members> m;
478 }; 446 };
479 447
libqpdf/QPDFWriter.cc
@@ -11,7 +11,6 @@ @@ -11,7 +11,6 @@
11 #include <qpdf/Pl_PNGFilter.hh> 11 #include <qpdf/Pl_PNGFilter.hh>
12 #include <qpdf/Pl_RC4.hh> 12 #include <qpdf/Pl_RC4.hh>
13 #include <qpdf/Pl_StdioFile.hh> 13 #include <qpdf/Pl_StdioFile.hh>
14 -#include <qpdf/Pl_String.hh>  
15 #include <qpdf/QIntC.hh> 14 #include <qpdf/QIntC.hh>
16 #include <qpdf/QPDFObjectHandle_private.hh> 15 #include <qpdf/QPDFObjectHandle_private.hh>
17 #include <qpdf/QPDFObject_private.hh> 16 #include <qpdf/QPDFObject_private.hh>
@@ -22,6 +21,7 @@ @@ -22,6 +21,7 @@
22 #include <qpdf/Util.hh> 21 #include <qpdf/Util.hh>
23 22
24 #include <algorithm> 23 #include <algorithm>
  24 +#include <concepts>
25 #include <cstdlib> 25 #include <cstdlib>
26 #include <stdexcept> 26 #include <stdexcept>
27 27
@@ -265,6 +265,15 @@ class QPDFWriter::Members @@ -265,6 +265,15 @@ class QPDFWriter::Members
265 friend class QPDFWriter; 265 friend class QPDFWriter;
266 266
267 public: 267 public:
  268 + // flags used by unparseObject
  269 + static int const f_stream = 1 << 0;
  270 + static int const f_filtered = 1 << 1;
  271 + static int const f_in_ostream = 1 << 2;
  272 + static int const f_hex_string = 1 << 3;
  273 + static int const f_no_encryption = 1 << 4;
  274 +
  275 + enum trailer_e { t_normal, t_lin_first, t_lin_second };
  276 +
268 Members(QPDFWriter& w, QPDF& pdf) : 277 Members(QPDFWriter& w, QPDF& pdf) :
269 w(w), 278 w(w),
270 pdf(pdf), 279 pdf(pdf),
@@ -290,6 +299,17 @@ class QPDFWriter::Members @@ -290,6 +299,17 @@ class QPDFWriter::Members
290 void prepareFileForWrite(); 299 void prepareFileForWrite();
291 300
292 void disableIncompatibleEncryption(int major, int minor, int extension_level); 301 void disableIncompatibleEncryption(int major, int minor, int extension_level);
  302 + void interpretR3EncryptionParameters(
  303 + bool allow_accessibility,
  304 + bool allow_extract,
  305 + bool allow_assemble,
  306 + bool allow_annotate_and_form,
  307 + bool allow_form_filling,
  308 + bool allow_modify_other,
  309 + qpdf_r3_print_e print,
  310 + qpdf_r3_modify_e modify);
  311 + void setEncryptionParameters(char const* user_password, char const* owner_password);
  312 + void setEncryptionMinimumVersion();
293 void parseVersion(std::string const& version, int& major, int& minor) const; 313 void parseVersion(std::string const& version, int& major, int& minor) const;
294 int compareVersions(int major1, int minor1, int major2, int minor2) const; 314 int compareVersions(int major1, int minor1, int major2, int minor2) const;
295 void generateID(bool encrypted); 315 void generateID(bool encrypted);
@@ -752,7 +772,7 @@ QPDFWriter::setR2EncryptionParametersInsecure( @@ -752,7 +772,7 @@ QPDFWriter::setR2EncryptionParametersInsecure(
752 if (!allow_annotate) { 772 if (!allow_annotate) {
753 m->encryption->setP(6, false); 773 m->encryption->setP(6, false);
754 } 774 }
755 - setEncryptionParameters(user_password, owner_password); 775 + m->setEncryptionParameters(user_password, owner_password);
756 } 776 }
757 777
758 void 778 void
@@ -768,7 +788,7 @@ QPDFWriter::setR3EncryptionParametersInsecure( @@ -768,7 +788,7 @@ QPDFWriter::setR3EncryptionParametersInsecure(
768 qpdf_r3_print_e print) 788 qpdf_r3_print_e print)
769 { 789 {
770 m->encryption = std::make_unique<QPDF::EncryptionData>(2, 3, 16, true); 790 m->encryption = std::make_unique<QPDF::EncryptionData>(2, 3, 16, true);
771 - interpretR3EncryptionParameters( 791 + m->interpretR3EncryptionParameters(
772 allow_accessibility, 792 allow_accessibility,
773 allow_extract, 793 allow_extract,
774 allow_assemble, 794 allow_assemble,
@@ -777,7 +797,7 @@ QPDFWriter::setR3EncryptionParametersInsecure( @@ -777,7 +797,7 @@ QPDFWriter::setR3EncryptionParametersInsecure(
777 allow_modify_other, 797 allow_modify_other,
778 print, 798 print,
779 qpdf_r3m_all); 799 qpdf_r3m_all);
780 - setEncryptionParameters(user_password, owner_password); 800 + m->setEncryptionParameters(user_password, owner_password);
781 } 801 }
782 802
783 void 803 void
@@ -796,7 +816,7 @@ QPDFWriter::setR4EncryptionParametersInsecure( @@ -796,7 +816,7 @@ QPDFWriter::setR4EncryptionParametersInsecure(
796 { 816 {
797 m->encryption = std::make_unique<QPDF::EncryptionData>(4, 4, 16, encrypt_metadata); 817 m->encryption = std::make_unique<QPDF::EncryptionData>(4, 4, 16, encrypt_metadata);
798 m->encrypt_use_aes = use_aes; 818 m->encrypt_use_aes = use_aes;
799 - interpretR3EncryptionParameters( 819 + m->interpretR3EncryptionParameters(
800 allow_accessibility, 820 allow_accessibility,
801 allow_extract, 821 allow_extract,
802 allow_assemble, 822 allow_assemble,
@@ -805,7 +825,7 @@ QPDFWriter::setR4EncryptionParametersInsecure( @@ -805,7 +825,7 @@ QPDFWriter::setR4EncryptionParametersInsecure(
805 allow_modify_other, 825 allow_modify_other,
806 print, 826 print,
807 qpdf_r3m_all); 827 qpdf_r3m_all);
808 - setEncryptionParameters(user_password, owner_password); 828 + m->setEncryptionParameters(user_password, owner_password);
809 } 829 }
810 830
811 void 831 void
@@ -823,7 +843,7 @@ QPDFWriter::setR5EncryptionParameters( @@ -823,7 +843,7 @@ QPDFWriter::setR5EncryptionParameters(
823 { 843 {
824 m->encryption = std::make_unique<QPDF::EncryptionData>(5, 5, 32, encrypt_metadata); 844 m->encryption = std::make_unique<QPDF::EncryptionData>(5, 5, 32, encrypt_metadata);
825 m->encrypt_use_aes = true; 845 m->encrypt_use_aes = true;
826 - interpretR3EncryptionParameters( 846 + m->interpretR3EncryptionParameters(
827 allow_accessibility, 847 allow_accessibility,
828 allow_extract, 848 allow_extract,
829 allow_assemble, 849 allow_assemble,
@@ -832,7 +852,7 @@ QPDFWriter::setR5EncryptionParameters( @@ -832,7 +852,7 @@ QPDFWriter::setR5EncryptionParameters(
832 allow_modify_other, 852 allow_modify_other,
833 print, 853 print,
834 qpdf_r3m_all); 854 qpdf_r3m_all);
835 - setEncryptionParameters(user_password, owner_password); 855 + m->setEncryptionParameters(user_password, owner_password);
836 } 856 }
837 857
838 void 858 void
@@ -849,7 +869,7 @@ QPDFWriter::setR6EncryptionParameters( @@ -849,7 +869,7 @@ QPDFWriter::setR6EncryptionParameters(
849 bool encrypt_metadata) 869 bool encrypt_metadata)
850 { 870 {
851 m->encryption = std::make_unique<QPDF::EncryptionData>(5, 6, 32, encrypt_metadata); 871 m->encryption = std::make_unique<QPDF::EncryptionData>(5, 6, 32, encrypt_metadata);
852 - interpretR3EncryptionParameters( 872 + m->interpretR3EncryptionParameters(
853 allow_accessibility, 873 allow_accessibility,
854 allow_extract, 874 allow_extract,
855 allow_assemble, 875 allow_assemble,
@@ -859,11 +879,11 @@ QPDFWriter::setR6EncryptionParameters( @@ -859,11 +879,11 @@ QPDFWriter::setR6EncryptionParameters(
859 print, 879 print,
860 qpdf_r3m_all); 880 qpdf_r3m_all);
861 m->encrypt_use_aes = true; 881 m->encrypt_use_aes = true;
862 - setEncryptionParameters(user_password, owner_password); 882 + m->setEncryptionParameters(user_password, owner_password);
863 } 883 }
864 884
865 void 885 void
866 -QPDFWriter::interpretR3EncryptionParameters( 886 +QPDFWriter::Members::interpretR3EncryptionParameters(
867 bool allow_accessibility, 887 bool allow_accessibility,
868 bool allow_extract, 888 bool allow_extract,
869 bool allow_assemble, 889 bool allow_assemble,
@@ -902,21 +922,21 @@ QPDFWriter::interpretR3EncryptionParameters( @@ -902,21 +922,21 @@ QPDFWriter::interpretR3EncryptionParameters(
902 // 10: accessibility; ignored by readers, should always be set 922 // 10: accessibility; ignored by readers, should always be set
903 // 11: document assembly even if 4 is clear 923 // 11: document assembly even if 4 is clear
904 // 12: high-resolution printing 924 // 12: high-resolution printing
905 - if (!allow_accessibility && m->encryption->getR() <= 3) { 925 + if (!allow_accessibility && encryption->getR() <= 3) {
906 // Bit 10 is deprecated and should always be set. This used to mean accessibility. There 926 // Bit 10 is deprecated and should always be set. This used to mean accessibility. There
907 // is no way to disable accessibility with R > 3. 927 // is no way to disable accessibility with R > 3.
908 - m->encryption->setP(10, false); 928 + encryption->setP(10, false);
909 } 929 }
910 if (!allow_extract) { 930 if (!allow_extract) {
911 - m->encryption->setP(5, false); 931 + encryption->setP(5, false);
912 } 932 }
913 933
914 switch (print) { 934 switch (print) {
915 case qpdf_r3p_none: 935 case qpdf_r3p_none:
916 - m->encryption->setP(3, false); // any printing 936 + encryption->setP(3, false); // any printing
917 [[fallthrough]]; 937 [[fallthrough]];
918 case qpdf_r3p_low: 938 case qpdf_r3p_low:
919 - m->encryption->setP(12, false); // high resolution printing 939 + encryption->setP(12, false); // high resolution printing
920 [[fallthrough]]; 940 [[fallthrough]];
921 case qpdf_r3p_full: 941 case qpdf_r3p_full:
922 break; 942 break;
@@ -930,16 +950,16 @@ QPDFWriter::interpretR3EncryptionParameters( @@ -930,16 +950,16 @@ QPDFWriter::interpretR3EncryptionParameters(
930 // NOT EXERCISED IN TEST SUITE 950 // NOT EXERCISED IN TEST SUITE
931 switch (modify) { 951 switch (modify) {
932 case qpdf_r3m_none: 952 case qpdf_r3m_none:
933 - m->encryption->setP(11, false); // document assembly 953 + encryption->setP(11, false); // document assembly
934 [[fallthrough]]; 954 [[fallthrough]];
935 case qpdf_r3m_assembly: 955 case qpdf_r3m_assembly:
936 - m->encryption->setP(9, false); // filling in form fields 956 + encryption->setP(9, false); // filling in form fields
937 [[fallthrough]]; 957 [[fallthrough]];
938 case qpdf_r3m_form: 958 case qpdf_r3m_form:
939 - m->encryption->setP(6, false); // modify annotations, fill in form fields 959 + encryption->setP(6, false); // modify annotations, fill in form fields
940 [[fallthrough]]; 960 [[fallthrough]];
941 case qpdf_r3m_annotate: 961 case qpdf_r3m_annotate:
942 - m->encryption->setP(4, false); // other modifications 962 + encryption->setP(4, false); // other modifications
943 [[fallthrough]]; 963 [[fallthrough]];
944 case qpdf_r3m_all: 964 case qpdf_r3m_all:
945 break; 965 break;
@@ -948,25 +968,25 @@ QPDFWriter::interpretR3EncryptionParameters( @@ -948,25 +968,25 @@ QPDFWriter::interpretR3EncryptionParameters(
948 // END NOT EXERCISED IN TEST SUITE 968 // END NOT EXERCISED IN TEST SUITE
949 969
950 if (!allow_assemble) { 970 if (!allow_assemble) {
951 - m->encryption->setP(11, false); 971 + encryption->setP(11, false);
952 } 972 }
953 if (!allow_annotate_and_form) { 973 if (!allow_annotate_and_form) {
954 - m->encryption->setP(6, false); 974 + encryption->setP(6, false);
955 } 975 }
956 if (!allow_form_filling) { 976 if (!allow_form_filling) {
957 - m->encryption->setP(9, false); 977 + encryption->setP(9, false);
958 } 978 }
959 if (!allow_modify_other) { 979 if (!allow_modify_other) {
960 - m->encryption->setP(4, false); 980 + encryption->setP(4, false);
961 } 981 }
962 } 982 }
963 983
964 void 984 void
965 -QPDFWriter::setEncryptionParameters(char const* user_password, char const* owner_password) 985 +QPDFWriter::Members::setEncryptionParameters(char const* user_password, char const* owner_password)
966 { 986 {
967 - m->generateID(true);  
968 - m->encryption->setId1(m->id1);  
969 - m->encryption_key = m->encryption->compute_parameters(user_password, owner_password); 987 + generateID(true);
  988 + encryption->setId1(id1);
  989 + encryption_key = encryption->compute_parameters(user_password, owner_password);
970 setEncryptionMinimumVersion(); 990 setEncryptionMinimumVersion();
971 } 991 }
972 992
@@ -1018,7 +1038,7 @@ QPDFWriter::Members::copyEncryptionParameters(QPDF&amp; qpdf) @@ -1018,7 +1038,7 @@ QPDFWriter::Members::copyEncryptionParameters(QPDF&amp; qpdf)
1018 encrypt_metadata); 1038 encrypt_metadata);
1019 encryption_key = V >= 5 ? qpdf.getEncryptionKey() 1039 encryption_key = V >= 5 ? qpdf.getEncryptionKey()
1020 : encryption->compute_encryption_key(qpdf.getPaddedUserPassword()); 1040 : encryption->compute_encryption_key(qpdf.getPaddedUserPassword());
1021 - w.setEncryptionMinimumVersion(); 1041 + setEncryptionMinimumVersion();
1022 } 1042 }
1023 } 1043 }
1024 1044
@@ -1092,19 +1112,19 @@ QPDFWriter::Members::compareVersions(int major1, int minor1, int major2, int min @@ -1092,19 +1112,19 @@ QPDFWriter::Members::compareVersions(int major1, int minor1, int major2, int min
1092 } 1112 }
1093 1113
1094 void 1114 void
1095 -QPDFWriter::setEncryptionMinimumVersion() 1115 +QPDFWriter::Members::setEncryptionMinimumVersion()
1096 { 1116 {
1097 - auto const R = m->encryption->getR(); 1117 + auto const R = encryption->getR();
1098 if (R >= 6) { 1118 if (R >= 6) {
1099 - setMinimumPDFVersion("1.7", 8); 1119 + w.setMinimumPDFVersion("1.7", 8);
1100 } else if (R == 5) { 1120 } else if (R == 5) {
1101 - setMinimumPDFVersion("1.7", 3); 1121 + w.setMinimumPDFVersion("1.7", 3);
1102 } else if (R == 4) { 1122 } else if (R == 4) {
1103 - setMinimumPDFVersion(m->encrypt_use_aes ? "1.6" : "1.5"); 1123 + w.setMinimumPDFVersion(encrypt_use_aes ? "1.6" : "1.5");
1104 } else if (R == 3) { 1124 } else if (R == 3) {
1105 - setMinimumPDFVersion("1.4"); 1125 + w.setMinimumPDFVersion("1.4");
1106 } else { 1126 } else {
1107 - setMinimumPDFVersion("1.3"); 1127 + w.setMinimumPDFVersion("1.3");
1108 } 1128 }
1109 } 1129 }
1110 1130