diff --git a/ChangeLog b/ChangeLog index 827a633..662bad6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2022-05-03 Jay Berkenbilt + + * API change: Pipeline::write now takes "unsigned char const *" + instead of "unsigned char*". Callers shouldn't have to change + anything, though can stop using writable strings or + QUtil::unsigned_char_pointer. If you have implemented your own + pipelines, you should change your write method to take a const + pointer. + 2022-05-01 Jay Berkenbilt * JSON: add reactors to the JSON parser, making it possible to diff --git a/examples/pdf-custom-filter.cc b/examples/pdf-custom-filter.cc index 4514f6d..ede4a19 100644 --- a/examples/pdf-custom-filter.cc +++ b/examples/pdf-custom-filter.cc @@ -49,7 +49,7 @@ class Pl_XOR: public Pipeline public: Pl_XOR(char const* identifier, Pipeline* next, unsigned char key); virtual ~Pl_XOR() = default; - virtual void write(unsigned char* data, size_t len) override; + virtual void write(unsigned char const* data, size_t len) override; virtual void finish() override; private: @@ -63,7 +63,7 @@ Pl_XOR::Pl_XOR(char const* identifier, Pipeline* next, unsigned char key) : } void -Pl_XOR::write(unsigned char* data, size_t len) +Pl_XOR::write(unsigned char const* data, size_t len) { for (size_t i = 0; i < len; ++i) { unsigned char p = data[i] ^ this->key; diff --git a/include/qpdf/Pipeline.hh b/include/qpdf/Pipeline.hh index 09ec092..8c1dfe1 100644 --- a/include/qpdf/Pipeline.hh +++ b/include/qpdf/Pipeline.hh @@ -63,15 +63,9 @@ class QPDF_DLL_CLASS Pipeline // Subclasses should implement write and finish to do their jobs // and then, if they are not end-of-line pipelines, call - // getNext()->write or getNext()->finish. It would be really nice - // if write could take unsigned char const*, but this would make - // it much more difficult to write pipelines around legacy - // interfaces whose calls don't want pointers to const data. As a - // rule, pipelines should generally not be modifying the data - // passed to them. They should, instead, create new data to pass - // downstream. + // getNext()->write or getNext()->finish. QPDF_DLL - virtual void write(unsigned char* data, size_t len) = 0; + virtual void write(unsigned char const* data, size_t len) = 0; QPDF_DLL virtual void finish() = 0; QPDF_DLL diff --git a/include/qpdf/Pl_Buffer.hh b/include/qpdf/Pl_Buffer.hh index d9aec07..7784286 100644 --- a/include/qpdf/Pl_Buffer.hh +++ b/include/qpdf/Pl_Buffer.hh @@ -47,7 +47,7 @@ class QPDF_DLL_CLASS Pl_Buffer: public Pipeline QPDF_DLL virtual ~Pl_Buffer(); QPDF_DLL - virtual void write(unsigned char*, size_t); + virtual void write(unsigned char const*, size_t); QPDF_DLL virtual void finish(); diff --git a/include/qpdf/Pl_Concatenate.hh b/include/qpdf/Pl_Concatenate.hh index 1f4e2f4..4d6bef1 100644 --- a/include/qpdf/Pl_Concatenate.hh +++ b/include/qpdf/Pl_Concatenate.hh @@ -39,7 +39,7 @@ class QPDF_DLL_CLASS Pl_Concatenate: public Pipeline virtual ~Pl_Concatenate(); QPDF_DLL - virtual void write(unsigned char* data, size_t len); + virtual void write(unsigned char const* data, size_t len); QPDF_DLL virtual void finish(); diff --git a/include/qpdf/Pl_Count.hh b/include/qpdf/Pl_Count.hh index d0bf8cb..1df32eb 100644 --- a/include/qpdf/Pl_Count.hh +++ b/include/qpdf/Pl_Count.hh @@ -36,7 +36,7 @@ class QPDF_DLL_CLASS Pl_Count: public Pipeline QPDF_DLL virtual ~Pl_Count(); QPDF_DLL - virtual void write(unsigned char*, size_t); + virtual void write(unsigned char const*, size_t); QPDF_DLL virtual void finish(); // Returns the number of bytes written diff --git a/include/qpdf/Pl_DCT.hh b/include/qpdf/Pl_DCT.hh index 3503ac7..fcbf1c2 100644 --- a/include/qpdf/Pl_DCT.hh +++ b/include/qpdf/Pl_DCT.hh @@ -61,7 +61,7 @@ class QPDF_DLL_CLASS Pl_DCT: public Pipeline virtual ~Pl_DCT(); QPDF_DLL - virtual void write(unsigned char* data, size_t len); + virtual void write(unsigned char const* data, size_t len); QPDF_DLL virtual void finish(); diff --git a/include/qpdf/Pl_Discard.hh b/include/qpdf/Pl_Discard.hh index c58c162..ae63b8d 100644 --- a/include/qpdf/Pl_Discard.hh +++ b/include/qpdf/Pl_Discard.hh @@ -38,7 +38,7 @@ class QPDF_DLL_CLASS Pl_Discard: public Pipeline QPDF_DLL virtual ~Pl_Discard(); QPDF_DLL - virtual void write(unsigned char*, size_t); + virtual void write(unsigned char const*, size_t); QPDF_DLL virtual void finish(); diff --git a/include/qpdf/Pl_Flate.hh b/include/qpdf/Pl_Flate.hh index daf0583..ee79718 100644 --- a/include/qpdf/Pl_Flate.hh +++ b/include/qpdf/Pl_Flate.hh @@ -43,7 +43,7 @@ class QPDF_DLL_CLASS Pl_Flate: public Pipeline virtual ~Pl_Flate(); QPDF_DLL - virtual void write(unsigned char* data, size_t len); + virtual void write(unsigned char const* data, size_t len); QPDF_DLL virtual void finish(); @@ -61,7 +61,7 @@ class QPDF_DLL_CLASS Pl_Flate: public Pipeline private: QPDF_DLL_PRIVATE - void handleData(unsigned char* data, size_t len, int flush); + void handleData(unsigned char const* data, size_t len, int flush); QPDF_DLL_PRIVATE void checkError(char const* prefix, int error_code); QPDF_DLL_PRIVATE diff --git a/include/qpdf/Pl_QPDFTokenizer.hh b/include/qpdf/Pl_QPDFTokenizer.hh index 20f3660..5dbaf78 100644 --- a/include/qpdf/Pl_QPDFTokenizer.hh +++ b/include/qpdf/Pl_QPDFTokenizer.hh @@ -55,7 +55,7 @@ class QPDF_DLL_CLASS Pl_QPDFTokenizer: public Pipeline QPDF_DLL virtual ~Pl_QPDFTokenizer(); QPDF_DLL - virtual void write(unsigned char* buf, size_t len); + virtual void write(unsigned char const* buf, size_t len); QPDF_DLL virtual void finish(); diff --git a/include/qpdf/Pl_RunLength.hh b/include/qpdf/Pl_RunLength.hh index 47c72d6..92023f4 100644 --- a/include/qpdf/Pl_RunLength.hh +++ b/include/qpdf/Pl_RunLength.hh @@ -35,15 +35,15 @@ class QPDF_DLL_CLASS Pl_RunLength: public Pipeline virtual ~Pl_RunLength(); QPDF_DLL - virtual void write(unsigned char* data, size_t len); + virtual void write(unsigned char const* data, size_t len); QPDF_DLL virtual void finish(); private: QPDF_DLL_PRIVATE - void encode(unsigned char* data, size_t len); + void encode(unsigned char const* data, size_t len); QPDF_DLL_PRIVATE - void decode(unsigned char* data, size_t len); + void decode(unsigned char const* data, size_t len); QPDF_DLL_PRIVATE void flush_encode(); diff --git a/include/qpdf/Pl_StdioFile.hh b/include/qpdf/Pl_StdioFile.hh index 1dfb6c9..ae3a86e 100644 --- a/include/qpdf/Pl_StdioFile.hh +++ b/include/qpdf/Pl_StdioFile.hh @@ -43,7 +43,7 @@ class QPDF_DLL_CLASS Pl_StdioFile: public Pipeline virtual ~Pl_StdioFile(); QPDF_DLL - virtual void write(unsigned char* buf, size_t len); + virtual void write(unsigned char const* buf, size_t len); QPDF_DLL virtual void finish(); diff --git a/include/qpdf/QPDFCryptoImpl.hh b/include/qpdf/QPDFCryptoImpl.hh index bf3c908..a88b416 100644 --- a/include/qpdf/QPDFCryptoImpl.hh +++ b/include/qpdf/QPDFCryptoImpl.hh @@ -78,7 +78,9 @@ class QPDF_DLL_CLASS QPDFCryptoImpl // out_data = 0 means to encrypt/decrypt in place QPDF_DLL virtual void RC4_process( - unsigned char* in_data, size_t len, unsigned char* out_data = 0) = 0; + unsigned char const* in_data, + size_t len, + unsigned char* out_data = 0) = 0; QPDF_DLL virtual void RC4_finalize() = 0; diff --git a/libqpdf/Pipeline.cc b/libqpdf/Pipeline.cc index 5c13489..b63dff9 100644 --- a/libqpdf/Pipeline.cc +++ b/libqpdf/Pipeline.cc @@ -1,5 +1,6 @@ #include +#include #include Pipeline::Pipeline(char const* identifier, Pipeline* next) : diff --git a/libqpdf/Pl_AES_PDF.cc b/libqpdf/Pl_AES_PDF.cc index dc281fa..fa42f53 100644 --- a/libqpdf/Pl_AES_PDF.cc +++ b/libqpdf/Pl_AES_PDF.cc @@ -72,10 +72,10 @@ Pl_AES_PDF::useStaticIV() } void -Pl_AES_PDF::write(unsigned char* data, size_t len) +Pl_AES_PDF::write(unsigned char const* data, size_t len) { size_t bytes_left = len; - unsigned char* p = data; + unsigned char const* p = data; while (bytes_left > 0) { if (this->offset == this->buf_size) { diff --git a/libqpdf/Pl_ASCII85Decoder.cc b/libqpdf/Pl_ASCII85Decoder.cc index 41dad3b..1e3d1b4 100644 --- a/libqpdf/Pl_ASCII85Decoder.cc +++ b/libqpdf/Pl_ASCII85Decoder.cc @@ -13,7 +13,7 @@ Pl_ASCII85Decoder::Pl_ASCII85Decoder(char const* identifier, Pipeline* next) : } void -Pl_ASCII85Decoder::write(unsigned char* buf, size_t len) +Pl_ASCII85Decoder::write(unsigned char const* buf, size_t len) { if (eod > 1) { return; diff --git a/libqpdf/Pl_ASCIIHexDecoder.cc b/libqpdf/Pl_ASCIIHexDecoder.cc index 9924773..f1c4785 100644 --- a/libqpdf/Pl_ASCIIHexDecoder.cc +++ b/libqpdf/Pl_ASCIIHexDecoder.cc @@ -16,7 +16,7 @@ Pl_ASCIIHexDecoder::Pl_ASCIIHexDecoder(char const* identifier, Pipeline* next) : } void -Pl_ASCIIHexDecoder::write(unsigned char* buf, size_t len) +Pl_ASCIIHexDecoder::write(unsigned char const* buf, size_t len) { if (this->eod) { return; diff --git a/libqpdf/Pl_Base64.cc b/libqpdf/Pl_Base64.cc index bfacc1d..6fb422c 100644 --- a/libqpdf/Pl_Base64.cc +++ b/libqpdf/Pl_Base64.cc @@ -35,7 +35,7 @@ Pl_Base64::Pl_Base64(char const* identifier, Pipeline* next, action_e action) : } void -Pl_Base64::write(unsigned char* data, size_t len) +Pl_Base64::write(unsigned char const* data, size_t len) { if (finished) { throw std::logic_error("Pl_Base64 used after finished"); @@ -48,9 +48,9 @@ Pl_Base64::write(unsigned char* data, size_t len) } void -Pl_Base64::decode(unsigned char* data, size_t len) +Pl_Base64::decode(unsigned char const* data, size_t len) { - unsigned char* p = data; + unsigned char const* p = data; while (len > 0) { if (!QUtil::is_space(to_c(*p))) { this->buf[this->pos++] = *p; @@ -64,9 +64,9 @@ Pl_Base64::decode(unsigned char* data, size_t len) } void -Pl_Base64::encode(unsigned char* data, size_t len) +Pl_Base64::encode(unsigned char const* data, size_t len) { - unsigned char* p = data; + unsigned char const* p = data; while (len > 0) { this->buf[this->pos++] = *p; if (this->pos == 3) { diff --git a/libqpdf/Pl_Buffer.cc b/libqpdf/Pl_Buffer.cc index 4f45acb..829d0e7 100644 --- a/libqpdf/Pl_Buffer.cc +++ b/libqpdf/Pl_Buffer.cc @@ -24,7 +24,7 @@ Pl_Buffer::~Pl_Buffer() } void -Pl_Buffer::write(unsigned char* buf, size_t len) +Pl_Buffer::write(unsigned char const* buf, size_t len) { if (this->m->data.get() == 0) { this->m->data = std::make_shared(len); diff --git a/libqpdf/Pl_Concatenate.cc b/libqpdf/Pl_Concatenate.cc index dc74618..ecb20a4 100644 --- a/libqpdf/Pl_Concatenate.cc +++ b/libqpdf/Pl_Concatenate.cc @@ -12,7 +12,7 @@ Pl_Concatenate::~Pl_Concatenate() } void -Pl_Concatenate::write(unsigned char* data, size_t len) +Pl_Concatenate::write(unsigned char const* data, size_t len) { getNext()->write(data, len); } diff --git a/libqpdf/Pl_Count.cc b/libqpdf/Pl_Count.cc index fb13572..8652678 100644 --- a/libqpdf/Pl_Count.cc +++ b/libqpdf/Pl_Count.cc @@ -21,7 +21,7 @@ Pl_Count::~Pl_Count() } void -Pl_Count::write(unsigned char* buf, size_t len) +Pl_Count::write(unsigned char const* buf, size_t len) { if (len) { this->m->count += QIntC::to_offset(len); diff --git a/libqpdf/Pl_DCT.cc b/libqpdf/Pl_DCT.cc index 653fa55..a05dd48 100644 --- a/libqpdf/Pl_DCT.cc +++ b/libqpdf/Pl_DCT.cc @@ -86,7 +86,7 @@ Pl_DCT::~Pl_DCT() } void -Pl_DCT::write(unsigned char* data, size_t len) +Pl_DCT::write(unsigned char const* data, size_t len) { this->m->buf.write(data, len); } diff --git a/libqpdf/Pl_Discard.cc b/libqpdf/Pl_Discard.cc index fc46c3c..4e0da6f 100644 --- a/libqpdf/Pl_Discard.cc +++ b/libqpdf/Pl_Discard.cc @@ -14,7 +14,7 @@ Pl_Discard::~Pl_Discard() } void -Pl_Discard::write(unsigned char* buf, size_t len) +Pl_Discard::write(unsigned char const* buf, size_t len) { } diff --git a/libqpdf/Pl_Flate.cc b/libqpdf/Pl_Flate.cc index 05a3bbc..3ce7f43 100644 --- a/libqpdf/Pl_Flate.cc +++ b/libqpdf/Pl_Flate.cc @@ -84,7 +84,7 @@ Pl_Flate::warn(char const* msg, int code) } void -Pl_Flate::write(unsigned char* data, size_t len) +Pl_Flate::write(unsigned char const* data, size_t len) { if (this->m->outbuf.get() == 0) { throw std::logic_error( @@ -96,7 +96,7 @@ Pl_Flate::write(unsigned char* data, size_t len) // Assume int is at least 32 bits. static size_t const max_bytes = 1 << 30; size_t bytes_left = len; - unsigned char* buf = data; + unsigned char const* buf = data; while (bytes_left > 0) { size_t bytes = (bytes_left >= max_bytes ? max_bytes : bytes_left); handleData( @@ -109,14 +109,16 @@ Pl_Flate::write(unsigned char* data, size_t len) } void -Pl_Flate::handleData(unsigned char* data, size_t len, int flush) +Pl_Flate::handleData(unsigned char const* data, size_t len, int flush) { if (len > UINT_MAX) { throw std::runtime_error("Pl_Flate: zlib doesn't support data" " blocks larger than int"); } z_stream& zstream = *(static_cast(this->m->zdata)); - zstream.next_in = data; + // zlib is known not to modify the data pointed to by next_in but + // doesn't declare the field value const unless compiled to do so. + zstream.next_in = const_cast(data); zstream.avail_in = QIntC::to_uint(len); if (!this->m->initialized) { diff --git a/libqpdf/Pl_LZWDecoder.cc b/libqpdf/Pl_LZWDecoder.cc index db6d749..3a38189 100644 --- a/libqpdf/Pl_LZWDecoder.cc +++ b/libqpdf/Pl_LZWDecoder.cc @@ -22,7 +22,7 @@ Pl_LZWDecoder::Pl_LZWDecoder( } void -Pl_LZWDecoder::write(unsigned char* bytes, size_t len) +Pl_LZWDecoder::write(unsigned char const* bytes, size_t len) { for (size_t i = 0; i < len; ++i) { this->buf[next++] = bytes[i]; diff --git a/libqpdf/Pl_MD5.cc b/libqpdf/Pl_MD5.cc index a5e6413..358f580 100644 --- a/libqpdf/Pl_MD5.cc +++ b/libqpdf/Pl_MD5.cc @@ -11,7 +11,7 @@ Pl_MD5::Pl_MD5(char const* identifier, Pipeline* next) : } void -Pl_MD5::write(unsigned char* buf, size_t len) +Pl_MD5::write(unsigned char const* buf, size_t len) { if (this->enabled) { if (!this->in_progress) { @@ -23,11 +23,11 @@ Pl_MD5::write(unsigned char* buf, size_t len) // Assume int is at least 32 bits. static size_t const max_bytes = 1 << 30; size_t bytes_left = len; - unsigned char* data = buf; + unsigned char const* data = buf; while (bytes_left > 0) { size_t bytes = (bytes_left >= max_bytes ? max_bytes : bytes_left); this->md5.encodeDataIncrementally( - reinterpret_cast(data), bytes); + reinterpret_cast(data), bytes); bytes_left -= bytes; data += bytes; } diff --git a/libqpdf/Pl_PNGFilter.cc b/libqpdf/Pl_PNGFilter.cc index d62aec5..7914b3b 100644 --- a/libqpdf/Pl_PNGFilter.cc +++ b/libqpdf/Pl_PNGFilter.cc @@ -62,7 +62,7 @@ Pl_PNGFilter::Pl_PNGFilter( } void -Pl_PNGFilter::write(unsigned char* data, size_t len) +Pl_PNGFilter::write(unsigned char const* data, size_t len) { size_t left = this->incoming - this->pos; size_t offset = 0; diff --git a/libqpdf/Pl_QPDFTokenizer.cc b/libqpdf/Pl_QPDFTokenizer.cc index 97efb51..85b5fcc 100644 --- a/libqpdf/Pl_QPDFTokenizer.cc +++ b/libqpdf/Pl_QPDFTokenizer.cc @@ -33,7 +33,7 @@ Pl_QPDFTokenizer::~Pl_QPDFTokenizer() } void -Pl_QPDFTokenizer::write(unsigned char* data, size_t len) +Pl_QPDFTokenizer::write(unsigned char const* data, size_t len) { this->m->buf.write(data, len); } diff --git a/libqpdf/Pl_RC4.cc b/libqpdf/Pl_RC4.cc index 6f04ab6..1f64b5d 100644 --- a/libqpdf/Pl_RC4.cc +++ b/libqpdf/Pl_RC4.cc @@ -16,7 +16,7 @@ Pl_RC4::Pl_RC4( } void -Pl_RC4::write(unsigned char* data, size_t len) +Pl_RC4::write(unsigned char const* data, size_t len) { if (this->outbuf.get() == 0) { throw std::logic_error( @@ -25,7 +25,7 @@ Pl_RC4::write(unsigned char* data, size_t len) } size_t bytes_left = len; - unsigned char* p = data; + unsigned char const* p = data; while (bytes_left > 0) { size_t bytes = diff --git a/libqpdf/Pl_RunLength.cc b/libqpdf/Pl_RunLength.cc index 86e4b68..786e2e8 100644 --- a/libqpdf/Pl_RunLength.cc +++ b/libqpdf/Pl_RunLength.cc @@ -24,7 +24,7 @@ Pl_RunLength::~Pl_RunLength() } void -Pl_RunLength::write(unsigned char* data, size_t len) +Pl_RunLength::write(unsigned char const* data, size_t len) { if (this->m->action == a_encode) { encode(data, len); @@ -34,7 +34,7 @@ Pl_RunLength::write(unsigned char* data, size_t len) } void -Pl_RunLength::encode(unsigned char* data, size_t len) +Pl_RunLength::encode(unsigned char const* data, size_t len) { for (size_t i = 0; i < len; ++i) { if ((this->m->state == st_top) != (this->m->length <= 1)) { @@ -71,7 +71,7 @@ Pl_RunLength::encode(unsigned char* data, size_t len) } void -Pl_RunLength::decode(unsigned char* data, size_t len) +Pl_RunLength::decode(unsigned char const* data, size_t len) { for (size_t i = 0; i < len; ++i) { unsigned char ch = data[i]; diff --git a/libqpdf/Pl_SHA2.cc b/libqpdf/Pl_SHA2.cc index a89cf21..c54bd7e 100644 --- a/libqpdf/Pl_SHA2.cc +++ b/libqpdf/Pl_SHA2.cc @@ -15,7 +15,7 @@ Pl_SHA2::Pl_SHA2(int bits, Pipeline* next) : } void -Pl_SHA2::write(unsigned char* buf, size_t len) +Pl_SHA2::write(unsigned char const* buf, size_t len) { if (!this->in_progress) { this->in_progress = true; @@ -25,7 +25,7 @@ Pl_SHA2::write(unsigned char* buf, size_t len) // Assume int is at least 32 bits. static size_t const max_bytes = 1 << 30; size_t bytes_left = len; - unsigned char* data = buf; + unsigned char const* data = buf; while (bytes_left > 0) { size_t bytes = (bytes_left >= max_bytes ? max_bytes : bytes_left); this->crypto->SHA2_update(data, bytes); diff --git a/libqpdf/Pl_StdioFile.cc b/libqpdf/Pl_StdioFile.cc index 78b3114..2415ef9 100644 --- a/libqpdf/Pl_StdioFile.cc +++ b/libqpdf/Pl_StdioFile.cc @@ -24,7 +24,7 @@ Pl_StdioFile::~Pl_StdioFile() } void -Pl_StdioFile::write(unsigned char* buf, size_t len) +Pl_StdioFile::write(unsigned char const* buf, size_t len) { size_t so_far = 0; while (len > 0) { diff --git a/libqpdf/Pl_TIFFPredictor.cc b/libqpdf/Pl_TIFFPredictor.cc index fe788da..c29396d 100644 --- a/libqpdf/Pl_TIFFPredictor.cc +++ b/libqpdf/Pl_TIFFPredictor.cc @@ -46,7 +46,7 @@ Pl_TIFFPredictor::Pl_TIFFPredictor( } void -Pl_TIFFPredictor::write(unsigned char* data, size_t len) +Pl_TIFFPredictor::write(unsigned char const* data, size_t len) { size_t left = this->bytes_per_row - this->pos; size_t offset = 0; diff --git a/libqpdf/QPDFCrypto_gnutls.cc b/libqpdf/QPDFCrypto_gnutls.cc index 86e92c4..dabf912 100644 --- a/libqpdf/QPDFCrypto_gnutls.cc +++ b/libqpdf/QPDFCrypto_gnutls.cc @@ -97,11 +97,8 @@ QPDFCrypto_gnutls::RC4_init(unsigned char const* key_data, int key_len) void QPDFCrypto_gnutls::RC4_process( - unsigned char* in_data, size_t len, unsigned char* out_data) + unsigned char const* in_data, size_t len, unsigned char* out_data) { - if (nullptr == out_data) { - out_data = in_data; - } gnutls_cipher_encrypt2(this->cipher_ctx, in_data, len, out_data, len); } diff --git a/libqpdf/QPDFCrypto_native.cc b/libqpdf/QPDFCrypto_native.cc index 5255ba3..458e90c 100644 --- a/libqpdf/QPDFCrypto_native.cc +++ b/libqpdf/QPDFCrypto_native.cc @@ -69,7 +69,7 @@ QPDFCrypto_native::RC4_init(unsigned char const* key_data, int key_len) void QPDFCrypto_native::RC4_process( - unsigned char* in_data, size_t len, unsigned char* out_data) + unsigned char const* in_data, size_t len, unsigned char* out_data) { this->rc4->process(in_data, len, out_data); } diff --git a/libqpdf/QPDFCrypto_openssl.cc b/libqpdf/QPDFCrypto_openssl.cc index 52b2fa0..b82094a 100644 --- a/libqpdf/QPDFCrypto_openssl.cc +++ b/libqpdf/QPDFCrypto_openssl.cc @@ -217,11 +217,8 @@ QPDFCrypto_openssl::rijndael_init( void QPDFCrypto_openssl::RC4_process( - unsigned char* in_data, size_t len, unsigned char* out_data) + unsigned char const* in_data, size_t len, unsigned char* out_data) { - if (nullptr == out_data) { - out_data = in_data; - } int out_len = static_cast(len); check_openssl( EVP_EncryptUpdate(cipher_ctx, out_data, &out_len, in_data, out_len)); diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index 76a6127..e1c9488 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -180,7 +180,7 @@ namespace public: LastChar(Pipeline* next); virtual ~LastChar() = default; - virtual void write(unsigned char* data, size_t len); + virtual void write(unsigned char const* data, size_t len); virtual void finish(); unsigned char getLastChar(); @@ -196,7 +196,7 @@ LastChar::LastChar(Pipeline* next) : } void -LastChar::write(unsigned char* data, size_t len) +LastChar::write(unsigned char const* data, size_t len) { if (len > 0) { this->last_char = data[len - 1]; diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc index 103abee..4b2e785 100644 --- a/libqpdf/QPDFWriter.cc +++ b/libqpdf/QPDFWriter.cc @@ -1750,7 +1750,8 @@ QPDFWriter::unparseObject( RC4 rc4( QUtil::unsigned_char_pointer(this->m->cur_data_key), QIntC::to_int(this->m->cur_data_key.length())); - rc4.process(QUtil::unsigned_char_pointer(tmp), vlen); + auto data = QUtil::unsigned_char_pointer(tmp); + rc4.process(data, vlen, data); val = QPDF_String(std::string(tmp, vlen)).unparse(); } } else if (flags & f_hex_string) { diff --git a/libqpdf/QPDF_encryption.cc b/libqpdf/QPDF_encryption.cc index 6a9ad87..5fb1e80 100644 --- a/libqpdf/QPDF_encryption.cc +++ b/libqpdf/QPDF_encryption.cc @@ -207,7 +207,7 @@ iterate_rc4( key[j] = static_cast(okey[j] ^ xor_value); } RC4 rc4(key, QIntC::to_int(key_len)); - rc4.process(data, data_len); + rc4.process(data, data_len, data); } } @@ -1163,7 +1163,8 @@ QPDF::decryptString(std::string& str, int objid, int generation) // be freed even if rc4.process throws an exception. auto tmp = QUtil::make_unique_cstr(str); RC4 rc4(QUtil::unsigned_char_pointer(key), toI(key.length())); - rc4.process(QUtil::unsigned_char_pointer(tmp.get()), vlen); + auto data = QUtil::unsigned_char_pointer(tmp.get()); + rc4.process(data, vlen, data); str = std::string(tmp.get(), vlen); } } catch (QPDFExc&) { diff --git a/libqpdf/RC4.cc b/libqpdf/RC4.cc index 4859c87..6fc25a8 100644 --- a/libqpdf/RC4.cc +++ b/libqpdf/RC4.cc @@ -11,7 +11,7 @@ RC4::RC4(unsigned char const* key_data, int key_len) : } void -RC4::process(unsigned char* in_data, size_t len, unsigned char* out_data) +RC4::process(unsigned char const* in_data, size_t len, unsigned char* out_data) { this->crypto->RC4_process(in_data, len, out_data); } diff --git a/libqpdf/RC4_native.cc b/libqpdf/RC4_native.cc index e2d3655..a29e78e 100644 --- a/libqpdf/RC4_native.cc +++ b/libqpdf/RC4_native.cc @@ -37,13 +37,9 @@ RC4_native::RC4_native(unsigned char const* key_data, int key_len) } void -RC4_native::process(unsigned char* in_data, size_t len, unsigned char* out_data) +RC4_native::process( + unsigned char const* in_data, size_t len, unsigned char* out_data) { - if (out_data == 0) { - // Convert in place - out_data = in_data; - } - for (size_t i = 0; i < len; ++i) { key.x = static_cast((key.x + 1) % 256); key.y = static_cast((key.state[key.x] + key.y) % 256); diff --git a/libqpdf/qpdf/Pl_AES_PDF.hh b/libqpdf/qpdf/Pl_AES_PDF.hh index 036842d..1809158 100644 --- a/libqpdf/qpdf/Pl_AES_PDF.hh +++ b/libqpdf/qpdf/Pl_AES_PDF.hh @@ -20,7 +20,7 @@ class Pl_AES_PDF: public Pipeline size_t key_bytes); virtual ~Pl_AES_PDF() = default; - virtual void write(unsigned char* data, size_t len); + virtual void write(unsigned char const* data, size_t len); virtual void finish(); // Use zero initialization vector; needed for AESV3 diff --git a/libqpdf/qpdf/Pl_ASCII85Decoder.hh b/libqpdf/qpdf/Pl_ASCII85Decoder.hh index b359e16..667b56e 100644 --- a/libqpdf/qpdf/Pl_ASCII85Decoder.hh +++ b/libqpdf/qpdf/Pl_ASCII85Decoder.hh @@ -8,7 +8,7 @@ class Pl_ASCII85Decoder: public Pipeline public: Pl_ASCII85Decoder(char const* identifier, Pipeline* next); virtual ~Pl_ASCII85Decoder() = default; - virtual void write(unsigned char* buf, size_t len); + virtual void write(unsigned char const* buf, size_t len); virtual void finish(); private: diff --git a/libqpdf/qpdf/Pl_ASCIIHexDecoder.hh b/libqpdf/qpdf/Pl_ASCIIHexDecoder.hh index a385cce..c71dcf0 100644 --- a/libqpdf/qpdf/Pl_ASCIIHexDecoder.hh +++ b/libqpdf/qpdf/Pl_ASCIIHexDecoder.hh @@ -8,7 +8,7 @@ class Pl_ASCIIHexDecoder: public Pipeline public: Pl_ASCIIHexDecoder(char const* identifier, Pipeline* next); virtual ~Pl_ASCIIHexDecoder() = default; - virtual void write(unsigned char* buf, size_t len); + virtual void write(unsigned char const* buf, size_t len); virtual void finish(); private: diff --git a/libqpdf/qpdf/Pl_Base64.hh b/libqpdf/qpdf/Pl_Base64.hh index 313bd2c..788bfd6 100644 --- a/libqpdf/qpdf/Pl_Base64.hh +++ b/libqpdf/qpdf/Pl_Base64.hh @@ -9,12 +9,12 @@ class Pl_Base64: public Pipeline enum action_e { a_encode, a_decode }; Pl_Base64(char const* identifier, Pipeline* next, action_e); virtual ~Pl_Base64() = default; - virtual void write(unsigned char* buf, size_t len) override; + virtual void write(unsigned char const* buf, size_t len) override; virtual void finish() override; private: - void decode(unsigned char* buf, size_t len); - void encode(unsigned char* buf, size_t len); + void decode(unsigned char const* buf, size_t len); + void encode(unsigned char const* buf, size_t len); void flush(); void flush_decode(); void flush_encode(); diff --git a/libqpdf/qpdf/Pl_LZWDecoder.hh b/libqpdf/qpdf/Pl_LZWDecoder.hh index e157ee5..46cce7b 100644 --- a/libqpdf/qpdf/Pl_LZWDecoder.hh +++ b/libqpdf/qpdf/Pl_LZWDecoder.hh @@ -12,7 +12,7 @@ class Pl_LZWDecoder: public Pipeline Pl_LZWDecoder( char const* identifier, Pipeline* next, bool early_code_change); virtual ~Pl_LZWDecoder() = default; - virtual void write(unsigned char* buf, size_t len); + virtual void write(unsigned char const* buf, size_t len); virtual void finish(); private: diff --git a/libqpdf/qpdf/Pl_MD5.hh b/libqpdf/qpdf/Pl_MD5.hh index bbefba0..bd56f9c 100644 --- a/libqpdf/qpdf/Pl_MD5.hh +++ b/libqpdf/qpdf/Pl_MD5.hh @@ -17,7 +17,7 @@ class Pl_MD5: public Pipeline public: Pl_MD5(char const* identifier, Pipeline* next); virtual ~Pl_MD5() = default; - virtual void write(unsigned char*, size_t); + virtual void write(unsigned char const*, size_t); virtual void finish(); std::string getHexDigest(); // Enable/disable. Disabling the pipeline causes it to become a diff --git a/libqpdf/qpdf/Pl_PNGFilter.hh b/libqpdf/qpdf/Pl_PNGFilter.hh index 27986c5..6cc34a9 100644 --- a/libqpdf/qpdf/Pl_PNGFilter.hh +++ b/libqpdf/qpdf/Pl_PNGFilter.hh @@ -24,7 +24,7 @@ class Pl_PNGFilter: public Pipeline unsigned int bits_per_sample = 8); virtual ~Pl_PNGFilter() = default; - virtual void write(unsigned char* data, size_t len); + virtual void write(unsigned char const* data, size_t len); virtual void finish(); private: diff --git a/libqpdf/qpdf/Pl_RC4.hh b/libqpdf/qpdf/Pl_RC4.hh index b5fc508..07b8a1c 100644 --- a/libqpdf/qpdf/Pl_RC4.hh +++ b/libqpdf/qpdf/Pl_RC4.hh @@ -19,7 +19,7 @@ class Pl_RC4: public Pipeline size_t out_bufsize = def_bufsize); virtual ~Pl_RC4() = default; - virtual void write(unsigned char* data, size_t len); + virtual void write(unsigned char const* data, size_t len); virtual void finish(); private: diff --git a/libqpdf/qpdf/Pl_SHA2.hh b/libqpdf/qpdf/Pl_SHA2.hh index ba782bc..d5b2e54 100644 --- a/libqpdf/qpdf/Pl_SHA2.hh +++ b/libqpdf/qpdf/Pl_SHA2.hh @@ -22,7 +22,7 @@ class Pl_SHA2: public Pipeline public: Pl_SHA2(int bits = 0, Pipeline* next = 0); virtual ~Pl_SHA2() = default; - virtual void write(unsigned char*, size_t); + virtual void write(unsigned char const*, size_t); virtual void finish(); void resetBits(int bits); std::string getHexDigest(); diff --git a/libqpdf/qpdf/Pl_TIFFPredictor.hh b/libqpdf/qpdf/Pl_TIFFPredictor.hh index 22c9322..2b3bdb1 100644 --- a/libqpdf/qpdf/Pl_TIFFPredictor.hh +++ b/libqpdf/qpdf/Pl_TIFFPredictor.hh @@ -20,7 +20,7 @@ class Pl_TIFFPredictor: public Pipeline unsigned int bits_per_sample = 8); virtual ~Pl_TIFFPredictor() = default; - virtual void write(unsigned char* data, size_t len); + virtual void write(unsigned char const* data, size_t len); virtual void finish(); private: diff --git a/libqpdf/qpdf/QPDFCrypto_gnutls.hh b/libqpdf/qpdf/QPDFCrypto_gnutls.hh index 2325944..05c94bf 100644 --- a/libqpdf/qpdf/QPDFCrypto_gnutls.hh +++ b/libqpdf/qpdf/QPDFCrypto_gnutls.hh @@ -26,7 +26,7 @@ class QPDFCrypto_gnutls: public QPDFCryptoImpl virtual void RC4_init(unsigned char const* key_data, int key_len = -1); virtual void RC4_process( - unsigned char* in_data, size_t len, unsigned char* out_data = 0); + unsigned char const* in_data, size_t len, unsigned char* out_data = 0); virtual void RC4_finalize(); virtual void SHA2_init(int bits); diff --git a/libqpdf/qpdf/QPDFCrypto_native.hh b/libqpdf/qpdf/QPDFCrypto_native.hh index ec3cab2..0beca39 100644 --- a/libqpdf/qpdf/QPDFCrypto_native.hh +++ b/libqpdf/qpdf/QPDFCrypto_native.hh @@ -24,7 +24,7 @@ class QPDFCrypto_native: public QPDFCryptoImpl virtual void RC4_init(unsigned char const* key_data, int key_len = -1); virtual void RC4_process( - unsigned char* in_data, size_t len, unsigned char* out_data = 0); + unsigned char const* in_data, size_t len, unsigned char* out_data = 0); virtual void RC4_finalize(); virtual void SHA2_init(int bits); diff --git a/libqpdf/qpdf/QPDFCrypto_openssl.hh b/libqpdf/qpdf/QPDFCrypto_openssl.hh index 9bdaaae..252bdf6 100644 --- a/libqpdf/qpdf/QPDFCrypto_openssl.hh +++ b/libqpdf/qpdf/QPDFCrypto_openssl.hh @@ -37,7 +37,7 @@ class QPDFCrypto_openssl: public QPDFCryptoImpl void RC4_init(unsigned char const* key_data, int key_len = -1) override; void RC4_process( - unsigned char* in_data, + unsigned char const* in_data, size_t len, unsigned char* out_data = 0) override; void RC4_finalize() override; diff --git a/libqpdf/qpdf/RC4.hh b/libqpdf/qpdf/RC4.hh index 43326d9..00de390 100644 --- a/libqpdf/qpdf/RC4.hh +++ b/libqpdf/qpdf/RC4.hh @@ -11,9 +11,10 @@ class RC4 // key_len of -1 means treat key_data as a null-terminated string RC4(unsigned char const* key_data, int key_len = -1); - // out_data = 0 means to encrypt/decrypt in place + // It is safe to pass the same pointer to in_data and out_data to + // encrypt/decrypt in place void - process(unsigned char* in_data, size_t len, unsigned char* out_data = 0); + process(unsigned char const* in_data, size_t len, unsigned char* out_data); private: std::shared_ptr crypto; diff --git a/libqpdf/qpdf/RC4_native.hh b/libqpdf/qpdf/RC4_native.hh index 4693ff9..e740408 100644 --- a/libqpdf/qpdf/RC4_native.hh +++ b/libqpdf/qpdf/RC4_native.hh @@ -10,8 +10,8 @@ class RC4_native RC4_native(unsigned char const* key_data, int key_len = -1); // out_data = 0 means to encrypt/decrypt in place - void - process(unsigned char* in_data, size_t len, unsigned char* out_data = 0); + void process( + unsigned char const* in_data, size_t len, unsigned char* out_data = 0); private: class RC4Key diff --git a/libtests/rc4.cc b/libtests/rc4.cc index 1b1a874..a6a1328 100644 --- a/libtests/rc4.cc +++ b/libtests/rc4.cc @@ -18,7 +18,7 @@ other_tests() RC4 r(reinterpret_cast("quack")); auto data = std::make_unique(6); memcpy(data.get(), "potato", 6); - r.process(data.get(), 6); + r.process(data.get(), 6, data.get()); assert(memcmp(data.get(), "\xa5\x6f\xe7\x27\x2b\x5c", 6) == 0); std::cout << "passed" << std::endl; } diff --git a/manual/release-notes.rst b/manual/release-notes.rst index 8a90895..b378301 100644 --- a/manual/release-notes.rst +++ b/manual/release-notes.rst @@ -68,12 +68,18 @@ For a detailed list of changes, please see the file - API: breaking changes - - Remove + - Pipeline::write now takes ``unsigned char const*`` instead of + ``unsigned char*``. Callers don't need to change anything, but + you no longer have to pass writable pointers to pipelines. If + you've implemented your own pipeline classes, you will need to + update them. + + - Remove deprecated ``QPDFAcroFormDocumentHelper::copyFieldsFromForeignPage``. This method never worked and only did something in qpdf version 10.2.x. - - Remove ``QPDFNameTreeObjectHelper`` and + - Remove deprecated ``QPDFNameTreeObjectHelper`` and ``QPDFNumberTreeObjectHelper`` constructors that don't take a ``QPDF&`` argument. diff --git a/qpdf/test_large_file.cc b/qpdf/test_large_file.cc index 904f3dd..4f4f5a4 100644 --- a/qpdf/test_large_file.cc +++ b/qpdf/test_large_file.cc @@ -63,7 +63,7 @@ class ImageChecker: public Pipeline public: ImageChecker(size_t n); virtual ~ImageChecker() = default; - virtual void write(unsigned char* data, size_t len); + virtual void write(unsigned char const* data, size_t len); virtual void finish(); private: @@ -81,7 +81,7 @@ ImageChecker::ImageChecker(size_t n) : } void -ImageChecker::write(unsigned char* data, size_t len) +ImageChecker::write(unsigned char const* data, size_t len) { for (size_t i = 0; i < len; ++i) { size_t y = (this->offset + i) / width / stripesize;