Commit a15d0afa3e362ef7744f43c9a238c46ddd902cf6

Authored by m-holger
1 parent 44fa03c6

Refactor `QPDFWriter`: move `generateID` and `getOriginalID1` to `QPDFWriter::Me…

…mbers` and update encryption parameter handling logic.
include/qpdf/QPDFWriter.hh
... ... @@ -494,8 +494,6 @@ class QPDFWriter
494 494 void initializeSpecialStreams();
495 495 void preserveObjectStreams();
496 496 void generateObjectStreams();
497   - std::string getOriginalID1();
498   - void generateID(bool encrypted);
499 497 void interpretR3EncryptionParameters(
500 498 bool allow_accessibility,
501 499 bool allow_extract,
... ...
libqpdf/QPDFWriter.cc
... ... @@ -285,10 +285,13 @@ class QPDFWriter::Members
285 285 }
286 286  
287 287 void setMinimumPDFVersion(std::string const& version, int extension_level);
  288 + void copyEncryptionParameters(QPDF&);
288 289  
289 290 void disableIncompatibleEncryption(int major, int minor, int extension_level);
290 291 void parseVersion(std::string const& version, int& major, int& minor) const;
291 292 int compareVersions(int major1, int minor1, int major2, int minor2) const;
  293 + void generateID(bool encrypted);
  294 + std::string getOriginalID1();
