Commit fe122b0b8c8256b5cf5f824701923ded8439ae36
1 parent
fad1399f
Refactor `QPDFWriter` to remove `encryption_dictionary` member, streamline encry…
…ption dictionary generation, and reduce redundancy in encryption handling logic.
Showing
1 changed file
with
43 additions
and
38 deletions
libqpdf/QPDFWriter.cc
| @@ -89,7 +89,6 @@ class QPDFWriter::Members | @@ -89,7 +89,6 @@ class QPDFWriter::Members | ||
| 89 | std::unique_ptr<QPDF::EncryptionData> encryption; | 89 | std::unique_ptr<QPDF::EncryptionData> encryption; |
| 90 | std::string encryption_key; | 90 | std::string encryption_key; |
| 91 | bool encrypt_use_aes{false}; | 91 | bool encrypt_use_aes{false}; |
| 92 | - std::map<std::string, std::string> encryption_dictionary; | ||
| 93 | 92 | ||
| 94 | std::string id1; // for /ID key of | 93 | std::string id1; // for /ID key of |
| 95 | std::string id2; // trailer dictionary | 94 | std::string id2; // trailer dictionary |
| @@ -783,21 +782,7 @@ void | @@ -783,21 +782,7 @@ void | ||
| 783 | QPDFWriter::setEncryptionParametersInternal( | 782 | QPDFWriter::setEncryptionParametersInternal( |
| 784 | std::string const& user_password, std::string const& encryption_key) | 783 | std::string const& user_password, std::string const& encryption_key) |
| 785 | { | 784 | { |
| 786 | - auto& enc = *m->encryption; | ||
| 787 | - auto const V = enc.getV(); | ||
| 788 | - auto const R = enc.getR(); | ||
| 789 | - m->encryption_dictionary["/Filter"] = "/Standard"; | ||
| 790 | - m->encryption_dictionary["/V"] = std::to_string(enc.getV()); | ||
| 791 | - m->encryption_dictionary["/Length"] = std::to_string(enc.getLengthBytes() * 8); | ||
| 792 | - m->encryption_dictionary["/R"] = std::to_string(enc.getR()); | ||
| 793 | - m->encryption_dictionary["/P"] = std::to_string(enc.getP()); | ||
| 794 | - m->encryption_dictionary["/O"] = QPDF_String(enc.getO()).unparse(true); | ||
| 795 | - m->encryption_dictionary["/U"] = QPDF_String(enc.getU()).unparse(true); | ||
| 796 | - if (V >= 5) { | ||
| 797 | - m->encryption_dictionary["/OE"] = QPDF_String(enc.getOE()).unparse(true); | ||
| 798 | - m->encryption_dictionary["/UE"] = QPDF_String(enc.getUE()).unparse(true); | ||
| 799 | - m->encryption_dictionary["/Perms"] = QPDF_String(enc.getPerms()).unparse(true); | ||
| 800 | - } | 785 | + auto const R = m->encryption->getR(); |
| 801 | if (R >= 6) { | 786 | if (R >= 6) { |
| 802 | setMinimumPDFVersion("1.7", 8); | 787 | setMinimumPDFVersion("1.7", 8); |
| 803 | } else if (R == 5) { | 788 | } else if (R == 5) { |
| @@ -810,23 +795,8 @@ QPDFWriter::setEncryptionParametersInternal( | @@ -810,23 +795,8 @@ QPDFWriter::setEncryptionParametersInternal( | ||
| 810 | setMinimumPDFVersion("1.3"); | 795 | setMinimumPDFVersion("1.3"); |
| 811 | } | 796 | } |
| 812 | 797 | ||
| 813 | - if (R >= 4 && !m->encryption->getEncryptMetadata()) { | ||
| 814 | - m->encryption_dictionary["/EncryptMetadata"] = "false"; | ||
| 815 | - } | ||
| 816 | - if ((V == 4) || (V == 5)) { | ||
| 817 | - // The spec says the value for the crypt filter key can be anything, and xpdf seems to | ||
| 818 | - // agree. However, Adobe Reader won't open our files unless we use /StdCF. | ||
| 819 | - m->encryption_dictionary["/StmF"] = "/StdCF"; | ||
| 820 | - m->encryption_dictionary["/StrF"] = "/StdCF"; | ||
| 821 | - std::string method = (m->encrypt_use_aes ? ((V < 5) ? "/AESV2" : "/AESV3") : "/V2"); | ||
| 822 | - // The PDF spec says the /Length key is optional, but the PDF previewer on some versions of | ||
| 823 | - // MacOS won't open encrypted files without it. | ||
| 824 | - m->encryption_dictionary["/CF"] = "<< /StdCF << /AuthEvent /DocOpen /CFM " + method + | ||
| 825 | - " /Length " + std::string((V < 5) ? "16" : "32") + " >> >>"; | ||
| 826 | - } | ||
| 827 | - | ||
| 828 | - if (V < 5) { | ||
| 829 | - m->encryption_key = enc.compute_encryption_key(user_password); | 798 | + if (m->encryption->getV() < 5) { |
| 799 | + m->encryption_key = m->encryption->compute_encryption_key(user_password); | ||
| 830 | } else { | 800 | } else { |
| 831 | m->encryption_key = encryption_key; | 801 | m->encryption_key = encryption_key; |
| 832 | } | 802 | } |
| @@ -2310,13 +2280,48 @@ void | @@ -2310,13 +2280,48 @@ void | ||
| 2310 | QPDFWriter::writeEncryptionDictionary() | 2280 | QPDFWriter::writeEncryptionDictionary() |
| 2311 | { | 2281 | { |
| 2312 | m->encryption_dict_objid = openObject(m->encryption_dict_objid); | 2282 | m->encryption_dict_objid = openObject(m->encryption_dict_objid); |
| 2283 | + auto& enc = *m->encryption; | ||
| 2284 | + auto const V = enc.getV(); | ||
| 2285 | + | ||
| 2313 | writeString("<<"); | 2286 | writeString("<<"); |
| 2314 | - for (auto const& iter: m->encryption_dictionary) { | ||
| 2315 | - writeString(" "); | ||
| 2316 | - writeString(iter.first); | ||
| 2317 | - writeString(" "); | ||
| 2318 | - writeString(iter.second); | 2287 | + if (V >= 4) { |
| 2288 | + writeString(" /CF << /StdCF << /AuthEvent /DocOpen /CFM "); | ||
| 2289 | + writeString(m->encrypt_use_aes ? ((V < 5) ? "/AESV2" : "/AESV3") : "/V2"); | ||
| 2290 | + // The PDF spec says the /Length key is optional, but the PDF previewer on some versions of | ||
| 2291 | + // MacOS won't open encrypted files without it. | ||
| 2292 | + writeString((V < 5) ? " /Length 16 >> >>" : " /Length 32 >> >>"); | ||
| 2293 | + if (!m->encryption->getEncryptMetadata()) { | ||
| 2294 | + writeString(" /EncryptMetadata false"); | ||
| 2295 | + } | ||
| 2296 | + } | ||
| 2297 | + writeString(" /Filter /Standard /Length "); | ||
| 2298 | + writeString(std::to_string(enc.getLengthBytes() * 8)); | ||
| 2299 | + writeString(" /O "); | ||
| 2300 | + writeString(QPDF_String(enc.getO()).unparse(true)); | ||
| 2301 | + if (V >= 4) { | ||
| 2302 | + writeString(" /OE "); | ||
| 2303 | + writeString(QPDF_String(enc.getOE()).unparse(true)); | ||
| 2304 | + } | ||
| 2305 | + writeString(" /P "); | ||
| 2306 | + writeString(std::to_string(enc.getP())); | ||
| 2307 | + if (V >= 5) { | ||
| 2308 | + writeString(" /Perms "); | ||
| 2309 | + writeString(QPDF_String(enc.getPerms()).unparse(true)); | ||
| 2310 | + } | ||
| 2311 | + writeString(" /R "); | ||
| 2312 | + writeString(std::to_string(enc.getR())); | ||
| 2313 | + | ||
| 2314 | + if (V >= 4) { | ||
| 2315 | + writeString(" /StmF /StdCF /StrF /StdCF"); | ||
| 2316 | + } | ||
| 2317 | + writeString(" /U "); | ||
| 2318 | + writeString(QPDF_String(enc.getU()).unparse(true)); | ||
| 2319 | + if (V >= 4) { | ||
| 2320 | + writeString(" /UE "); | ||
| 2321 | + writeString(QPDF_String(enc.getUE()).unparse(true)); | ||
| 2319 | } | 2322 | } |
| 2323 | + writeString(" /V "); | ||
| 2324 | + writeString(std::to_string(enc.getV())); | ||
| 2320 | writeString(" >>"); | 2325 | writeString(" >>"); |
| 2321 | closeObject(m->encryption_dict_objid); | 2326 | closeObject(m->encryption_dict_objid); |
| 2322 | } | 2327 | } |