From b30deaeeaba3941d7615bc2cc89c664b1273e5df Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Fri, 23 Oct 2020 06:40:27 -0400 Subject: Avoid merging adjacent tokens when concatenating contents (fixes #444) --- libqpdf/QPDFObjectHandle.cc | 53 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) (limited to 'libqpdf/QPDFObjectHandle.cc') diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index 85493680..472ff4e8 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -165,6 +165,47 @@ QPDFObjectHandle::ParserCallbacks::terminateParsing() throw TerminateParsing(); } +class LastChar: public Pipeline +{ + public: + LastChar(Pipeline* next); + virtual ~LastChar() = default; + virtual void write(unsigned char* data, size_t len); + virtual void finish(); + unsigned char getLastChar(); + + private: + unsigned char last_char; +}; + +LastChar::LastChar(Pipeline* next) : + Pipeline("lastchar", next), + last_char(0) +{ +} + +void +LastChar::write(unsigned char* data, size_t len) +{ + if (len > 0) + { + this->last_char = data[len - 1]; + } + getNext()->write(data, len); +} + +void +LastChar::finish() +{ + getNext()->finish(); +} + +unsigned char +LastChar::getLastChar() +{ + return this->last_char; +} + QPDFObjectHandle::QPDFObjectHandle() : initialized(false), qpdf(0), @@ -1600,21 +1641,31 @@ QPDFObjectHandle::pipeContentStreams( std::vector streams = arrayOrStreamToStreamArray( description, all_description); + bool need_newline = false; for (std::vector::iterator iter = streams.begin(); iter != streams.end(); ++iter) { + if (need_newline) + { + p->write(QUtil::unsigned_char_pointer("\n"), 1); + } + LastChar lc(p); QPDFObjectHandle stream = *iter; std::string og = QUtil::int_to_string(stream.getObjectID()) + " " + QUtil::int_to_string(stream.getGeneration()); std::string w_description = "content stream object " + og; - if (! stream.pipeStreamData(p, 0, qpdf_dl_specialized)) + if (! stream.pipeStreamData(&lc, 0, qpdf_dl_specialized)) { QTC::TC("qpdf", "QPDFObjectHandle errors in parsecontent"); throw QPDFExc(qpdf_e_damaged_pdf, "content stream", w_description, 0, "errors while decoding content stream"); } + lc.finish(); + need_newline = (lc.getLastChar() != static_cast('\n')); + QTC::TC("qpdf", "QPDFObjectHandle need_newline", + need_newline ? 0 : 1); } } -- cgit v1.2.3-54-g00ecf