From 9b0801721710093102c64068b6c643c8fcd7f5db Mon Sep 17 00:00:00 2001 From: m-holger Date: Thu, 5 Jan 2023 11:09:44 +0000 Subject: Add new convenience class QPDFObjGen::set --- include/qpdf/QPDFObjGen.hh | 69 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/qpdf/QPDFObjGen.hh b/include/qpdf/QPDFObjGen.hh index ccab4ba2..0d14efaf 100644 --- a/include/qpdf/QPDFObjGen.hh +++ b/include/qpdf/QPDFObjGen.hh @@ -24,6 +24,10 @@ #include #include +#include + +class QPDFObjectHandle; +class QPDFObjectHelper; // This class represents an object ID and generation pair. It is // suitable to use as a key in a map or set. @@ -31,6 +35,7 @@ class QPDFObjGen { public: + // ABI: change to default. QPDF_DLL QPDFObjGen() : obj(0), @@ -84,12 +89,72 @@ class QPDFObjGen QPDF_DLL friend std::ostream& operator<<(std::ostream& os, const QPDFObjGen& og); + // Convenience class for loop detection when processing objects. + // + // The class adds 'add' methods to a std::set which allows + // to test whether an QPDFObjGen is present in the set and to insert it in + // a single operation. The 'add' method is overloaded to take a QPDFObjGen, + // QPDFObjectHandle or an QPDFObjectHelper as parameter. + // + // The erase method is modified to ignore requests to erase + // QPDFObjGen(0, 0). + // + // Usage example: + // + // void process_object(QPDFObjectHandle oh, QPDFObjGen::Tracker& seen) + // { + // if (seen.add(oh)) { + // // handle first encounter of oh + // } else { + // // handle loop / subsequent encounter of oh + // } + // } + class QPDF_DLL_CLASS set: public std::set + { + public: + // Add 'og' to the set. Return false if 'og' is already present in + // the set. Attempts to insert QPDFObjGen(0, 0) are ignored. + QPDF_DLL + bool + add(QPDFObjGen og) + { + if (og.isIndirect()) { + if (count(og) > 0) { + return false; + } + emplace(og); + } + return true; + } + + QPDF_DLL + bool add(QPDFObjectHandle const& oh); + + QPDF_DLL + bool add(QPDFObjectHelper const& oh); + + QPDF_DLL + void + erase(QPDFObjGen og) + { + if (og.isIndirect()) { + std::set::erase(og); + } + } + + QPDF_DLL + void erase(QPDFObjectHandle const& oh); + + QPDF_DLL + void erase(QPDFObjectHelper const& oh); + }; + private: // This class does not use the Members pattern to avoid a memory // allocation for every one of these. A lot of these get created // and destroyed. - int obj; - int gen; + int obj{0}; + int gen{0}; }; #endif // QPDFOBJGEN_HH -- cgit v1.2.3-70-g09d2 From 55abecc42dc44d1b93337afe9628fea029a85696 Mon Sep 17 00:00:00 2001 From: m-holger Date: Thu, 5 Jan 2023 12:20:37 +0000 Subject: Use QPDFObjGen::set in QPDFOutlineDocumentHelper --- include/qpdf/QPDFOutlineDocumentHelper.hh | 10 +++++----- libqpdf/QPDFOutlineDocumentHelper.cc | 19 ++----------------- 2 files changed, 7 insertions(+), 22 deletions(-) (limited to 'include') diff --git a/include/qpdf/QPDFOutlineDocumentHelper.hh b/include/qpdf/QPDFOutlineDocumentHelper.hh index cd11884d..38310302 100644 --- a/include/qpdf/QPDFOutlineDocumentHelper.hh +++ b/include/qpdf/QPDFOutlineDocumentHelper.hh @@ -22,13 +22,13 @@ #ifndef QPDFOUTLINEDOCUMENTHELPER_HH #define QPDFOUTLINEDOCUMENTHELPER_HH +#include #include #include +#include #include -#include #include -#include #include #include @@ -69,16 +69,16 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper { friend class QPDFOutlineObjectHelper; + // ABI: remove QPDF_DLL and pass og by value. QPDF_DLL static bool checkSeen(QPDFOutlineDocumentHelper& dh, QPDFObjGen const& og) { - return dh.checkSeen(og); + return !dh.m->seen.add(og); } }; private: - bool checkSeen(QPDFObjGen const& og); void initializeByPage(); class Members @@ -94,7 +94,7 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper Members(Members const&) = delete; std::vector outlines; - std::set seen; + QPDFObjGen::set seen; QPDFObjectHandle dest_dict; std::shared_ptr names_dest; std::map> by_page; diff --git a/libqpdf/QPDFOutlineDocumentHelper.cc b/libqpdf/QPDFOutlineDocumentHelper.cc index 5b2f71f6..e3485bfd 100644 --- a/libqpdf/QPDFOutlineDocumentHelper.cc +++ b/libqpdf/QPDFOutlineDocumentHelper.cc @@ -15,13 +15,8 @@ QPDFOutlineDocumentHelper::QPDFOutlineDocumentHelper(QPDF& qpdf) : return; } QPDFObjectHandle cur = outlines.getKey("/First"); - std::set seen; - while (!cur.isNull()) { - auto og = cur.getObjGen(); - if (seen.count(og)) { - break; - } - seen.insert(og); + QPDFObjGen::set seen; + while (!cur.isNull() && seen.add(cur)) { this->m->outlines.push_back( QPDFOutlineObjectHelper::Accessor::create(cur, *this, 1)); cur = cur.getKey("/Next"); @@ -104,13 +99,3 @@ QPDFOutlineDocumentHelper::resolveNamedDest(QPDFObjectHandle name) } return result; } - -bool -QPDFOutlineDocumentHelper::checkSeen(QPDFObjGen const& og) -{ - if (this->m->seen.count(og) > 0) { - return true; - } - this->m->seen.insert(og); - return false; -} -- cgit v1.2.3-70-g09d2 From c12a6d06fcd7990ff42fa6285185a4692c209ec5 Mon Sep 17 00:00:00 2001 From: m-holger Date: Thu, 5 Jan 2023 13:10:27 +0000 Subject: Use QPDFObjGen::set in QPDFAcroFormDocumentHelper::traverseField --- include/qpdf/QPDFAcroFormDocumentHelper.hh | 2 +- libqpdf/QPDFAcroFormDocumentHelper.cc | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/qpdf/QPDFAcroFormDocumentHelper.hh b/include/qpdf/QPDFAcroFormDocumentHelper.hh index 4539b52d..d1ac6253 100644 --- a/include/qpdf/QPDFAcroFormDocumentHelper.hh +++ b/include/qpdf/QPDFAcroFormDocumentHelper.hh @@ -254,7 +254,7 @@ class QPDFAcroFormDocumentHelper: public QPDFDocumentHelper QPDFObjectHandle field, QPDFObjectHandle parent, int depth, - std::set& visited); + QPDFObjGen::set& visited); QPDFObjectHandle getOrCreateAcroForm(); void adjustInheritedFields( QPDFObjectHandle obj, diff --git a/libqpdf/QPDFAcroFormDocumentHelper.cc b/libqpdf/QPDFAcroFormDocumentHelper.cc index 8c2c5e56..c44f7838 100644 --- a/libqpdf/QPDFAcroFormDocumentHelper.cc +++ b/libqpdf/QPDFAcroFormDocumentHelper.cc @@ -57,7 +57,7 @@ QPDFAcroFormDocumentHelper::addFormField(QPDFFormFieldObjectHelper ff) "/Fields", QPDFObjectHandle::newArray()); } fields.appendItem(ff.getObjectHandle()); - std::set visited; + QPDFObjGen::set visited; traverseField( ff.getObjectHandle(), QPDFObjectHandle::newNull(), 0, visited); } @@ -167,7 +167,7 @@ QPDFAcroFormDocumentHelper::setFormFieldName( QPDFFormFieldObjectHelper ff, std::string const& name) { ff.setFieldAttribute("/T", name); - std::set visited; + QPDFObjGen::set visited; auto ff_oh = ff.getObjectHandle(); traverseField(ff_oh, ff_oh.getKey("/Parent"), 0, visited); } @@ -273,7 +273,7 @@ QPDFAcroFormDocumentHelper::analyze() // Traverse /AcroForm to find annotations and map them // bidirectionally to fields. - std::set visited; + QPDFObjGen::set visited; int nfields = fields.getArrayNItems(); QPDFObjectHandle null(QPDFObjectHandle::newNull()); for (int i = 0; i < nfields; ++i) { @@ -319,7 +319,7 @@ QPDFAcroFormDocumentHelper::traverseField( QPDFObjectHandle field, QPDFObjectHandle parent, int depth, - std::set& visited) + QPDFObjGen::set& visited) { if (depth > 100) { // Arbitrarily cut off recursion at a fixed depth to avoid @@ -341,12 +341,11 @@ QPDFAcroFormDocumentHelper::traverseField( return; } QPDFObjGen og(field.getObjGen()); - if (visited.count(og) != 0) { + if (!visited.add(og)) { QTC::TC("qpdf", "QPDFAcroFormDocumentHelper loop"); field.warnIfPossible("loop detected while traversing /AcroForm"); return; } - visited.insert(og); // A dictionary encountered while traversing the /AcroForm field // may be a form field, an annotation, or the merger of the two. A -- cgit v1.2.3-70-g09d2 From 8335b2833b22418742e85eaa77c4269447afac63 Mon Sep 17 00:00:00 2001 From: m-holger Date: Thu, 5 Jan 2023 15:29:38 +0000 Subject: Use QPDFObjGen::set in QPDFObjectHandle --- include/qpdf/QPDFObjectHandle.hh | 2 +- libqpdf/QPDFObjectHandle.cc | 41 ++++++++++++---------------------------- 2 files changed, 13 insertions(+), 30 deletions(-) (limited to 'include') diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh index ee424e39..0ab68734 100644 --- a/include/qpdf/QPDFObjectHandle.hh +++ b/include/qpdf/QPDFObjectHandle.hh @@ -1611,7 +1611,7 @@ class QPDFObjectHandle void objectWarning(std::string const& warning); void assertType(char const* type_name, bool istype); inline bool dereference(); - void makeDirect(std::set& visited, bool stop_at_streams); + void makeDirect(QPDFObjGen::set& visited, bool stop_at_streams); void disconnect(); void setParsedOffset(qpdf_offset_t offset); void parseContentStream_internal( diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index b3f208a5..7ae78c8b 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -1588,22 +1588,12 @@ QPDFObjectHandle::rotatePage(int angle, bool relative) int new_angle = angle; if (relative) { int old_angle = 0; - bool found_rotate = false; QPDFObjectHandle cur_obj = *this; - bool searched_parent = false; - std::set visited; - while (!found_rotate) { - if (visited.count(cur_obj.getObjGen())) { - // Don't get stuck in an infinite loop + QPDFObjGen::set visited; + while (visited.add(cur_obj)) { + // Don't get stuck in an infinite loop + if (cur_obj.getKey("/Rotate").getValueAsInt(old_angle)) { break; - } - if (!visited.empty()) { - searched_parent = true; - } - visited.insert(cur_obj.getObjGen()); - if (cur_obj.getKey("/Rotate").isInteger()) { - found_rotate = true; - old_angle = cur_obj.getKey("/Rotate").getIntValueAsInt(); } else if (cur_obj.getKey("/Parent").isDictionary()) { cur_obj = cur_obj.getKey("/Parent"); } else { @@ -1613,7 +1603,7 @@ QPDFObjectHandle::rotatePage(int angle, bool relative) QTC::TC( "qpdf", "QPDFObjectHandle found old angle", - searched_parent ? 0 : 1); + visited.size() > 1 ? 0 : 1); if ((old_angle % 90) != 0) { old_angle = 0; } @@ -2181,20 +2171,15 @@ QPDFObjectHandle::unsafeShallowCopy() } void -QPDFObjectHandle::makeDirect( - std::set& visited, bool stop_at_streams) +QPDFObjectHandle::makeDirect(QPDFObjGen::set& visited, bool stop_at_streams) { assertInitialized(); auto cur_og = getObjGen(); - if (cur_og.getObj() != 0) { - if (visited.count(cur_og)) { - QTC::TC("qpdf", "QPDFObjectHandle makeDirect loop"); - throw std::runtime_error( - "loop detected while converting object from " - "indirect to direct"); - } - visited.insert(cur_og); + if (!visited.add(cur_og)) { + QTC::TC("qpdf", "QPDFObjectHandle makeDirect loop"); + throw std::runtime_error("loop detected while converting object from " + "indirect to direct"); } if (isBool() || isInteger() || isName() || isNull() || isReal() || @@ -2232,9 +2217,7 @@ QPDFObjectHandle::makeDirect( "unknown object type"); } - if (cur_og.getObj()) { - visited.erase(cur_og); - } + visited.erase(cur_og); } QPDFObjectHandle @@ -2258,7 +2241,7 @@ QPDFObjectHandle::copyStream() void QPDFObjectHandle::makeDirect(bool allow_streams) { - std::set visited; + QPDFObjGen::set visited; makeDirect(visited, allow_streams); } -- cgit v1.2.3-70-g09d2 From 5473c0956cdfbe2a72c048b19d9d5334e23007bf Mon Sep 17 00:00:00 2001 From: m-holger Date: Fri, 19 May 2023 11:12:49 +0100 Subject: Use QPDFObjGen::set in QPDF::replaceForeignIndirectObjects --- include/qpdf/QPDF.hh | 2 +- libqpdf/QPDF.cc | 54 ++++++++++++++++++++++------------------------------ 2 files changed, 24 insertions(+), 32 deletions(-) (limited to 'include') diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh index 4541db64..6a4af01f 100644 --- a/include/qpdf/QPDF.hh +++ b/include/qpdf/QPDF.hh @@ -1017,7 +1017,7 @@ class QPDF public: std::map object_map; std::vector to_copy; - std::set visiting; + QPDFObjGen::set visiting; }; class EncryptionParameters diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index c6720dd9..20028dcb 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -2176,7 +2176,8 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign) void QPDF::reserveObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top) { - if (foreign.isReserved()) { + auto foreign_tc = foreign.getTypeCode(); + if (foreign_tc == ::ot_reserved) { throw std::logic_error( "QPDF: attempting to copy a foreign reserved object"); } @@ -2193,70 +2194,62 @@ QPDF::reserveObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top) if (foreign.isIndirect()) { QPDFObjGen foreign_og(foreign.getObjGen()); - if (obj_copier.visiting.find(foreign_og) != obj_copier.visiting.end()) { - QTC::TC("qpdf", "QPDF loop reserving objects"); + if (obj_copier.object_map.count(foreign_og) > 0) { + QTC::TC("qpdf", "QPDF already reserved object"); + if (obj_copier.visiting.count(foreign_og)) { + QTC::TC("qpdf", "QPDF loop reserving objects"); + } return; } - if (obj_copier.object_map.find(foreign_og) != - obj_copier.object_map.end()) { - QTC::TC("qpdf", "QPDF already reserved object"); + if (!obj_copier.visiting.add(foreign_og)) { return; } QTC::TC("qpdf", "QPDF copy indirect"); - obj_copier.visiting.insert(foreign_og); - auto mapping = obj_copier.object_map.find(foreign_og); - if (mapping == obj_copier.object_map.end()) { + if (obj_copier.object_map.count(foreign_og) == 0) { obj_copier.to_copy.push_back(foreign); - QPDFObjectHandle reservation; - if (foreign.isStream()) { - reservation = newStream(); - } else { - reservation = QPDFObjectHandle::newReserved(this); - } - obj_copier.object_map[foreign_og] = reservation; + obj_copier.object_map[foreign_og] = foreign.isStream() + ? newStream() + : QPDFObjectHandle::newReserved(this); } } - if (foreign.isArray()) { + if (foreign_tc == ::ot_array) { QTC::TC("qpdf", "QPDF reserve array"); int n = foreign.getArrayNItems(); for (int i = 0; i < n; ++i) { reserveObjects(foreign.getArrayItem(i), obj_copier, false); } - } else if (foreign.isDictionary()) { + } else if (foreign_tc == ::ot_dictionary) { QTC::TC("qpdf", "QPDF reserve dictionary"); for (auto const& key: foreign.getKeys()) { reserveObjects(foreign.getKey(key), obj_copier, false); } - } else if (foreign.isStream()) { + } else if (foreign_tc == ::ot_stream) { QTC::TC("qpdf", "QPDF reserve stream"); reserveObjects(foreign.getDict(), obj_copier, false); } - if (foreign.isIndirect()) { - QPDFObjGen foreign_og(foreign.getObjGen()); - obj_copier.visiting.erase(foreign_og); - } + obj_copier.visiting.erase(foreign); } QPDFObjectHandle QPDF::replaceForeignIndirectObjects( QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top) { + auto foreign_tc = foreign.getTypeCode(); QPDFObjectHandle result; if ((!top) && foreign.isIndirect()) { QTC::TC("qpdf", "QPDF replace indirect"); - QPDFObjGen foreign_og(foreign.getObjGen()); - auto mapping = obj_copier.object_map.find(foreign_og); + auto mapping = obj_copier.object_map.find(foreign.getObjGen()); if (mapping == obj_copier.object_map.end()) { // This case would occur if this is a reference to a Page // or Pages object that we didn't traverse into. QTC::TC("qpdf", "QPDF replace foreign indirect with null"); result = QPDFObjectHandle::newNull(); } else { - result = obj_copier.object_map[foreign_og]; + result = mapping->second; } - } else if (foreign.isArray()) { + } else if (foreign_tc == ::ot_array) { QTC::TC("qpdf", "QPDF replace array"); result = QPDFObjectHandle::newArray(); int n = foreign.getArrayNItems(); @@ -2266,7 +2259,7 @@ QPDF::replaceForeignIndirectObjects( replaceForeignIndirectObjects( foreign.getArrayItem(i), obj_copier, false)); } - } else if (foreign.isDictionary()) { + } else if (foreign_tc == ::ot_dictionary) { QTC::TC("qpdf", "QPDF replace dictionary"); result = QPDFObjectHandle::newDictionary(); std::set keys = foreign.getKeys(); @@ -2276,10 +2269,9 @@ QPDF::replaceForeignIndirectObjects( replaceForeignIndirectObjects( foreign.getKey(iter), obj_copier, false)); } - } else if (foreign.isStream()) { + } else if (foreign_tc == ::ot_stream) { QTC::TC("qpdf", "QPDF replace stream"); - QPDFObjGen foreign_og(foreign.getObjGen()); - result = obj_copier.object_map[foreign_og]; + result = obj_copier.object_map[foreign.getObjGen()]; result.assertStream(); QPDFObjectHandle dict = result.getDict(); QPDFObjectHandle old_dict = foreign.getDict(); -- cgit v1.2.3-70-g09d2 From 8fbef47093e93cfdaffd62449a18b57679b610f5 Mon Sep 17 00:00:00 2001 From: m-holger Date: Thu, 18 May 2023 17:57:47 +0100 Subject: Use QPDFObjGen::set in QPDF::getAllPages --- include/qpdf/QPDF.hh | 4 ++-- libqpdf/QPDF_pages.cc | 19 +++++++------------ 2 files changed, 9 insertions(+), 14 deletions(-) (limited to 'include') diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh index 6a4af01f..88dadcdb 100644 --- a/include/qpdf/QPDF.hh +++ b/include/qpdf/QPDF.hh @@ -1252,8 +1252,8 @@ class QPDF void getAllPagesInternal( QPDFObjectHandle cur_pages, - std::set& visited, - std::set& seen); + QPDFObjGen::set& visited, + QPDFObjGen::set& seen); void insertPage(QPDFObjectHandle newpage, int pos); void flattenPagesTree(); void insertPageobjToPage( diff --git a/libqpdf/QPDF_pages.cc b/libqpdf/QPDF_pages.cc index b73e48e1..0791980f 100644 --- a/libqpdf/QPDF_pages.cc +++ b/libqpdf/QPDF_pages.cc @@ -55,13 +55,13 @@ QPDF::getAllPages() // initialize this->m->all_pages. if (this->m->all_pages.empty()) { this->m->ever_called_get_all_pages = true; - std::set visited; - std::set seen; + QPDFObjGen::set visited; + QPDFObjGen::set seen; QPDFObjectHandle pages = getRoot().getKey("/Pages"); bool warned = false; bool changed_pages = false; while (pages.isDictionary() && pages.hasKey("/Parent")) { - if (seen.count(pages.getObjGen())) { + if (!seen.add(pages)) { // loop -- will be detected again and reported later break; } @@ -74,7 +74,6 @@ QPDF::getAllPages() " to the root of the page tree; attempting to correct"); warned = true; } - seen.insert(pages.getObjGen()); changed_pages = true; pages = pages.getKey("/Parent"); } @@ -92,12 +91,9 @@ QPDF::getAllPages() void QPDF::getAllPagesInternal( - QPDFObjectHandle cur_node, - std::set& visited, - std::set& seen) + QPDFObjectHandle cur_node, QPDFObjGen::set& visited, QPDFObjGen::set& seen) { - QPDFObjGen cur_node_og = cur_node.getObjGen(); - if (visited.count(cur_node_og) > 0) { + if (!visited.add(cur_node)) { throw QPDFExc( qpdf_e_pages, this->m->file->getName(), @@ -105,7 +101,6 @@ QPDF::getAllPagesInternal( 0, "Loop detected in /Pages structure (getAllPages)"); } - visited.insert(cur_node_og); if (!cur_node.isDictionaryOfType("/Pages")) { cur_node.warnIfPossible( "/Type key should be /Pages but is not; overriding"); @@ -125,7 +120,7 @@ QPDF::getAllPagesInternal( " (from 0) is direct; converting to indirect"); kid = makeIndirectObject(kid); kids.setArrayItem(i, kid); - } else if (seen.count(kid.getObjGen())) { + } else if (!seen.add(kid)) { // Make a copy of the page. This does the same as // shallowCopyPage in QPDFPageObjectHelper. QTC::TC("qpdf", "QPDF resolve duplicated page object"); @@ -134,6 +129,7 @@ QPDF::getAllPagesInternal( " (from 0) appears more than once in the pages tree;" " creating a new page object as a copy"); kid = makeIndirectObject(QPDFObjectHandle(kid).shallowCopy()); + seen.add(kid); kids.setArrayItem(i, kid); } if (!kid.isDictionaryOfType("/Page")) { @@ -141,7 +137,6 @@ QPDF::getAllPagesInternal( "/Type key should be /Page but is not; overriding"); kid.replaceKey("/Type", "/Page"_qpdf); } - seen.insert(kid.getObjGen()); m->all_pages.push_back(kid); } } -- cgit v1.2.3-70-g09d2 From ae2d623929c280f1d2411787bf4e41d5d91a4f3a Mon Sep 17 00:00:00 2001 From: m-holger Date: Thu, 18 May 2023 18:05:59 +0100 Subject: Use QPDFObjGen::set in QPDF::updateObjectMaps --- include/qpdf/QPDF.hh | 2 +- libqpdf/QPDF_optimization.cc | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh index 88dadcdb..955f9c17 100644 --- a/include/qpdf/QPDF.hh +++ b/include/qpdf/QPDF.hh @@ -1645,7 +1645,7 @@ class QPDF ObjUser const& ou, QPDFObjectHandle oh, std::function skip_stream_parameters, - std::set& visited, + QPDFObjGen::set& visited, bool top); void filterCompressedObjects(std::map const& object_stream_data); diff --git a/libqpdf/QPDF_optimization.cc b/libqpdf/QPDF_optimization.cc index 41204fbd..0c534432 100644 --- a/libqpdf/QPDF_optimization.cc +++ b/libqpdf/QPDF_optimization.cc @@ -284,7 +284,7 @@ QPDF::updateObjectMaps( QPDFObjectHandle oh, std::function skip_stream_parameters) { - std::set visited; + QPDFObjGen::set visited; updateObjectMapsInternal(ou, oh, skip_stream_parameters, visited, true); } @@ -293,7 +293,7 @@ QPDF::updateObjectMapsInternal( ObjUser const& ou, QPDFObjectHandle oh, std::function skip_stream_parameters, - std::set& visited, + QPDFObjGen::set& visited, bool top) { // Traverse the object tree from this point taking care to avoid @@ -310,13 +310,12 @@ QPDF::updateObjectMapsInternal( if (oh.isIndirect()) { QPDFObjGen og(oh.getObjGen()); - if (visited.count(og)) { + if (!visited.add(og)) { QTC::TC("qpdf", "QPDF opt loop detected"); return; } this->m->obj_user_to_objects[ou].insert(og); this->m->object_to_obj_users[og].insert(ou); - visited.insert(og); } if (oh.isArray()) { -- cgit v1.2.3-70-g09d2 From 9db2965f628640e8ed19797a5fc8a31172cb6e7d Mon Sep 17 00:00:00 2001 From: m-holger Date: Thu, 18 May 2023 14:42:27 +0100 Subject: Use QPDFObjGen::set in QPDFJob::getWantedJSONObjects --- include/qpdf/QPDFJob.hh | 2 +- libqpdf/QPDFJob.cc | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/qpdf/QPDFJob.hh b/include/qpdf/QPDFJob.hh index 2a82d61c..63c888e6 100644 --- a/include/qpdf/QPDFJob.hh +++ b/include/qpdf/QPDFJob.hh @@ -571,7 +571,7 @@ class QPDFJob // JSON void doJSON(QPDF& pdf, Pipeline*); - std::set getWantedJSONObjects(); + QPDFObjGen::set getWantedJSONObjects(); void doJSONObject( Pipeline* p, bool& first, std::string const& key, QPDFObjectHandle&); void doJSONObjects(Pipeline* p, bool& first, QPDF& pdf); diff --git a/libqpdf/QPDFJob.cc b/libqpdf/QPDFJob.cc index 39ff1300..37dbf3fe 100644 --- a/libqpdf/QPDFJob.cc +++ b/libqpdf/QPDFJob.cc @@ -1001,18 +1001,16 @@ QPDFJob::parse_object_id( } } -std::set +QPDFObjGen::set QPDFJob::getWantedJSONObjects() { - std::set wanted_og; + QPDFObjGen::set wanted_og; for (auto const& iter: m->json_objects) { bool trailer; int obj = 0; int gen = 0; parse_object_id(iter, trailer, obj, gen); - if (obj) { - wanted_og.insert(QPDFObjGen(obj, gen)); - } + wanted_og.add(QPDFObjGen(obj, gen)); } return wanted_og; } -- cgit v1.2.3-70-g09d2