Commit 9aef15899ece1235583e5520ccb64ca315affe79
1 parent
f52b9848
Refactor `QPDFWriter`: move encryption-related methods and flags to `QPDFWriter:…
…:Members`, update related logic, and remove obsolete declarations.
Showing
2 changed files
with
65 additions
and
77 deletions
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& 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 | ... | ... |