From f40a96bdeb5d34c1bb7894445df8d981b7399dbd Mon Sep 17 00:00:00 2001 From: m-holger Date: Sat, 8 Mar 2025 13:31:12 +0000 Subject: [PATCH] Fix two BaseHandle bugs --- include/qpdf/ObjectHandle.hh | 2 ++ libqpdf/QPDFObjectHandle.cc | 6 +++--- libqpdf/qpdf/QPDFObjectHandle_private.hh | 12 ++++++++++++ qpdf/test_driver.cc | 26 ++++++++++++++++++++++++-- 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/include/qpdf/ObjectHandle.hh b/include/qpdf/ObjectHandle.hh index 78bd9f8..2b28a04 100644 --- a/include/qpdf/ObjectHandle.hh +++ b/include/qpdf/ObjectHandle.hh @@ -52,6 +52,7 @@ namespace qpdf public: explicit inline operator bool() const; inline operator QPDFObjectHandle() const; + QPDF_DLL operator QPDFObjGen() const; // The rest of the header file is for qpdf internal use only. @@ -65,6 +66,7 @@ namespace qpdf inline bool null() const; inline QPDF* qpdf() const; inline qpdf_object_type_e raw_type_code() const; + inline qpdf_object_type_e resolved_type_code() const; inline qpdf_object_type_e type_code() const; std::string unparse() const; void write_json(int json_version, JSON::Writer& p) const; diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index f4c71cd..df791f3 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -291,7 +291,7 @@ Name::normalize(std::string const& name) std::shared_ptr BaseHandle::copy(bool shallow) const { - switch (type_code()) { + switch (resolved_type_code()) { case ::ot_uninitialized: throw std::logic_error("QPDFObjectHandle: attempting to copy an uninitialized object"); return {}; // does not return @@ -371,7 +371,7 @@ BaseHandle::copy(bool shallow) const std::string BaseHandle::unparse() const { - switch (type_code()) { + switch (resolved_type_code()) { case ::ot_uninitialized: throw std::logic_error("QPDFObjectHandle: attempting to unparse an uninitialized object"); return ""; // does not return @@ -448,7 +448,7 @@ BaseHandle::unparse() const void BaseHandle::write_json(int json_version, JSON::Writer& p) const { - switch (type_code()) { + switch (resolved_type_code()) { case ::ot_uninitialized: throw std::logic_error( "QPDFObjectHandle: attempting to get JSON from a uninitialized object"); diff --git a/libqpdf/qpdf/QPDFObjectHandle_private.hh b/libqpdf/qpdf/QPDFObjectHandle_private.hh index b940251..009f43b 100644 --- a/libqpdf/qpdf/QPDFObjectHandle_private.hh +++ b/libqpdf/qpdf/QPDFObjectHandle_private.hh @@ -374,6 +374,18 @@ namespace qpdf } inline qpdf_object_type_e + BaseHandle::resolved_type_code() const + { + if (!obj) { + return ::ot_uninitialized; + } + if (raw_type_code() == ::ot_unresolved) { + return QPDF::Resolver::resolved(obj->qpdf, obj->og)->getTypeCode(); + } + return raw_type_code(); + } + + inline qpdf_object_type_e BaseHandle::type_code() const { if (!obj) { diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc index 64ba1ef..843d576 100644 --- a/qpdf/test_driver.cc +++ b/qpdf/test_driver.cc @@ -1403,8 +1403,7 @@ test_41(QPDF& pdf, char const* arg2) static void test_42(QPDF& pdf, char const* arg2) { - // Access objects as wrong type. This test case is crafted to - // work with object-types.pdf. + // Access objects as wrong type. This test case is crafted to work with object-types.pdf. QPDFObjectHandle qtest = pdf.getTrailer().getKey("/QTest"); QPDFObjectHandle array = qtest.getKey("/Dictionary").getKey("/Key2"); QPDFObjectHandle dictionary = qtest.getKey("/Dictionary"); @@ -1537,12 +1536,35 @@ test_42(QPDF& pdf, char const* arg2) assert(!"42"_qpdf.isMatrix()); m1 = "42"_qpdf.getArrayAsMatrix(); assert(m1.a == 0 && m1.b == 0 && m1.c == 0 && m1.d == 0 && m1.e == 0 && m1.f == 0); + // Uninitialized QPDFObjectHandle uninitialized; assert(!uninitialized); assert(!uninitialized.isInteger()); assert(!uninitialized.isDictionary()); assert(!uninitialized.isScalar()); + + // Reference + auto indirect = pdf.newIndirectNull(); + QPDFObjGen indirect_og{indirect.getObjGen()}; + pdf.replaceObject(indirect, array); + assert(array.isIndirect()); + assert(indirect.isArray()); + assert(array.getObjGen() == indirect_og); + assert(array.isArray()); + assert(indirect.isArray()); + assert(indirect.unparse() == indirect_og.unparse(' ') + " R"); + + auto pl1 = Pl_Buffer(""); + array.writeJSON(2, &pl1, true); + pl1.finish(); + assert(pl1.getString() == std::string("\"" + indirect_og.unparse(' ') + " R\"")); + + array.setArrayItem(1, "42"_qpdf); + assert(indirect.getArrayItem(1).getIntValue() == 42); + + pdf.replaceObject(indirect, "42"_qpdf); + assert(array.isInteger()); } static void -- libgit2 0.21.4