diff --git a/include/qpdf/ObjectHandle.hh b/include/qpdf/ObjectHandle.hh index 9cf4dc6..9d53a82 100644 --- a/include/qpdf/ObjectHandle.hh +++ b/include/qpdf/ObjectHandle.hh @@ -132,11 +132,9 @@ namespace qpdf inline void assign(qpdf_object_type_e required, BaseHandle const& other); inline void assign(qpdf_object_type_e required, BaseHandle&& other); - inline void nullify(); std::string description() const; - inline QPDFObjectHandle const& get(std::string const& key) const; void no_ci_warn_if(bool condition, std::string const& warning) const; @@ -148,6 +146,9 @@ namespace qpdf char const* type_name() const; std::shared_ptr obj; + + private: + inline QPDFObjectHandle referenced_object() const; }; } // namespace qpdf diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index 5bad81b..7ae1d17 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -322,7 +322,7 @@ BaseHandle::copy(bool shallow) const throw std::logic_error("attempted to shallow copy QPDFObjectHandle from destroyed QPDF"); return {}; // does not return case ::ot_reference: - return obj->qpdf->getObject(obj->og).obj_sp(); + return referenced_object().obj_sp(); } return {}; // unreachable } diff --git a/libqpdf/qpdf/QPDFObjectHandle_private.hh b/libqpdf/qpdf/QPDFObjectHandle_private.hh index ab54009..2687c50 100644 --- a/libqpdf/qpdf/QPDFObjectHandle_private.hh +++ b/libqpdf/qpdf/QPDFObjectHandle_private.hh @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -757,6 +758,33 @@ namespace qpdf return {obj}; } + /// @brief Retrieve the QPDFObjectHandle for the object referenced by a reference object. + /// + /// Look up and return the object from the document's object table using QPDF::getObject(). The + /// returned value is a QPDFObjectHandle that wraps the shared pointer to the underlying + /// QPDFObject held in the document's cache. + /// + /// @note We must perform the lookup because qpdf represents certain replacements using + /// QPDF_Reference. In particular, `QPDF::makeIndirectObject` used to make the input + /// object indirect and then return the original input object. To replicate that + /// existing behavior the implementation now makes the input object indirect and + /// returns it, while modifying the input object to become a reference to the + /// newly-created indirect object. Looking up the resulting indirect object in the + /// document's object table via `QPDF::getObject()` ensures callers receive the + /// cached object and avoids surprises if the indirect object is subsequently + /// replaced. + /// + /// @return The QPDFObjectHandle for the object referenced by a reference object. + /// + /// @since 12.3.3 + inline QPDFObjectHandle + BaseHandle::referenced_object() const + { + qpdf_expect(resolved_type_code() == ::ot_reserved); + qpdf_expect(obj->qpdf); + return obj->qpdf->getObject(obj->og); + } + inline void BaseHandle::assign(qpdf_object_type_e required, BaseHandle const& other) {