From e93f7ff527706f5c42eb91c223ccae3df2d8f58e Mon Sep 17 00:00:00 2001 From: m-holger Date: Fri, 14 Mar 2025 09:40:33 +0000 Subject: [PATCH] Tidy QPDF::resolveObjectsInStream --- include/qpdf/QPDF.hh | 3 ++- libqpdf/QPDF_objects.cc | 57 ++++++++++++++++++++++++++------------------------------- 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh index 150f7e6..9d1e90e 100644 --- a/include/qpdf/QPDF.hh +++ b/include/qpdf/QPDF.hh @@ -48,6 +48,7 @@ class QPDF_Stream; class BitStream; class BitWriter; +class BufferInputSource; class QPDFLogger; class QPDFParser; @@ -784,7 +785,7 @@ class QPDF QPDFObjectHandle readObject(std::string const& description, QPDFObjGen og); void readStream(QPDFObjectHandle& object, QPDFObjGen og, qpdf_offset_t offset); void validateStreamLineEnd(QPDFObjectHandle& object, QPDFObjGen og, qpdf_offset_t offset); - QPDFObjectHandle readObjectInStream(std::shared_ptr& input, int obj); + QPDFObjectHandle readObjectInStream(BufferInputSource& input, int obj); size_t recoverStreamLength( std::shared_ptr input, QPDFObjGen og, qpdf_offset_t stream_offset); QPDFTokenizer::Token readToken(InputSource&, size_t max_len = 0); diff --git a/libqpdf/QPDF_objects.cc b/libqpdf/QPDF_objects.cc index 8fc86f7..e67b85f 100644 --- a/libqpdf/QPDF_objects.cc +++ b/libqpdf/QPDF_objects.cc @@ -1292,19 +1292,19 @@ QPDF::validateStreamLineEnd(QPDFObjectHandle& object, QPDFObjGen og, qpdf_offset } QPDFObjectHandle -QPDF::readObjectInStream(std::shared_ptr& input, int obj) +QPDF::readObjectInStream(BufferInputSource& input, int obj) { m->last_object_description.erase(7); // last_object_description starts with "object " m->last_object_description += std::to_string(obj); m->last_object_description += " 0"; bool empty = false; - auto object = QPDFParser(*input, m->last_object_description, m->tokenizer, nullptr, this, true) + auto object = QPDFParser(input, m->last_object_description, m->tokenizer, nullptr, this, true) .parse(empty, false); if (empty) { // Nothing in the PDF spec appears to allow empty objects, but they have been encountered in // actual PDF files and Adobe Reader appears to ignore them. - warn(damagedPDF(*input, input->getLastOffset(), "empty object treated as null")); + warn(damagedPDF(input, input.getLastOffset(), "empty object treated as null")); } return object; } @@ -1610,7 +1610,7 @@ QPDF::resolveObjectsInStream(int obj_stream_number) } m->resolved_object_streams.insert(obj_stream_number); // Force resolution of object stream - QPDFObjectHandle obj_stream = getObjectByID(obj_stream_number, 0); + QPDFObjectHandle obj_stream = getObject(obj_stream_number, 0); if (!obj_stream.isStream()) { throw damagedPDF( "object " + std::to_string(obj_stream_number) + " 0", @@ -1631,33 +1631,29 @@ QPDF::resolveObjectsInStream(int obj_stream_number) "supposed object stream " + std::to_string(obj_stream_number) + " has wrong type")); } - if (!(dict.getKey("/N").isInteger() && dict.getKey("/First").isInteger())) { + unsigned int n{0}; + int first{0}; + if (!(dict.getKey("/N").getValueAsUInt(n) && dict.getKey("/First").getValueAsInt(first))) { throw damagedPDF( "object " + std::to_string(obj_stream_number) + " 0", "object stream " + std::to_string(obj_stream_number) + " has incorrect keys"); } - int n = dict.getKey("/N").getIntValueAsInt(); - int first = dict.getKey("/First").getIntValueAsInt(); + std::vector> offsets; - std::map offsets; - - std::shared_ptr bp = obj_stream.getStreamData(qpdf_dl_specialized); - auto input = std::shared_ptr( - // line-break - new BufferInputSource( - (m->file->getName() + " object stream " + std::to_string(obj_stream_number)), - bp.get())); + auto bp = obj_stream.getStreamData(qpdf_dl_specialized); + BufferInputSource input( + (m->file->getName() + " object stream " + std::to_string(obj_stream_number)), bp.get()); long long last_offset = -1; - for (int i = 0; i < n; ++i) { - QPDFTokenizer::Token tnum = readToken(*input); - QPDFTokenizer::Token toffset = readToken(*input); + for (unsigned int i = 0; i < n; ++i) { + auto tnum = readToken(input); + auto toffset = readToken(input); if (!(tnum.isInteger() && toffset.isInteger())) { throw damagedPDF( - *input, + input, "object " + std::to_string(obj_stream_number) + " 0", - input->getLastOffset(), + input.getLastOffset(), "expected integer in object stream header"); } @@ -1667,9 +1663,9 @@ QPDF::resolveObjectsInStream(int obj_stream_number) if (num == obj_stream_number) { QTC::TC("qpdf", "QPDF ignore self-referential object stream"); warn(damagedPDF( - *input, + input, "object " + std::to_string(obj_stream_number) + " 0", - input->getLastOffset(), + input.getLastOffset(), "object stream claims to contain itself")); continue; } @@ -1677,9 +1673,9 @@ QPDF::resolveObjectsInStream(int obj_stream_number) if (num < 1) { QTC::TC("qpdf", "QPDF object stream contains id < 1"); warn(damagedPDF( - *input, + input, "object " + std::to_string(num) + " 0", - input->getLastOffset(), + input.getLastOffset(), "object id is invalid"s)); continue; } @@ -1687,7 +1683,7 @@ QPDF::resolveObjectsInStream(int obj_stream_number) if (offset <= last_offset) { QTC::TC("qpdf", "QPDF object stream offsets not increasing"); warn(damagedPDF( - *input, + input, "object " + std::to_string(num) + " 0", offset, "offset is invalid (must be larger than previous offset " + @@ -1700,7 +1696,7 @@ QPDF::resolveObjectsInStream(int obj_stream_number) continue; } - offsets[num] = toI(offset + first); + offsets.emplace_back(num, offset + first); } // To avoid having to read the object stream multiple times, store all objects that would be @@ -1709,14 +1705,13 @@ QPDF::resolveObjectsInStream(int obj_stream_number) // cache what would actually be resolved here. m->last_object_description.clear(); m->last_object_description += "object "; - for (auto const& iter: offsets) { - QPDFObjGen og(iter.first, 0); + for (auto const& [id, offset]: offsets) { + QPDFObjGen og(id, 0); auto entry = m->xref_table.find(og); if (entry != m->xref_table.end() && entry->second.getType() == 2 && entry->second.getObjStreamNumber() == obj_stream_number) { - int offset = iter.second; - input->seek(offset, SEEK_SET); - QPDFObjectHandle oh = readObjectInStream(input, iter.first); + input.seek(offset, SEEK_SET); + QPDFObjectHandle oh = readObjectInStream(input, id); updateCache(og, oh.getObj(), end_before_space, end_after_space); } else { QTC::TC("qpdf", "QPDF not caching overridden objstm object"); -- libgit2 0.21.4