diff --git a/libqpdf/QPDFParser.cc b/libqpdf/QPDFParser.cc index e00cd606..8bc9e10a 100644 --- a/libqpdf/QPDFParser.cc +++ b/libqpdf/QPDFParser.cc @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -287,8 +288,8 @@ QPDFParser::parse(bool& empty, bool content_stream) if (!indirect_ref && !is_null) { // No need to set description for direct nulls - they will // become implicit. - setDescriptionFromInput(object, input->getLastOffset()); - object.setParsedOffset(input->getLastOffset()); + auto os = input->getLastOffset(); + setDescription(object, os, os); } set_offset = true; olist.push_back(is_null ? null_oh : object); @@ -311,13 +312,12 @@ QPDFParser::parse(bool& empty, bool content_stream) state_stack.pop_back(); if (old_state == st_array) { object = QPDFObjectHandle::newArray(olist); - setDescriptionFromInput(object, offset); + setDescription(object, offset, offset - 1); // The `offset` points to the next of "[". Set the rewind // offset to point to the beginning of "[". This has been // explicitly tested with whitespace surrounding the array start // delimiter. getLastOffset points to the array end token and // therefore can't be used here. - object.setParsedOffset(offset - 1); set_offset = true; } else if (old_state == st_dictionary) { // Convert list to map. Alternating elements are keys. Attempt @@ -362,7 +362,7 @@ QPDFParser::parse(bool& empty, bool content_stream) "dictionary ended prematurely; " "using null as value for last key"); val = QPDFObjectHandle::newNull(); - setDescriptionFromInput(val, offset); + setDescription(val, offset); } else { val = olist.at(++i); } @@ -386,13 +386,12 @@ QPDFParser::parse(bool& empty, bool content_stream) dict["/Contents"].setParsedOffset(frame.contents_offset); } object = QPDFObjectHandle::newDictionary(dict); - setDescriptionFromInput(object, offset); + setDescription(object, offset, offset - 2); // The `offset` points to the next of "<<". Set the rewind // offset to point to the beginning of "<<". This has been // explicitly tested with whitespace surrounding the dictionary // start delimiter. getLastOffset points to the dictionary end // token and therefore can't be used here. - object.setParsedOffset(offset - 2); set_offset = true; } stack.pop_back(); @@ -408,20 +407,24 @@ QPDFParser::parse(bool& empty, bool content_stream) object = QPDFObjectHandle::newNull(); } if (!set_offset) { - setDescriptionFromInput(object, offset); - object.setParsedOffset(offset); + setDescription(object, offset, offset); } return object; } void -QPDFParser::setDescriptionFromInput( - QPDFObjectHandle oh, qpdf_offset_t offset) const +QPDFParser::setDescription( + QPDFObjectHandle oh, + qpdf_offset_t descr_offset, + qpdf_offset_t parsed_offset) const { - oh.setObjectDescription( - context, - (input->getName() + ", " + object_description + " at offset " + - std::to_string(offset))); + if (auto& obj = oh.obj) { + obj->setDescription( + context, + (input->getName() + ", " + object_description + " at offset " + + std::to_string(descr_offset)), + parsed_offset); + } } void diff --git a/libqpdf/QPDF_Stream.cc b/libqpdf/QPDF_Stream.cc index 480bb6e9..7ff7a1b8 100644 --- a/libqpdf/QPDF_Stream.cc +++ b/libqpdf/QPDF_Stream.cc @@ -124,8 +124,9 @@ QPDF_Stream::QPDF_Stream( "object for dictionary"); } setDescription( - qpdf, qpdf->getFilename() + ", stream object " + og.unparse(' ')); - this->parsed_offset = offset; + qpdf, + qpdf->getFilename() + ", stream object " + og.unparse(' '), + offset); } std::shared_ptr @@ -282,9 +283,10 @@ QPDF_Stream::getStreamJSON( } void -QPDF_Stream::setDescription(QPDF* qpdf, std::string const& description) +QPDF_Stream::setDescription( + QPDF* qpdf, std::string const& description, qpdf_offset_t offset) { - this->QPDFValue::setDescription(qpdf, description); + this->QPDFValue::setDescription(qpdf, description, offset); setDictDescription(); } diff --git a/libqpdf/qpdf/QPDFObject_private.hh b/libqpdf/qpdf/QPDFObject_private.hh index 447743fc..2efda859 100644 --- a/libqpdf/qpdf/QPDFObject_private.hh +++ b/libqpdf/qpdf/QPDFObject_private.hh @@ -70,9 +70,10 @@ class QPDFObject } void - setDescription(QPDF* qpdf, std::string const& description) + setDescription( + QPDF* qpdf, std::string const& description, qpdf_offset_t offset = -1) { - return value->setDescription(qpdf, description); + return value->setDescription(qpdf, description, offset); } bool getDescription(QPDF*& qpdf, std::string& description) diff --git a/libqpdf/qpdf/QPDFParser.hh b/libqpdf/qpdf/QPDFParser.hh index b83dbb1c..45d36695 100644 --- a/libqpdf/qpdf/QPDFParser.hh +++ b/libqpdf/qpdf/QPDFParser.hh @@ -40,9 +40,11 @@ class QPDFParser void warn(qpdf_offset_t offset, std::string const& msg) const; void warn(std::string const& msg) const; static void warn(QPDF*, QPDFExc const&); - void setParsedOffset(qpdf_offset_t offset); - void - setDescriptionFromInput(QPDFObjectHandle oh, qpdf_offset_t offset) const; + + void setDescription( + QPDFObjectHandle oh, + qpdf_offset_t descr_offset, + qpdf_offset_t parsed_offset = -1) const; std::shared_ptr input; std::string const& object_description; QPDFTokenizer& tokenizer; diff --git a/libqpdf/qpdf/QPDFValue.hh b/libqpdf/qpdf/QPDFValue.hh index da80e37f..9a0e8cba 100644 --- a/libqpdf/qpdf/QPDFValue.hh +++ b/libqpdf/qpdf/QPDFValue.hh @@ -24,10 +24,12 @@ class QPDFValue virtual std::string unparse() = 0; virtual JSON getJSON(int json_version) = 0; virtual void - setDescription(QPDF* qpdf_p, std::string const& description) + setDescription( + QPDF* qpdf_p, std::string const& description, qpdf_offset_t offset) { qpdf = qpdf_p; object_description = description; + setParsedOffset(offset); } bool getDescription(QPDF*& qpdf_p, std::string& description) diff --git a/libqpdf/qpdf/QPDF_Stream.hh b/libqpdf/qpdf/QPDF_Stream.hh index 3bb9e19a..a436420a 100644 --- a/libqpdf/qpdf/QPDF_Stream.hh +++ b/libqpdf/qpdf/QPDF_Stream.hh @@ -26,7 +26,8 @@ class QPDF_Stream: public QPDFValue virtual std::shared_ptr copy(bool shallow = false); virtual std::string unparse(); virtual JSON getJSON(int json_version); - virtual void setDescription(QPDF*, std::string const&); + virtual void + setDescription(QPDF*, std::string const&, qpdf_offset_t offset); virtual void disconnect(); QPDFObjectHandle getDict() const; bool isDataModified() const;