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 22  
23 23 #include <qpdf/DLL.h>
24 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 35 #include <bitset>
27   -#include <concepts>
28 36 #include <cstdio>
29 37 #include <functional>
30 38 #include <list>
... ... @@ -35,24 +43,7 @@
35 43 #include <string_view>
36 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 46 class QPDF;
54   -class Pl_Count;
55   -class Pl_MD5;
56 47  
57 48 // This class implements a simple writer for saving QPDF objects to new PDF files. See comments
58 49 // through the header file for additional details.
... ... @@ -449,31 +440,8 @@ class QPDFWriter
449 440 class NewObjTable;
450 441  
451 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 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 445 std::shared_ptr<Members> m;
478 446 };
479 447  
... ...
libqpdf/QPDFWriter.cc
... ... @@ -11,7 +11,6 @@
11 11 #include <qpdf/Pl_PNGFilter.hh>
12 12 #include <qpdf/Pl_RC4.hh>
13 13 #include <qpdf/Pl_StdioFile.hh>
14   -#include <qpdf/Pl_String.hh>
15 14 #include <qpdf/QIntC.hh>
16 15 #include <qpdf/QPDFObjectHandle_private.hh>
17 16 #include <qpdf/QPDFObject_private.hh>
... ... @@ -22,6 +21,7 @@
22 21 #include <qpdf/Util.hh>
23 22  
24 23 #include <algorithm>
  24 +#include <concepts>
