From d58ec90310c93653ab42bcb7373a38e3f8d43362 Mon Sep 17 00:00:00 2001 From: m-holger Date: Wed, 15 Feb 2023 10:35:10 +0000 Subject: Un-inline QPDFValue::getDescription --- libqpdf/QPDFValue.cc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'libqpdf/QPDFValue.cc') diff --git a/libqpdf/QPDFValue.cc b/libqpdf/QPDFValue.cc index ca3205b7..19679df2 100644 --- a/libqpdf/QPDFValue.cc +++ b/libqpdf/QPDFValue.cc @@ -9,3 +9,20 @@ QPDFValue::do_create(QPDFValue* object) obj->value = std::shared_ptr(object); return obj; } + +std::string +QPDFValue::getDescription() +{ + auto description = object_description ? *object_description : ""; + if (auto pos = description.find("$OG"); pos != std::string::npos) { + description.replace(pos, 3, og.unparse(' ')); + } + if (auto pos = description.find("$PO"); pos != std::string::npos) { + qpdf_offset_t shift = (type_code == ::ot_dictionary) ? 2 + : (type_code == ::ot_array) ? 1 + : 0; + + description.replace(pos, 3, std::to_string(parsed_offset + shift)); + } + return description; +} -- cgit v1.2.3-70-g09d2 From 32907fc14c663e95df0f7c62905b82389c0024a2 Mon Sep 17 00:00:00 2001 From: m-holger Date: Wed, 15 Feb 2023 10:11:38 +0000 Subject: Change type of QPDFValue::object_description to std::shared_ptr Also, name the type QPDFValue::Description. --- libqpdf/QPDFObjectHandle.cc | 3 ++- libqpdf/QPDFValue.cc | 32 ++++++++++++++++++++++---------- libqpdf/QPDF_Stream.cc | 6 ++++-- libqpdf/qpdf/QPDFObject_private.hh | 2 +- libqpdf/qpdf/QPDFParser.hh | 7 ++++--- libqpdf/qpdf/QPDFValue.hh | 12 ++++++++---- libqpdf/qpdf/QPDF_Stream.hh | 4 +++- 7 files changed, 44 insertions(+), 22 deletions(-) (limited to 'libqpdf/QPDFValue.cc') diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index 2b2ca5db..7a37ffc2 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -2176,7 +2176,8 @@ QPDFObjectHandle::setObjectDescription( // This is called during parsing on newly created direct objects, // so we can't call dereference() here. if (isInitialized() && obj.get()) { - auto descr = std::make_shared(object_description); + auto descr = + std::make_shared(object_description); obj->setDescription(owning_qpdf, descr); } } diff --git a/libqpdf/QPDFValue.cc b/libqpdf/QPDFValue.cc index 19679df2..7c5b30a6 100644 --- a/libqpdf/QPDFValue.cc +++ b/libqpdf/QPDFValue.cc @@ -13,16 +13,28 @@ QPDFValue::do_create(QPDFValue* object) std::string QPDFValue::getDescription() { - auto description = object_description ? *object_description : ""; - if (auto pos = description.find("$OG"); pos != std::string::npos) { - description.replace(pos, 3, og.unparse(' ')); - } - if (auto pos = description.find("$PO"); pos != std::string::npos) { - qpdf_offset_t shift = (type_code == ::ot_dictionary) ? 2 - : (type_code == ::ot_array) ? 1 - : 0; + if (object_description) { + switch (object_description->index()) { + case 0: + { + auto description = std::get<0>(*object_description); + + if (auto pos = description.find("$OG"); + pos != std::string::npos) { + description.replace(pos, 3, og.unparse(' ')); + } + if (auto pos = description.find("$PO"); + pos != std::string::npos) { + qpdf_offset_t shift = (type_code == ::ot_dictionary) ? 2 + : (type_code == ::ot_array) ? 1 + : 0; - description.replace(pos, 3, std::to_string(parsed_offset + shift)); + description.replace( + pos, 3, std::to_string(parsed_offset + shift)); + } + return description; + } + } } - return description; + return {}; } diff --git a/libqpdf/QPDF_Stream.cc b/libqpdf/QPDF_Stream.cc index 66916c21..8e2e16c5 100644 --- a/libqpdf/QPDF_Stream.cc +++ b/libqpdf/QPDF_Stream.cc @@ -123,7 +123,7 @@ QPDF_Stream::QPDF_Stream( throw std::logic_error("stream object instantiated with non-dictionary " "object for dictionary"); } - auto descr = std::make_shared( + auto descr = std::make_shared( qpdf->getFilename() + ", stream object " + og.unparse(' ')); setDescription(qpdf, descr, offset); } @@ -283,7 +283,9 @@ QPDF_Stream::getStreamJSON( void QPDF_Stream::setDescription( - QPDF* qpdf, std::shared_ptr& description, qpdf_offset_t offset) + QPDF* qpdf, + std::shared_ptr& description, + qpdf_offset_t offset) { this->QPDFValue::setDescription(qpdf, description, offset); setDictDescription(); diff --git a/libqpdf/qpdf/QPDFObject_private.hh b/libqpdf/qpdf/QPDFObject_private.hh index 4d388503..612949da 100644 --- a/libqpdf/qpdf/QPDFObject_private.hh +++ b/libqpdf/qpdf/QPDFObject_private.hh @@ -71,7 +71,7 @@ class QPDFObject void setDescription( QPDF* qpdf, - std::shared_ptr& description, + std::shared_ptr& description, qpdf_offset_t offset = -1) { return value->setDescription(qpdf, description, offset); diff --git a/libqpdf/qpdf/QPDFParser.hh b/libqpdf/qpdf/QPDFParser.hh index 65279700..c2bf6bbe 100644 --- a/libqpdf/qpdf/QPDFParser.hh +++ b/libqpdf/qpdf/QPDFParser.hh @@ -2,6 +2,7 @@ #define QPDFPARSER_HH #include +#include #include #include @@ -21,8 +22,8 @@ class QPDFParser tokenizer(tokenizer), decrypter(decrypter), context(context), - description(std::make_shared( - input->getName() + ", " + object_description + " at offset $PO")) + description(std::make_shared(std::string( + input->getName() + ", " + object_description + " at offset $PO"))) { } virtual ~QPDFParser() = default; @@ -49,7 +50,7 @@ class QPDFParser QPDFTokenizer& tokenizer; QPDFObjectHandle::StringDecrypter* decrypter; QPDF* context; - std::shared_ptr description; + std::shared_ptr description; }; #endif // QPDFPARSER_HH diff --git a/libqpdf/qpdf/QPDFValue.hh b/libqpdf/qpdf/QPDFValue.hh index b9c3cdb1..eef088f9 100644 --- a/libqpdf/qpdf/QPDFValue.hh +++ b/libqpdf/qpdf/QPDFValue.hh @@ -8,6 +8,7 @@ #include #include +#include class QPDF; class QPDFObjectHandle; @@ -23,10 +24,13 @@ class QPDFValue virtual std::shared_ptr copy(bool shallow = false) = 0; virtual std::string unparse() = 0; virtual JSON getJSON(int json_version) = 0; + + using Description = std::variant; + virtual void setDescription( QPDF* qpdf_p, - std::shared_ptr& description, + std::shared_ptr& description, qpdf_offset_t offset) { qpdf = qpdf_p; @@ -37,7 +41,7 @@ class QPDFValue setDefaultDescription(QPDF* a_qpdf, QPDFObjGen const& a_og) { static auto default_description{ - std::make_shared("object $OG")}; + std::make_shared("object $OG")}; if (!object_description) { object_description = default_description; } @@ -49,7 +53,7 @@ class QPDFValue hasDescription() { return qpdf != nullptr && object_description && - !object_description->empty(); + !getDescription().empty(); } void setParsedOffset(qpdf_offset_t offset) @@ -108,7 +112,7 @@ class QPDFValue private: QPDFValue(QPDFValue const&) = delete; QPDFValue& operator=(QPDFValue const&) = delete; - std::shared_ptr object_description; + std::shared_ptr object_description; const qpdf_object_type_e type_code{::ot_uninitialized}; char const* type_name{"uninitialized"}; diff --git a/libqpdf/qpdf/QPDF_Stream.hh b/libqpdf/qpdf/QPDF_Stream.hh index c0694c60..cf0a2288 100644 --- a/libqpdf/qpdf/QPDF_Stream.hh +++ b/libqpdf/qpdf/QPDF_Stream.hh @@ -27,7 +27,9 @@ class QPDF_Stream: public QPDFValue virtual std::string unparse(); virtual JSON getJSON(int json_version); virtual void setDescription( - QPDF*, std::shared_ptr& description, qpdf_offset_t offset); + QPDF*, + std::shared_ptr& description, + qpdf_offset_t offset); virtual void disconnect(); QPDFObjectHandle getDict() const; bool isDataModified() const; -- cgit v1.2.3-70-g09d2 From fe74f28dc4f269e4bf944ae61d77874f81f95daf Mon Sep 17 00:00:00 2001 From: m-holger Date: Wed, 15 Feb 2023 11:30:33 +0000 Subject: Refactor QPDFValue::setDefaultDescription --- libqpdf/QPDFValue.cc | 2 ++ libqpdf/qpdf/QPDFValue.hh | 7 +------ 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'libqpdf/QPDFValue.cc') diff --git a/libqpdf/QPDFValue.cc b/libqpdf/QPDFValue.cc index 7c5b30a6..41a00fa8 100644 --- a/libqpdf/QPDFValue.cc +++ b/libqpdf/QPDFValue.cc @@ -35,6 +35,8 @@ QPDFValue::getDescription() return description; } } + } else if (og.isIndirect()) { + return "object " + og.unparse(' '); } return {}; } diff --git a/libqpdf/qpdf/QPDFValue.hh b/libqpdf/qpdf/QPDFValue.hh index e7904253..8e9d4ea5 100644 --- a/libqpdf/qpdf/QPDFValue.hh +++ b/libqpdf/qpdf/QPDFValue.hh @@ -40,11 +40,6 @@ class QPDFValue void setDefaultDescription(QPDF* a_qpdf, QPDFObjGen const& a_og) { - static auto default_description{ - std::make_shared("object $OG")}; - if (!object_description) { - object_description = default_description; - } qpdf = a_qpdf; og = a_og; } @@ -52,7 +47,7 @@ class QPDFValue bool hasDescription() { - return object_description != nullptr; + return object_description || og.isIndirect(); } void setParsedOffset(qpdf_offset_t offset) -- cgit v1.2.3-70-g09d2 From dab27c9bb35c26e30e22f2e53299ee9566cadefd Mon Sep 17 00:00:00 2001 From: m-holger Date: Thu, 9 Feb 2023 12:43:56 +0000 Subject: Refactor setting of object descriptions in QPDF::JSONReactor --- include/qpdf/QPDF.hh | 3 +++ libqpdf/QPDFValue.cc | 8 ++++++++ libqpdf/QPDF_json.cc | 15 ++++++++++----- libqpdf/qpdf/QPDFValue.hh | 14 +++++++++++++- 4 files changed, 34 insertions(+), 6 deletions(-) (limited to 'libqpdf/QPDFValue.cc') diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh index d6b32fe9..b227bb37 100644 --- a/include/qpdf/QPDF.hh +++ b/include/qpdf/QPDF.hh @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -50,6 +51,7 @@ class BitStream; class BitWriter; class QPDFLogger; class QPDFParser; +struct JSON_Descr; class QPDF { @@ -1152,6 +1154,7 @@ class QPDF QPDF& pdf; std::shared_ptr is; bool must_be_complete; + std::shared_ptr> descr; bool errors; bool parse_error; bool saw_qpdf; diff --git a/libqpdf/QPDFValue.cc b/libqpdf/QPDFValue.cc index 41a00fa8..a89afd55 100644 --- a/libqpdf/QPDFValue.cc +++ b/libqpdf/QPDFValue.cc @@ -34,6 +34,14 @@ QPDFValue::getDescription() } return description; } + case 1: + { + auto j_descr = std::get<1>(*object_description); + return ( + *j_descr.input + + (j_descr.object.empty() ? "" : ", " + j_descr.object) + + " at offset " + std::to_string(parsed_offset)); + } } } else if (og.isIndirect()) { return "object " + og.unparse(' '); diff --git a/libqpdf/QPDF_json.cc b/libqpdf/QPDF_json.cc index 02dc57e8..fb858557 100644 --- a/libqpdf/QPDF_json.cc +++ b/libqpdf/QPDF_json.cc @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include #include #include @@ -226,6 +228,8 @@ QPDF::JSONReactor::JSONReactor( pdf(pdf), is(is), must_be_complete(must_be_complete), + descr(std::make_shared>( + JSON_Descr(std::make_shared(is->getName()), ""))), errors(false), parse_error(false), saw_qpdf(false), @@ -675,12 +679,13 @@ QPDF::JSONReactor::arrayItem(JSON const& value) void QPDF::JSONReactor::setObjectDescription(QPDFObjectHandle& oh, JSON const& value) { - std::string description = this->is->getName(); - if (!this->cur_object.empty()) { - description += ", " + this->cur_object; + auto j_descr = std::get(*descr); + if (j_descr.object != cur_object) { + descr = std::make_shared( + JSON_Descr(j_descr.input, cur_object)); } - description += " at offset " + std::to_string(value.getStart()); - oh.setObjectDescription(&this->pdf, description); + + oh.getObjectPtr()->setDescription(&pdf, descr, value.getStart()); } QPDFObjectHandle diff --git a/libqpdf/qpdf/QPDFValue.hh b/libqpdf/qpdf/QPDFValue.hh index 8e9d4ea5..2e0c5e8d 100644 --- a/libqpdf/qpdf/QPDFValue.hh +++ b/libqpdf/qpdf/QPDFValue.hh @@ -14,6 +14,18 @@ class QPDF; class QPDFObjectHandle; class QPDFObject; +struct JSON_Descr +{ + JSON_Descr(std::shared_ptr input, std::string const& object) : + input(input), + object(object) + { + } + + std::shared_ptr input; + std::string object; +}; + class QPDFValue { friend class QPDFObject; @@ -25,7 +37,7 @@ class QPDFValue virtual std::string unparse() = 0; virtual JSON getJSON(int json_version) = 0; - using Description = std::variant; + using Description = std::variant; virtual void setDescription( -- cgit v1.2.3-70-g09d2 From 1496472e1c2f64f46d2d7d76481aef1aa3fff869 Mon Sep 17 00:00:00 2001 From: m-holger Date: Fri, 17 Feb 2023 13:58:21 +0000 Subject: Add method QPDFValue::setChildDescription --- libqpdf/QPDFObjectHandle.cc | 23 ++++++++--------------- libqpdf/QPDFValue.cc | 16 ++++++++++++++++ libqpdf/QPDF_Dictionary.cc | 9 +++++---- libqpdf/qpdf/QPDFObject_private.hh | 20 ++++++++++++++++++++ libqpdf/qpdf/QPDFValue.hh | 33 +++++++++++++++++++++++++++++++-- 5 files changed, 80 insertions(+), 21 deletions(-) (limited to 'libqpdf/QPDFValue.cc') diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index 7a37ffc2..cbe42995 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -36,6 +36,8 @@ #include #include +using namespace std::literals; + namespace { class TerminateParsing @@ -813,13 +815,9 @@ QPDFObjectHandle::getArrayItem(int n) typeWarning("array", "returning null"); QTC::TC("qpdf", "QPDFObjectHandle array null for non-array"); } - QPDF* context = nullptr; - std::string description; - if (obj->getDescription(context, description)) { - result.setObjectDescription( - context, - description + " -> null returned from invalid array access"); - } + static auto constexpr msg = + " -> null returned from invalid array access"sv; + result.obj->setChildDescription(obj, msg, ""); } return result; } @@ -1038,14 +1036,9 @@ QPDFObjectHandle::getKey(std::string const& key) typeWarning("dictionary", "returning null for attempted key retrieval"); QTC::TC("qpdf", "QPDFObjectHandle dictionary null for getKey"); result = newNull(); - QPDF* qpdf = nullptr; - std::string description; - if (obj->getDescription(qpdf, description)) { - result.setObjectDescription( - qpdf, - (description + " -> null returned from getting key " + key + - " from non-Dictionary")); - } + static auto constexpr msg = + " -> null returned from getting key $VD from non-Dictionary"sv; + result.obj->setChildDescription(obj, msg, key); } return result; } diff --git a/libqpdf/QPDFValue.cc b/libqpdf/QPDFValue.cc index a89afd55..30d534dc 100644 --- a/libqpdf/QPDFValue.cc +++ b/libqpdf/QPDFValue.cc @@ -17,6 +17,7 @@ QPDFValue::getDescription() switch (object_description->index()) { case 0: { + // Simple template string auto description = std::get<0>(*object_description); if (auto pos = description.find("$OG"); @@ -36,12 +37,27 @@ QPDFValue::getDescription() } case 1: { + // QPDF::JSONReactor generated description auto j_descr = std::get<1>(*object_description); return ( *j_descr.input + (j_descr.object.empty() ? "" : ", " + j_descr.object) + " at offset " + std::to_string(parsed_offset)); } + case 2: + { + // Child object description + auto j_descr = std::get<2>(*object_description); + std::string result; + if (auto p = j_descr.parent.lock()) { + result = p->getDescription(); + } + result += j_descr.static_descr; + if (auto pos = result.find("$VD"); pos != std::string::npos) { + result.replace(pos, 3, j_descr.var_descr); + } + return result; + } } } else if (og.isIndirect()) { return "object " + og.unparse(' '); diff --git a/libqpdf/QPDF_Dictionary.cc b/libqpdf/QPDF_Dictionary.cc index 5349a2a8..f45c00c6 100644 --- a/libqpdf/QPDF_Dictionary.cc +++ b/libqpdf/QPDF_Dictionary.cc @@ -1,7 +1,10 @@ #include +#include #include +using namespace std::literals; + QPDF_Dictionary::QPDF_Dictionary( std::map const& items) : QPDFValue(::ot_dictionary, "dictionary"), @@ -98,10 +101,8 @@ QPDF_Dictionary::getKey(std::string const& key) return item->second; } else { auto null = QPDFObjectHandle::newNull(); - if (qpdf != nullptr) { - null.setObjectDescription( - qpdf, getDescription() + " -> dictionary key " + key); - } + static auto constexpr msg = " -> dictionary key $VD"sv; + null.getObj()->setChildDescription(shared_from_this(), msg, key); return null; } } diff --git a/libqpdf/qpdf/QPDFObject_private.hh b/libqpdf/qpdf/QPDFObject_private.hh index 612949da..0dc04699 100644 --- a/libqpdf/qpdf/QPDFObject_private.hh +++ b/libqpdf/qpdf/QPDFObject_private.hh @@ -12,6 +12,7 @@ #include #include +#include class QPDF; class QPDFObjectHandle; @@ -76,6 +77,25 @@ class QPDFObject { return value->setDescription(qpdf, description, offset); } + void + setChildDescription( + std::shared_ptr parent, + std::string_view const& static_descr, + std::string var_descr) + { + auto qpdf = parent ? parent->value->qpdf : nullptr; + value->setChildDescription( + qpdf, parent->value, static_descr, var_descr); + } + void + setChildDescription( + std::shared_ptr parent, + std::string_view const& static_descr, + std::string var_descr) + { + auto qpdf = parent ? parent->qpdf : nullptr; + value->setChildDescription(qpdf, parent, static_descr, var_descr); + } bool getDescription(QPDF*& qpdf, std::string& description) { diff --git a/libqpdf/qpdf/QPDFValue.hh b/libqpdf/qpdf/QPDFValue.hh index 9a1a6df1..e8a1834f 100644 --- a/libqpdf/qpdf/QPDFValue.hh +++ b/libqpdf/qpdf/QPDFValue.hh @@ -8,13 +8,14 @@ #include #include +#include #include class QPDF; class QPDFObjectHandle; class QPDFObject; -class QPDFValue +class QPDFValue: public std::enable_shared_from_this { friend class QPDFObject; @@ -38,7 +39,24 @@ class QPDFValue std::string object; }; - using Description = std::variant; + struct ChildDescr + { + ChildDescr( + std::shared_ptr parent, + std::string_view const& static_descr, + std::string var_descr) : + parent(parent), + static_descr(static_descr), + var_descr(var_descr) + { + } + + std::weak_ptr parent; + std::string_view const& static_descr; + std::string var_descr; + }; + + using Description = std::variant; virtual void setDescription( @@ -56,6 +74,17 @@ class QPDFValue qpdf = a_qpdf; og = a_og; } + void + setChildDescription( + QPDF* a_qpdf, + std::shared_ptr parent, + std::string_view const& static_descr, + std::string var_descr) + { + object_description = std::make_shared( + ChildDescr(parent, static_descr, var_descr)); + qpdf = a_qpdf; + } std::string getDescription(); bool hasDescription() -- cgit v1.2.3-70-g09d2