Commit 3a055d5b6af5e3eab1eac33c77ccb1c8a386867f
Committed by
GitHub
Merge pull request #1495 from m-holger/writer
Simplify QPDFWriter pipeline management
Showing
10 changed files
with
60 additions
and
155 deletions
libqpdf/Pl_AES_PDF.cc
| @@ -9,25 +9,18 @@ | @@ -9,25 +9,18 @@ | ||
| 9 | 9 | ||
| 10 | bool Pl_AES_PDF::use_static_iv = false; | 10 | bool Pl_AES_PDF::use_static_iv = false; |
| 11 | 11 | ||
| 12 | -Pl_AES_PDF::Pl_AES_PDF( | ||
| 13 | - char const* identifier, | ||
| 14 | - Pipeline* next, | ||
| 15 | - bool encrypt, | ||
| 16 | - unsigned char const* key, | ||
| 17 | - size_t key_bytes) : | 12 | +Pl_AES_PDF::Pl_AES_PDF(char const* identifier, Pipeline* next, bool encrypt, std::string key) : |
| 18 | Pipeline(identifier, next), | 13 | Pipeline(identifier, next), |
| 14 | + key(key), | ||
| 19 | crypto(QPDFCryptoProvider::getImpl()), | 15 | crypto(QPDFCryptoProvider::getImpl()), |
| 20 | - encrypt(encrypt), | ||
| 21 | - key_bytes(key_bytes) | 16 | + encrypt(encrypt) |
| 22 | { | 17 | { |
| 23 | if (!next) { | 18 | if (!next) { |
| 24 | throw std::logic_error("Attempt to create Pl_AES_PDF with nullptr as next"); | 19 | throw std::logic_error("Attempt to create Pl_AES_PDF with nullptr as next"); |
| 25 | } | 20 | } |
| 26 | - if (!(key_bytes == 32 || key_bytes == 16)) { | 21 | + if (!(key.size() == 32 || key.size() == 16)) { |
| 27 | throw std::runtime_error("unsupported key length"); | 22 | throw std::runtime_error("unsupported key length"); |
| 28 | } | 23 | } |
| 29 | - this->key = std::make_unique<unsigned char[]>(key_bytes); | ||
| 30 | - std::memcpy(this->key.get(), key, key_bytes); | ||
| 31 | std::memset(this->inbuf, 0, this->buf_size); | 24 | std::memset(this->inbuf, 0, this->buf_size); |
| 32 | std::memset(this->outbuf, 0, this->buf_size); | 25 | std::memset(this->outbuf, 0, this->buf_size); |
| 33 | std::memset(this->cbc_block, 0, this->buf_size); | 26 | std::memset(this->cbc_block, 0, this->buf_size); |
| @@ -170,7 +163,12 @@ Pl_AES_PDF::flush(bool strip_padding) | @@ -170,7 +163,12 @@ Pl_AES_PDF::flush(bool strip_padding) | ||
| 170 | return_after_init = true; | 163 | return_after_init = true; |
| 171 | } | 164 | } |
| 172 | } | 165 | } |
| 173 | - crypto->rijndael_init(encrypt, key.get(), key_bytes, cbc_mode, cbc_block); | 166 | + crypto->rijndael_init( |
| 167 | + encrypt, | ||
| 168 | + reinterpret_cast<const unsigned char*>(key.data()), | ||
| 169 | + key.size(), | ||
| 170 | + cbc_mode, | ||
| 171 | + cbc_block); | ||
| 174 | if (return_after_init) { | 172 | if (return_after_init) { |
| 175 | return; | 173 | return; |
| 176 | } | 174 | } |
libqpdf/Pl_RC4.cc
| @@ -2,15 +2,10 @@ | @@ -2,15 +2,10 @@ | ||
| 2 | 2 | ||
| 3 | #include <qpdf/QUtil.hh> | 3 | #include <qpdf/QUtil.hh> |
| 4 | 4 | ||
| 5 | -Pl_RC4::Pl_RC4( | ||
| 6 | - char const* identifier, | ||
| 7 | - Pipeline* next, | ||
| 8 | - unsigned char const* key_data, | ||
| 9 | - int key_len, | ||
| 10 | - size_t out_bufsize) : | 5 | +Pl_RC4::Pl_RC4(char const* identifier, Pipeline* next, std::string key, size_t out_bufsize) : |
| 11 | Pipeline(identifier, next), | 6 | Pipeline(identifier, next), |
| 12 | out_bufsize(out_bufsize), | 7 | out_bufsize(out_bufsize), |
| 13 | - rc4(key_data, key_len) | 8 | + rc4(reinterpret_cast<unsigned char const*>(key.data()), static_cast<int>(key.size())) |
| 14 | { | 9 | { |
| 15 | if (!next) { | 10 | if (!next) { |
| 16 | throw std::logic_error("Attempt to create Pl_RC4 with nullptr as next"); | 11 | throw std::logic_error("Attempt to create Pl_RC4 with nullptr as next"); |
libqpdf/QPDFWriter.cc
| @@ -141,20 +141,20 @@ namespace | @@ -141,20 +141,20 @@ namespace | ||
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | void | 143 | void |
| 144 | - activate(Popper& pp, std::unique_ptr<pl::Link> link) | 144 | + activate(Popper& pp, std::unique_ptr<Pipeline> next) |
| 145 | { | 145 | { |
| 146 | count_buffer.clear(); | 146 | count_buffer.clear(); |
| 147 | - activate(pp, false, &count_buffer, std::move(link)); | 147 | + activate(pp, false, &count_buffer, std::move(next)); |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | Popper | 150 | Popper |
| 151 | activate( | 151 | activate( |
| 152 | bool discard = false, | 152 | bool discard = false, |
| 153 | std::string* str = nullptr, | 153 | std::string* str = nullptr, |
| 154 | - std::unique_ptr<pl::Link> link = nullptr) | 154 | + std::unique_ptr<Pipeline> next = nullptr) |
| 155 | { | 155 | { |
| 156 | Popper pp{*this}; | 156 | Popper pp{*this}; |
| 157 | - activate(pp, discard, str, std::move(link)); | 157 | + activate(pp, discard, str, std::move(next)); |
| 158 | return pp; | 158 | return pp; |
| 159 | } | 159 | } |
| 160 | 160 | ||
| @@ -163,11 +163,11 @@ namespace | @@ -163,11 +163,11 @@ namespace | ||
| 163 | Popper& pp, | 163 | Popper& pp, |
| 164 | bool discard = false, | 164 | bool discard = false, |
| 165 | std::string* str = nullptr, | 165 | std::string* str = nullptr, |
| 166 | - std::unique_ptr<pl::Link> link = nullptr) | 166 | + std::unique_ptr<Pipeline> next = nullptr) |
| 167 | { | 167 | { |
| 168 | std::unique_ptr<pl::Count> c; | 168 | std::unique_ptr<pl::Count> c; |
| 169 | - if (link) { | ||
| 170 | - c = std::make_unique<pl::Count>(++last_id, count_buffer, std::move(link)); | 169 | + if (next) { |
| 170 | + c = std::make_unique<pl::Count>(++last_id, count_buffer, std::move(next)); | ||
| 171 | } else if (discard) { | 171 | } else if (discard) { |
| 172 | c = std::make_unique<pl::Count>(++last_id, nullptr); | 172 | c = std::make_unique<pl::Count>(++last_id, nullptr); |
| 173 | } else if (!str) { | 173 | } else if (!str) { |
| @@ -1109,18 +1109,9 @@ QPDFWriter::write_encrypted(std::string_view str) | @@ -1109,18 +1109,9 @@ QPDFWriter::write_encrypted(std::string_view str) | ||
| 1109 | if (!(m->encryption && !m->cur_data_key.empty())) { | 1109 | if (!(m->encryption && !m->cur_data_key.empty())) { |
| 1110 | write(str); | 1110 | write(str); |
| 1111 | } else if (m->encrypt_use_aes) { | 1111 | } else if (m->encrypt_use_aes) { |
| 1112 | - write( | ||
| 1113 | - pl::pipe<Pl_AES_PDF>( | ||
| 1114 | - str, | ||
| 1115 | - true, | ||
| 1116 | - QUtil::unsigned_char_pointer(m->cur_data_key), | ||
| 1117 | - m->cur_data_key.length())); | 1112 | + write(pl::pipe<Pl_AES_PDF>(str, true, m->cur_data_key)); |
| 1118 | } else { | 1113 | } else { |
| 1119 | - write( | ||
| 1120 | - pl::pipe<Pl_RC4>( | ||
| 1121 | - str, | ||
| 1122 | - QUtil::unsigned_char_pointer(m->cur_data_key), | ||
| 1123 | - QIntC::to_int(m->cur_data_key.length()))); | 1114 | + write(pl::pipe<Pl_RC4>(str, m->cur_data_key)); |
| 1124 | } | 1115 | } |
| 1125 | 1116 | ||
| 1126 | return *this; | 1117 | return *this; |
| @@ -1654,12 +1645,7 @@ QPDFWriter::unparseObject( | @@ -1654,12 +1645,7 @@ QPDFWriter::unparseObject( | ||
| 1654 | val = object.getStringValue(); | 1645 | val = object.getStringValue(); |
| 1655 | if (m->encrypt_use_aes) { | 1646 | if (m->encrypt_use_aes) { |
| 1656 | Pl_Buffer bufpl("encrypted string"); | 1647 | Pl_Buffer bufpl("encrypted string"); |
| 1657 | - Pl_AES_PDF pl( | ||
| 1658 | - "aes encrypt string", | ||
| 1659 | - &bufpl, | ||
| 1660 | - true, | ||
| 1661 | - QUtil::unsigned_char_pointer(m->cur_data_key), | ||
| 1662 | - m->cur_data_key.length()); | 1648 | + Pl_AES_PDF pl("aes encrypt string", &bufpl, true, m->cur_data_key); |
| 1663 | pl.writeString(val); | 1649 | pl.writeString(val); |
| 1664 | pl.finish(); | 1650 | pl.finish(); |
| 1665 | val = QPDF_String(bufpl.getString()).unparse(true); | 1651 | val = QPDF_String(bufpl.getString()).unparse(true); |
| @@ -1768,7 +1754,6 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) | @@ -1768,7 +1754,6 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) | ||
| 1768 | } | 1754 | } |
| 1769 | } | 1755 | } |
| 1770 | { | 1756 | { |
| 1771 | - auto pp_ostream = m->pipeline_stack.popper(); | ||
| 1772 | // Adjust offsets to skip over comment before first object | 1757 | // Adjust offsets to skip over comment before first object |
| 1773 | first = offsets.at(0); | 1758 | first = offsets.at(0); |
| 1774 | for (auto& iter: offsets) { | 1759 | for (auto& iter: offsets) { |
| @@ -1783,18 +1768,15 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) | @@ -1783,18 +1768,15 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) | ||
| 1783 | } | 1768 | } |
| 1784 | 1769 | ||
| 1785 | // Set up a stream to write the stream data into a buffer. | 1770 | // Set up a stream to write the stream data into a buffer. |
| 1786 | - if (compressed) { | ||
| 1787 | - m->pipeline_stack.activate( | ||
| 1788 | - pp_ostream, | ||
| 1789 | - pl::create<Pl_Flate>( | ||
| 1790 | - pl::create<pl::String>(stream_buffer_pass2), Pl_Flate::a_deflate)); | ||
| 1791 | - } else { | ||
| 1792 | - m->pipeline_stack.activate(pp_ostream, stream_buffer_pass2); | ||
| 1793 | - } | 1771 | + auto pp_ostream = m->pipeline_stack.activate(stream_buffer_pass2); |
| 1772 | + | ||
| 1794 | writeObjectStreamOffsets(offsets, first_obj); | 1773 | writeObjectStreamOffsets(offsets, first_obj); |
| 1795 | write(stream_buffer_pass1); | 1774 | write(stream_buffer_pass1); |
| 1796 | stream_buffer_pass1.clear(); | 1775 | stream_buffer_pass1.clear(); |
| 1797 | stream_buffer_pass1.shrink_to_fit(); | 1776 | stream_buffer_pass1.shrink_to_fit(); |
| 1777 | + if (compressed) { | ||
| 1778 | + stream_buffer_pass2 = pl::pipe<Pl_Flate>(stream_buffer_pass2, Pl_Flate::a_deflate); | ||
| 1779 | + } | ||
| 1798 | } | 1780 | } |
| 1799 | 1781 | ||
| 1800 | // Write the object | 1782 | // Write the object |
| @@ -2528,20 +2510,7 @@ QPDFWriter::writeXRefStream( | @@ -2528,20 +2510,7 @@ QPDFWriter::writeXRefStream( | ||
| 2528 | std::string xref_data; | 2510 | std::string xref_data; |
| 2529 | const bool compressed = m->compress_streams && !m->qdf_mode; | 2511 | const bool compressed = m->compress_streams && !m->qdf_mode; |
| 2530 | { | 2512 | { |
| 2531 | - auto pp_xref = m->pipeline_stack.popper(); | ||
| 2532 | - if (compressed) { | ||
| 2533 | - m->pipeline_stack.clear_buffer(); | ||
| 2534 | - auto link = pl::create<pl::String>(xref_data); | ||
| 2535 | - if (!skip_compression) { | ||
| 2536 | - // Write the stream dictionary for compression but don't actually compress. This | ||
| 2537 | - // helps us with computation of padding for pass 1 of linearization. | ||
| 2538 | - link = pl::create<Pl_Flate>(std::move(link), Pl_Flate::a_deflate); | ||
| 2539 | - } | ||
| 2540 | - m->pipeline_stack.activate( | ||
| 2541 | - pp_xref, pl::create<Pl_PNGFilter>(std::move(link), Pl_PNGFilter::a_encode, esize)); | ||
| 2542 | - } else { | ||
| 2543 | - m->pipeline_stack.activate(pp_xref, xref_data); | ||
| 2544 | - } | 2513 | + auto pp_xref = m->pipeline_stack.activate(xref_data); |
| 2545 | 2514 | ||
| 2546 | for (int i = first; i <= last; ++i) { | 2515 | for (int i = first; i <= last; ++i) { |
| 2547 | QPDFXRefEntry& e = m->new_obj[i].xref; | 2516 | QPDFXRefEntry& e = m->new_obj[i].xref; |
| @@ -2577,6 +2546,15 @@ QPDFWriter::writeXRefStream( | @@ -2577,6 +2546,15 @@ QPDFWriter::writeXRefStream( | ||
| 2577 | } | 2546 | } |
| 2578 | } | 2547 | } |
| 2579 | 2548 | ||
| 2549 | + if (compressed) { | ||
| 2550 | + xref_data = pl::pipe<Pl_PNGFilter>(xref_data, Pl_PNGFilter::a_encode, esize); | ||
| 2551 | + if (!skip_compression) { | ||
| 2552 | + // Write the stream dictionary for compression but don't actually compress. This | ||
| 2553 | + // helps us with computation of padding for pass 1 of linearization. | ||
| 2554 | + xref_data = pl::pipe<Pl_Flate>(xref_data, Pl_Flate::a_deflate); | ||
| 2555 | + } | ||
| 2556 | + } | ||
| 2557 | + | ||
| 2580 | openObject(xref_id); | 2558 | openObject(xref_id); |
| 2581 | write("<<").write_qdf("\n ").write(" /Type /XRef").write_qdf("\n "); | 2559 | write("<<").write_qdf("\n ").write(" /Type /XRef").write_qdf("\n "); |
| 2582 | write(" /Length ").write(xref_data.size()); | 2560 | write(" /Length ").write(xref_data.size()); |
| @@ -2743,9 +2721,7 @@ QPDFWriter::writeLinearized() | @@ -2743,9 +2721,7 @@ QPDFWriter::writeLinearized() | ||
| 2743 | lin_pass1_file = QUtil::safe_fopen(m->lin_pass1_filename.c_str(), "wb"); | 2721 | lin_pass1_file = QUtil::safe_fopen(m->lin_pass1_filename.c_str(), "wb"); |
| 2744 | m->pipeline_stack.activate( | 2722 | m->pipeline_stack.activate( |
| 2745 | pp_pass1, | 2723 | pp_pass1, |
| 2746 | - std::make_unique<pl::Link>( | ||
| 2747 | - nullptr, | ||
| 2748 | - std::make_unique<Pl_StdioFile>("linearization pass1", lin_pass1_file))); | 2724 | + std::make_unique<Pl_StdioFile>("linearization pass1", lin_pass1_file)); |
| 2749 | } else { | 2725 | } else { |
| 2750 | m->pipeline_stack.activate(pp_pass1, true); | 2726 | m->pipeline_stack.activate(pp_pass1, true); |
| 2751 | } | 2727 | } |
libqpdf/QPDF_encryption.cc
| @@ -230,8 +230,7 @@ process_with_aes( | @@ -230,8 +230,7 @@ process_with_aes( | ||
| 230 | size_t iv_length = 0) | 230 | size_t iv_length = 0) |
| 231 | { | 231 | { |
| 232 | Pl_Buffer buffer("buffer"); | 232 | Pl_Buffer buffer("buffer"); |
| 233 | - Pl_AES_PDF aes( | ||
| 234 | - "aes", &buffer, encrypt, QUtil::unsigned_char_pointer(key), QIntC::to_uint(key.length())); | 233 | + Pl_AES_PDF aes("aes", &buffer, encrypt, key); |
| 235 | if (iv) { | 234 | if (iv) { |
| 236 | aes.setIV(iv, iv_length); | 235 | aes.setIV(iv, iv_length); |
| 237 | } else { | 236 | } else { |
| @@ -902,12 +901,7 @@ QPDF::decryptString(std::string& str, QPDFObjGen og) | @@ -902,12 +901,7 @@ QPDF::decryptString(std::string& str, QPDFObjGen og) | ||
| 902 | if (use_aes) { | 901 | if (use_aes) { |
| 903 | QTC::TC("qpdf", "QPDF_encryption aes decode string"); | 902 | QTC::TC("qpdf", "QPDF_encryption aes decode string"); |
| 904 | Pl_Buffer bufpl("decrypted string"); | 903 | Pl_Buffer bufpl("decrypted string"); |
| 905 | - Pl_AES_PDF pl( | ||
| 906 | - "aes decrypt string", | ||
| 907 | - &bufpl, | ||
| 908 | - false, | ||
| 909 | - QUtil::unsigned_char_pointer(key), | ||
| 910 | - key.length()); | 904 | + Pl_AES_PDF pl("aes decrypt string", &bufpl, false, key); |
| 911 | pl.writeString(str); | 905 | pl.writeString(str); |
| 912 | pl.finish(); | 906 | pl.finish(); |
| 913 | str = bufpl.getString(); | 907 | str = bufpl.getString(); |
| @@ -1028,19 +1022,11 @@ QPDF::decryptStream( | @@ -1028,19 +1022,11 @@ QPDF::decryptStream( | ||
| 1028 | std::string key = getKeyForObject(encp, og, use_aes); | 1022 | std::string key = getKeyForObject(encp, og, use_aes); |
| 1029 | if (use_aes) { | 1023 | if (use_aes) { |
| 1030 | QTC::TC("qpdf", "QPDF_encryption aes decode stream"); | 1024 | QTC::TC("qpdf", "QPDF_encryption aes decode stream"); |
| 1031 | - decrypt_pipeline = std::make_unique<Pl_AES_PDF>( | ||
| 1032 | - "AES stream decryption", | ||
| 1033 | - pipeline, | ||
| 1034 | - false, | ||
| 1035 | - QUtil::unsigned_char_pointer(key), | ||
| 1036 | - key.length()); | 1025 | + decrypt_pipeline = |
| 1026 | + std::make_unique<Pl_AES_PDF>("AES stream decryption", pipeline, false, key); | ||
| 1037 | } else { | 1027 | } else { |
| 1038 | QTC::TC("qpdf", "QPDF_encryption rc4 decode stream"); | 1028 | QTC::TC("qpdf", "QPDF_encryption rc4 decode stream"); |
| 1039 | - decrypt_pipeline = std::make_unique<Pl_RC4>( | ||
| 1040 | - "RC4 stream decryption", | ||
| 1041 | - pipeline, | ||
| 1042 | - QUtil::unsigned_char_pointer(key), | ||
| 1043 | - toI(key.length())); | 1029 | + decrypt_pipeline = std::make_unique<Pl_RC4>("RC4 stream decryption", pipeline, key); |
| 1044 | } | 1030 | } |
| 1045 | pipeline = decrypt_pipeline.get(); | 1031 | pipeline = decrypt_pipeline.get(); |
| 1046 | } | 1032 | } |
libqpdf/QPDF_linearization.cc
| @@ -1753,21 +1753,18 @@ QPDF::generateHintStream( | @@ -1753,21 +1753,18 @@ QPDF::generateHintStream( | ||
| 1753 | 1753 | ||
| 1754 | // Write the hint stream itself into a compressed memory buffer. Write through a counter so we | 1754 | // Write the hint stream itself into a compressed memory buffer. Write through a counter so we |
| 1755 | // can get offsets. | 1755 | // can get offsets. |
| 1756 | - std::string b; | ||
| 1757 | - auto c = compressed | ||
| 1758 | - ? std::make_unique<pl::Count>( | ||
| 1759 | - 0, b, pl::create<Pl_Flate>(pl::create<pl::String>(hint_buffer), Pl_Flate::a_deflate)) | ||
| 1760 | - : std::make_unique<pl::Count>(0, hint_buffer); | ||
| 1761 | - | ||
| 1762 | - BitWriter w(c.get()); | 1756 | + pl::Count c(0, hint_buffer); |
| 1757 | + BitWriter w(&c); | ||
| 1763 | 1758 | ||
| 1764 | writeHPageOffset(w); | 1759 | writeHPageOffset(w); |
| 1765 | - S = toI(c->getCount()); | 1760 | + S = toI(c.getCount()); |
| 1766 | writeHSharedObject(w); | 1761 | writeHSharedObject(w); |
| 1767 | O = 0; | 1762 | O = 0; |
| 1768 | if (m->outline_hints.nobjects > 0) { | 1763 | if (m->outline_hints.nobjects > 0) { |
| 1769 | - O = toI(c->getCount()); | 1764 | + O = toI(c.getCount()); |
| 1770 | writeHGeneric(w, m->outline_hints); | 1765 | writeHGeneric(w, m->outline_hints); |
| 1771 | } | 1766 | } |
| 1772 | - c->finish(); | 1767 | + if (compressed) { |
| 1768 | + hint_buffer = pl::pipe<Pl_Flate>(hint_buffer, Pl_Flate::a_deflate); | ||
| 1769 | + } | ||
| 1773 | } | 1770 | } |
libqpdf/qpdf/Pipeline_private.hh
| @@ -8,35 +8,6 @@ | @@ -8,35 +8,6 @@ | ||
| 8 | 8 | ||
| 9 | namespace qpdf::pl | 9 | namespace qpdf::pl |
| 10 | { | 10 | { |
| 11 | - struct Link | ||
| 12 | - { | ||
| 13 | - Link(std::unique_ptr<Link> next_link, std::unique_ptr<Pipeline> next_pl) : | ||
| 14 | - next_link(std::move(next_link)), | ||
| 15 | - next_pl(std::move(next_pl)) | ||
| 16 | - { | ||
| 17 | - } | ||
| 18 | - | ||
| 19 | - std::unique_ptr<Link> next_link{nullptr}; | ||
| 20 | - std::unique_ptr<Pipeline> next_pl{nullptr}; | ||
| 21 | - }; | ||
| 22 | - | ||
| 23 | - template <typename P, typename... Args> | ||
| 24 | - std::unique_ptr<Link> | ||
| 25 | - create(Args&&... args) | ||
| 26 | - { | ||
| 27 | - return std::make_unique<Link>( | ||
| 28 | - nullptr, std::make_unique<P>("", nullptr, std::forward<Args>(args)...)); | ||
| 29 | - } | ||
| 30 | - | ||
| 31 | - template <typename P, typename... Args> | ||
| 32 | - std::unique_ptr<Link> | ||
| 33 | - create(std::unique_ptr<Link> link, Args&&... args) | ||
| 34 | - { | ||
| 35 | - auto* next = link->next_pl.get(); | ||
| 36 | - return std::make_unique<Link>( | ||
| 37 | - std::move(link), std::make_unique<P>("", next, std::forward<Args>(args)...)); | ||
| 38 | - } | ||
| 39 | - | ||
| 40 | class String final: public Pipeline | 11 | class String final: public Pipeline |
| 41 | { | 12 | { |
| 42 | public: | 13 | public: |
| @@ -83,20 +54,10 @@ namespace qpdf::pl | @@ -83,20 +54,10 @@ namespace qpdf::pl | ||
| 83 | { | 54 | { |
| 84 | } | 55 | } |
| 85 | 56 | ||
| 86 | - // Count the number of characters written. If 'next' is not set, the content written will be | ||
| 87 | - // discarded. | ||
| 88 | - Count(unsigned long id, std::unique_ptr<Link> link) : | ||
| 89 | - Pipeline("", link ? link->next_pl.get() : nullptr), | ||
| 90 | - link(std::move(link)), | ||
| 91 | - id_(id), | ||
| 92 | - pass_immediately_to_next(link) | ||
| 93 | - { | ||
| 94 | - } | ||
| 95 | - | ||
| 96 | // Write to 'str'. If 'next' is set, 'str' will be written to 'next' when 'finish' is | 57 | // Write to 'str'. If 'next' is set, 'str' will be written to 'next' when 'finish' is |
| 97 | // called. | 58 | // called. |
| 98 | - Count(unsigned long id, std::string& str, std::unique_ptr<Link> link = nullptr) : | ||
| 99 | - Pipeline("", link ? link->next_pl.get() : nullptr), | 59 | + Count(unsigned long id, std::string& str, std::unique_ptr<Pipeline> link = nullptr) : |
| 60 | + Pipeline("", link.get()), | ||
| 100 | str(&str), | 61 | str(&str), |
| 101 | link(std::move(link)), | 62 | link(std::move(link)), |
| 102 | id_(id) | 63 | id_(id) |
| @@ -169,7 +130,7 @@ namespace qpdf::pl | @@ -169,7 +130,7 @@ namespace qpdf::pl | ||
| 169 | private: | 130 | private: |
| 170 | qpdf_offset_t count{0}; | 131 | qpdf_offset_t count{0}; |
| 171 | std::string* str{nullptr}; | 132 | std::string* str{nullptr}; |
| 172 | - std::unique_ptr<Link> link{nullptr}; | 133 | + std::unique_ptr<Pipeline> link{nullptr}; |
| 173 | unsigned long id_{0}; | 134 | unsigned long id_{0}; |
| 174 | bool pass_immediately_to_next{false}; | 135 | bool pass_immediately_to_next{false}; |
| 175 | }; | 136 | }; |
libqpdf/qpdf/Pl_AES_PDF.hh
| @@ -11,12 +11,7 @@ class Pl_AES_PDF final: public Pipeline | @@ -11,12 +11,7 @@ class Pl_AES_PDF final: public Pipeline | ||
| 11 | { | 11 | { |
| 12 | public: | 12 | public: |
| 13 | // key should be a pointer to key_bytes bytes of data | 13 | // key should be a pointer to key_bytes bytes of data |
| 14 | - Pl_AES_PDF( | ||
| 15 | - char const* identifier, | ||
| 16 | - Pipeline* next, | ||
| 17 | - bool encrypt, | ||
| 18 | - unsigned char const* key, | ||
| 19 | - size_t key_bytes); | 14 | + Pl_AES_PDF(char const* identifier, Pipeline* next, bool encrypt, std::string key); |
| 20 | ~Pl_AES_PDF() final = default; | 15 | ~Pl_AES_PDF() final = default; |
| 21 | 16 | ||
| 22 | void write(unsigned char const* data, size_t len) final; | 17 | void write(unsigned char const* data, size_t len) final; |
| @@ -42,13 +37,12 @@ class Pl_AES_PDF final: public Pipeline | @@ -42,13 +37,12 @@ class Pl_AES_PDF final: public Pipeline | ||
| 42 | static unsigned int const buf_size = QPDFCryptoImpl::rijndael_buf_size; | 37 | static unsigned int const buf_size = QPDFCryptoImpl::rijndael_buf_size; |
| 43 | static bool use_static_iv; | 38 | static bool use_static_iv; |
| 44 | 39 | ||
| 40 | + std::string key; | ||
| 45 | std::shared_ptr<QPDFCryptoImpl> crypto; | 41 | std::shared_ptr<QPDFCryptoImpl> crypto; |
| 46 | bool encrypt; | 42 | bool encrypt; |
| 47 | bool cbc_mode{true}; | 43 | bool cbc_mode{true}; |
| 48 | bool first{true}; | 44 | bool first{true}; |
| 49 | size_t offset{0}; // offset into memory buffer | 45 | size_t offset{0}; // offset into memory buffer |
| 50 | - std::unique_ptr<unsigned char[]> key; | ||
| 51 | - size_t key_bytes{0}; | ||
| 52 | unsigned char inbuf[buf_size]; | 46 | unsigned char inbuf[buf_size]; |
| 53 | unsigned char outbuf[buf_size]; | 47 | unsigned char outbuf[buf_size]; |
| 54 | unsigned char cbc_block[buf_size]; | 48 | unsigned char cbc_block[buf_size]; |
libqpdf/qpdf/Pl_RC4.hh
| @@ -12,11 +12,7 @@ class Pl_RC4 final: public Pipeline | @@ -12,11 +12,7 @@ class Pl_RC4 final: public Pipeline | ||
| 12 | 12 | ||
| 13 | // key_len of -1 means treat key_data as a null-terminated string | 13 | // key_len of -1 means treat key_data as a null-terminated string |
| 14 | Pl_RC4( | 14 | Pl_RC4( |
| 15 | - char const* identifier, | ||
| 16 | - Pipeline* next, | ||
| 17 | - unsigned char const* key_data, | ||
| 18 | - int key_len = -1, | ||
| 19 | - size_t out_bufsize = def_bufsize); | 15 | + char const* identifier, Pipeline* next, std::string key, size_t out_bufsize = def_bufsize); |
| 20 | ~Pl_RC4() final = default; | 16 | ~Pl_RC4() final = default; |
| 21 | 17 | ||
| 22 | void write(unsigned char const* data, size_t len) final; | 18 | void write(unsigned char const* data, size_t len) final; |
libtests/aes.cc
| @@ -84,8 +84,9 @@ main(int argc, char* argv[]) | @@ -84,8 +84,9 @@ main(int argc, char* argv[]) | ||
| 84 | key[i / 2] = static_cast<unsigned char>(val); | 84 | key[i / 2] = static_cast<unsigned char>(val); |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | + std::string keystr(reinterpret_cast<char const*>(key), keylen); | ||
| 87 | auto* out = new Pl_StdioFile("stdout", outfile); | 88 | auto* out = new Pl_StdioFile("stdout", outfile); |
| 88 | - auto* aes = new Pl_AES_PDF("aes_128_cbc", out, encrypt, key, keylen); | 89 | + auto* aes = new Pl_AES_PDF("aes_128_cbc", out, encrypt, keystr); |
| 89 | delete[] key; | 90 | delete[] key; |
| 90 | key = nullptr; | 91 | key = nullptr; |
| 91 | if (!cbc_mode) { | 92 | if (!cbc_mode) { |
libtests/rc4.cc
| @@ -58,7 +58,8 @@ main(int argc, char* argv[]) | @@ -58,7 +58,8 @@ main(int argc, char* argv[]) | ||
| 58 | FILE* outfile = QUtil::safe_fopen(outfilename, "wb"); | 58 | FILE* outfile = QUtil::safe_fopen(outfilename, "wb"); |
| 59 | auto* out = new Pl_StdioFile("stdout", outfile); | 59 | auto* out = new Pl_StdioFile("stdout", outfile); |
| 60 | // Use a small buffer size (64) for testing | 60 | // Use a small buffer size (64) for testing |
| 61 | - auto* rc4 = new Pl_RC4("rc4", out, key, QIntC::to_int(keylen), 64U); | 61 | + std::string keystr(reinterpret_cast<char const*>(key), keylen); |
| 62 | + auto* rc4 = new Pl_RC4("rc4", out, keystr, 64U); | ||
| 62 | delete[] key; | 63 | delete[] key; |
| 63 | 64 | ||
| 64 | // 64 < buffer size < 512, buffer_size is not a power of 2 for testing | 65 | // 64 < buffer size < 512, buffer_size is not a power of 2 for testing |