25 25 #include <cstdlib>
26 26 #include <stdexcept>
27 27  
... ... @@ -265,6 +265,15 @@ class QPDFWriter::Members
265 265 friend class QPDFWriter;
266 266  
267 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 277 Members(QPDFWriter& w, QPDF& pdf) :
269 278 w(w),
270 279 pdf(pdf),
... ... @@ -290,6 +299,17 @@ class QPDFWriter::Members
290 299 void prepareFileForWrite();
291 300  
292 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 313 void parseVersion(std::string const& version, int& major, int& minor) const;
294 314 int compareVersions(int major1, int minor1, int major2, int minor2) const;
295 315 void generateID(bool encrypted);
... ... @@ -752,7 +772,7 @@ QPDFWriter::setR2EncryptionParametersInsecure(
752 772 if (!allow_annotate) {
753 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 778 void
... ... @@ -768,7 +788,7 @@ QPDFWriter::setR3EncryptionParametersInsecure(
768 788 qpdf_r3_print_e print)
769 789 {
770 790 m->encryption = std::make_unique<QPDF::EncryptionData>(2, 3, 16, true);
771   - interpretR3EncryptionParameters(
  791 + m->interpretR3EncryptionParameters(
772 792 allow_accessibility,
773 793 allow_extract,
774 794 allow_assemble,
... ... @@ -777,7 +797,7 @@ QPDFWriter::setR3EncryptionParametersInsecure(
777 797 allow_modify_other,
778 798 print,
779 799 qpdf_r3m_all);
780   - setEncryptionParameters(user_password, owner_password);
  800 + m->setEncryptionParameters(user_password, owner_password);
781 801 }
782 802  
783 803 void
... ... @@ -796,7 +816,7 @@ QPDFWriter::setR4EncryptionParametersInsecure(
796 816 {
797 817 m->encryption = std::make_unique<QPDF::EncryptionData>(4, 4, 16, encrypt_metadata);
798 818 m->encrypt_use_aes = use_aes;
799   - interpretR3EncryptionParameters(
  819 + m->interpretR3EncryptionParameters(
800 820 allow_accessibility,
801 821 allow_extract,
802 822 allow_assemble,
... ... @@ -805,7 +825,7 @@ QPDFWriter::setR4EncryptionParametersInsecure(
805 825 allow_modify_other,
806 826 print,
807 827 qpdf_r3m_all);
808   - setEncryptionParameters(user_password, owner_password);
  828 + m->setEncryptionParameters(user_password, owner_password);
809 829 }
810 830  
811 831 void
... ... @@ -823,7 +843,7 @@ QPDFWriter::setR5EncryptionParameters(
823 843 {
824 844 m->encryption = std::make_unique<QPDF::EncryptionData>(5, 5, 32, encrypt_metadata);
825 845 m->encrypt_use_aes = true;
826   - interpretR3EncryptionParameters(
  846 + m->interpretR3EncryptionParameters(
827 847 allow_accessibility,
828 848 allow_extract,
829 849 allow_assemble,
... ... @@ -832,7 +852,7 @@ QPDFWriter::setR5EncryptionParameters(
832 852 allow_modify_other,
833 853 print,
834 854 qpdf_r3m_all);
835   - setEncryptionParameters(user_password, owner_password);
  855 + m->setEncryptionParameters(user_password, owner_password);
836 856 }
837 857  
838 858 void
... ... @@ -849,7 +869,7 @@ QPDFWriter::setR6EncryptionParameters(
849 869 bool encrypt_metadata)
850 870 {
851 871 m->encryption = std::make_unique<QPDF::EncryptionData>(5, 6, 32, encrypt_metadata);
852   - interpretR3EncryptionParameters(
  872 + m->interpretR3EncryptionParameters(
853 873 allow_accessibility,
854 874 allow_extract,
855 875 allow_assemble,
... ... @@ -859,11 +879,11 @@ QPDFWriter::setR6EncryptionParameters(
859 879 print,
860 880 qpdf_r3m_all);
861 881 m->encrypt_use_aes = true;
862   - setEncryptionParameters(user_password, owner_password);
  882 + m->setEncryptionParameters(user_password, owner_password);
863 883 }
864 884  
865 885 void
866   -QPDFWriter::interpretR3EncryptionParameters(
  886 +QPDFWriter::Members::interpretR3EncryptionParameters(
867 887 bool allow_accessibility,
868 888 bool allow_extract,
869 889 bool allow_assemble,
... ... @@ -902,21 +922,21 @@ QPDFWriter::interpretR3EncryptionParameters(
902 922 // 10: accessibility; ignored by readers, should always be set
903 923 // 11: document assembly even if 4 is clear
904 924 // 12: high-resolution printing
905   - if (!allow_accessibility && m->encryption->getR() <= 3) {
  925 + if (!allow_accessibility && encryption->getR() <= 3) {
906 926 // Bit 10 is deprecated and should always be set. This used to mean accessibility. There
907 927 // is no way to disable accessibility with R > 3.
908   - m->encryption->setP(10, false);
  928 + encryption->setP(10, false);
909 929 }
910 930 if (!allow_extract) {
911   - m->encryption->setP(5, false);
  931 + encryption->setP(5, false);
912 932 }
913 933  
914 934 switch (print) {
915 935 case qpdf_r3p_none:
916   - m->encryption->setP(3, false); // any printing
  936 + encryption->setP(3, false); // any printing
917 937 [[fallthrough]];
918 938 case qpdf_r3p_low:
919   - m->encryption->setP(12, false); // high resolution printing
  939 + encryption->setP(12, false); // high resolution printing
920 940 [[fallthrough]];
921 941 case qpdf_r3p_full:
922 942 break;
... ... @@ -930,16 +950,16 @@ QPDFWriter::interpretR3EncryptionParameters(
930 950 // NOT EXERCISED IN TEST SUITE
931 951 switch (modify) {
932 952 case qpdf_r3m_none:
933   - m->encryption->setP(11, false); // document assembly
  953 + encryption->setP(11, false); // document assembly
934 954 [[fallthrough]];
935 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 957 [[fallthrough]];
938 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 960 [[fallthrough]];
941 961 case qpdf_r3m_annotate:
942   - m->encryption->setP(4, false); // other modifications
  962 + encryption->setP(4, false); // other modifications
943 963 [[fallthrough]];
944 964 case qpdf_r3m_all:
945 965 break;
... ... @@ -948,25 +968,25 @@ QPDFWriter::interpretR3EncryptionParameters(
948 968 // END NOT EXERCISED IN TEST SUITE
949 969  
950 970 if (!allow_assemble) {
951   - m->encryption->setP(11, false);
  971 + encryption->setP(11, false);
952 972 }
953 973 if (!allow_annotate_and_form) {
954   - m->encryption->setP(6, false);
  974 + encryption->setP(6, false);
955 975 }
956 976 if (!allow_form_filling) {
957   - m->encryption->setP(9, false);
  977 + encryption->setP(9, false);
958 978 }
959 979 if (!allow_modify_other) {
960   - m->encryption->setP(4, false);
  980 + encryption->setP(4, false);
961 981 }
962 982 }
963 983  
964 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 990 setEncryptionMinimumVersion();
971 991 }
972 992  
... ... @@ -1018,7 +1038,7 @@ QPDFWriter::Members::copyEncryptionParameters(QPDF&amp; qpdf)
1018 1038 encrypt_metadata);
1019 1039 encryption_key = V >= 5 ? qpdf.getEncryptionKey()
1020 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 1112 }
1093 1113  
1094 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 1118 if (R >= 6) {
1099   - setMinimumPDFVersion("1.7", 8);
  1119 + w.setMinimumPDFVersion("1.7", 8);
1100 1120 } else if (R == 5) {
1101   - setMinimumPDFVersion("1.7", 3);
  1121 + w.setMinimumPDFVersion("1.7", 3);
1102 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 1124 } else if (R == 3) {
1105   - setMinimumPDFVersion("1.4");
  1125 + w.setMinimumPDFVersion("1.4");
1106 1126 } else {
1107   - setMinimumPDFVersion("1.3");
  1127 + w.setMinimumPDFVersion("1.3");
1108 1128 }
1109 1129 }
1110 1130  
... ...