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,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& qpdf) | @@ -1018,7 +1038,7 @@ QPDFWriter::Members::copyEncryptionParameters(QPDF& 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 |