292 295  
293 296 private:
294 297 QPDFWriter& w;
... ... @@ -867,7 +870,7 @@ QPDFWriter::interpretR3EncryptionParameters(
867 870 void
868 871 QPDFWriter::setEncryptionParameters(char const* user_password, char const* owner_password)
869 872 {
870   - generateID(true);
  873 + m->generateID(true);
871 874 m->encryption->setId1(m->id1);
872 875 m->encryption_key = m->encryption->compute_parameters(user_password, owner_password);
873 876 setEncryptionMinimumVersion();
... ... @@ -876,11 +879,17 @@ QPDFWriter::setEncryptionParameters(char const* user_password, char const* owner
876 879 void
877 880 QPDFWriter::copyEncryptionParameters(QPDF& qpdf)
878 881 {
879   - m->preserve_encryption = false;
  882 + m->copyEncryptionParameters(qpdf);
  883 +}
  884 +
  885 +void
  886 +QPDFWriter::Members::copyEncryptionParameters(QPDF& qpdf)
  887 +{
  888 + preserve_encryption = false;
880 889 QPDFObjectHandle trailer = qpdf.getTrailer();
881 890 if (trailer.hasKey("/Encrypt")) {
882 891 generateID(true);
883   - m->id1 = trailer.getKey("/ID").getArrayItem(0).getStringValue();
  892 + id1 = trailer.getKey("/ID").getArrayItem(0).getStringValue();
884 893 QPDFObjectHandle encrypt = trailer.getKey("/Encrypt");
885 894 int V = encrypt.getKey("/V").getIntValueAsInt();
886 895 int key_len = 5;
... ... @@ -896,12 +905,12 @@ QPDFWriter::copyEncryptionParameters(QPDF& qpdf)
896 905 // Acrobat doesn't create files with V >= 4 that don't use AES, and the logic of
897 906 // figuring out whether AES is used or not is complicated with /StmF, /StrF, and /EFF
898 907 // all potentially having different values.
899   - m->encrypt_use_aes = true;
  908 + encrypt_use_aes = true;
900 909 }
901 910 QTC::TC("qpdf", "QPDFWriter copy encrypt metadata", encrypt_metadata ? 0 : 1);
902   - QTC::TC("qpdf", "QPDFWriter copy use_aes", m->encrypt_use_aes ? 0 : 1);
  911 + QTC::TC("qpdf", "QPDFWriter copy use_aes", encrypt_use_aes ? 0 : 1);
903 912  
904   - m->encryption = std::make_unique<QPDF::EncryptionData>(
  913 + encryption = std::make_unique<QPDF::EncryptionData>(
905 914 V,
906 915 encrypt.getKey("/R").getIntValueAsInt(),
907 916 key_len,
... ... @@ -911,12 +920,11 @@ QPDFWriter::copyEncryptionParameters(QPDF&amp; qpdf)
911 920 V < 5 ? "" : encrypt.getKey("/OE").getStringValue(),
912 921 V < 5 ? "" : encrypt.getKey("/UE").getStringValue(),
913 922 V < 5 ? "" : encrypt.getKey("/Perms").getStringValue(),
914   - m->id1, // m->id1 == the other file's id1
  923 + id1, // id1 == the other file's id1
915 924 encrypt_metadata);
916   - m->encryption_key = V >= 5
917   - ? qpdf.getEncryptionKey()
918   - : m->encryption->compute_encryption_key(qpdf.getPaddedUserPassword());
919   - setEncryptionMinimumVersion();
  925 + encryption_key = V >= 5 ? qpdf.getEncryptionKey()
  926 + : encryption->compute_encryption_key(qpdf.getPaddedUserPassword());
  927 + w.setEncryptionMinimumVersion();
920 928 }
921 929 }
922 930  
... ... @@ -1292,7 +1300,7 @@ QPDFWriter::writeTrailer(
1292 1300 // Write ID
1293 1301 write_qdf(" ").write(" /ID [");
1294 1302 if (linearization_pass == 1) {
1295   - std::string original_id1 = getOriginalID1();
  1303 + std::string original_id1 = m->getOriginalID1();
1296 1304 if (original_id1.empty()) {
1297 1305 write("<00000000000000000000000000000000>");
1298 1306 } else {
... ... @@ -1308,7 +1316,7 @@ QPDFWriter::writeTrailer(
1308 1316 if (linearization_pass == 0 && m->deterministic_id) {
1309 1317 computeDeterministicIDData();
1310 1318 }
1311   - generateID(m->encryption.get());
  1319 + m->generateID(m->encryption.get());
1312 1320 write_string(m->id1, true).write_string(m->id2, true);
1313 1321 }
1314 1322 write("]");
... ... @@ -1855,9 +1863,9 @@ QPDFWriter::writeObject(QPDFObjectHandle object, int object_stream_index)
1855 1863 }
1856 1864  
1857 1865 std::string
1858   -QPDFWriter::getOriginalID1()
  1866 +QPDFWriter::Members::getOriginalID1()
1859 1867 {
1860   - QPDFObjectHandle trailer = m->pdf.getTrailer();
  1868 + QPDFObjectHandle trailer = pdf.getTrailer();
1861 1869 if (trailer.hasKey("/ID")) {
1862 1870 return trailer.getKey("/ID").getArrayItem(0).getStringValue();
1863 1871 } else {
... ... @@ -1866,20 +1874,20 @@ QPDFWriter::getOriginalID1()
1866 1874 }
1867 1875  
1868 1876 void
1869   -QPDFWriter::generateID(bool encrypted)
  1877 +QPDFWriter::Members::generateID(bool encrypted)
1870 1878 {
1871 1879 // Generate the ID lazily so that we can handle the user's preference to use static or
1872 1880 // deterministic ID generation.
1873 1881  
1874   - if (!m->id2.empty()) {
  1882 + if (!id2.empty()) {
1875 1883 return;
1876 1884 }
1877 1885  
1878   - QPDFObjectHandle trailer = m->pdf.getTrailer();
  1886 + QPDFObjectHandle trailer = pdf.getTrailer();
1879 1887  
1880 1888 std::string result;
1881 1889  
1882   - if (m->static_id) {
  1890 + if (static_id) {
1883 1891 // For test suite use only...
1884 1892 static unsigned char tmp[] = {
1885 1893 0x31,
... ... @@ -1911,20 +1919,20 @@ QPDFWriter::generateID(bool encrypted)
1911 1919 // that case, would have the same ID regardless of the output file's name.
1912 1920  
1913 1921 std::string seed;
1914   - if (m->deterministic_id) {
  1922 + if (deterministic_id) {
1915 1923 if (encrypted) {
1916 1924 throw std::runtime_error(
1917 1925 "QPDFWriter: unable to generated a deterministic ID because the file to be "
1918 1926 "written is encrypted (even though the file may not require a password)");
1919 1927 }
1920   - if (m->deterministic_id_data.empty()) {
  1928 + if (deterministic_id_data.empty()) {
1921 1929 throw std::logic_error(
1922 1930 "INTERNAL ERROR: QPDFWriter::generateID has no data for deterministic ID");
1923 1931 }
1924   - seed += m->deterministic_id_data;
  1932 + seed += deterministic_id_data;
1925 1933 } else {
1926 1934 seed += std::to_string(QUtil::get_current_time());
1927   - seed += m->filename;
  1935 + seed += filename;
1928 1936 seed += " ";
1929 1937 }
1930 1938 seed += " QPDF ";
... ... @@ -1937,21 +1945,21 @@ QPDFWriter::generateID(bool encrypted)
1937 1945 }
1938 1946 }
1939 1947  
1940   - MD5 m;
1941   - m.encodeString(seed.c_str());
  1948 + MD5 md5;
  1949 + md5.encodeString(seed.c_str());
1942 1950 MD5::Digest digest;
1943   - m.digest(digest);
  1951 + md5.digest(digest);
1944 1952 result = std::string(reinterpret_cast<char*>(digest), sizeof(MD5::Digest));
1945 1953 }
1946 1954  
1947 1955 // If /ID already exists, follow the spec: use the original first word and generate a new second
1948 1956 // word. Otherwise, we'll use the generated ID for both.
1949 1957  
1950   - m->id2 = result;
  1958 + id2 = result;
1951 1959 // Note: keep /ID from old file even if --static-id was given.
1952   - m->id1 = getOriginalID1();
1953   - if (m->id1.empty()) {
1954   - m->id1 = m->id2;
  1960 + id1 = getOriginalID1();
  1961 + if (id1.empty()) {
  1962 + id1 = id2;
1955 1963 }
1956 1964 }
1957 1965  
... ...