summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Astals Cid <aacid@kde.org>2023-09-20 22:20:13 +0200
committerAlbert Astals Cid <aacid@kde.org>2023-09-20 22:20:13 +0200
commit8ba682b1a5d53efe975849a260e78715da74263c (patch)
tree23cbbdcf7e26058a7f3abd2db71a2b8e7f6ff3d0
parent77573e1a706f861ca4677ea36dbdcc0a9fb50a99 (diff)
Introduce RefRecursionChecker
-rw-r--r--poppler/Annot.cc17
-rw-r--r--poppler/FontInfo.cc15
-rw-r--r--poppler/FontInfo.h2
-rw-r--r--poppler/Object.h22
-rw-r--r--poppler/PageLabelInfo.cc14
-rw-r--r--poppler/PageLabelInfo.h2
6 files changed, 37 insertions, 35 deletions
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index aebcffcd..d62ba890 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -5314,19 +5314,8 @@ bool AnnotAppearanceBuilder::drawFormFieldChoice(const FormFieldChoice *fieldCho
return true;
}
-static bool insertIfNotAlreadyPresent(Ref r, std::set<int> *alreadySeenDicts)
-{
- if (r == Ref::INVALID()) {
- return true;
- }
-
- // std::pair<iterator,bool>
- const auto insertResult = alreadySeenDicts->insert(r.num);
- return insertResult.second;
-}
-
// Should we also merge Arrays?
-static void recursiveMergeDicts(Dict *primary, const Dict *secondary, std::set<int> *alreadySeenDicts)
+static void recursiveMergeDicts(Dict *primary, const Dict *secondary, RefRecursionChecker *alreadySeenDicts)
{
for (int i = 0; i < secondary->getLength(); ++i) {
const char *key = secondary->getKey(i);
@@ -5339,7 +5328,7 @@ static void recursiveMergeDicts(Dict *primary, const Dict *secondary, std::set<i
Ref secondaryRef;
Object secondaryObj = secondary->lookup(key, &secondaryRef);
if (secondaryObj.isDict()) {
- if (!insertIfNotAlreadyPresent(primaryRef, alreadySeenDicts) || !insertIfNotAlreadyPresent(secondaryRef, alreadySeenDicts)) {
+ if (!alreadySeenDicts->insert(primaryRef) || !alreadySeenDicts->insert(secondaryRef)) {
// bad PDF
return;
}
@@ -5352,7 +5341,7 @@ static void recursiveMergeDicts(Dict *primary, const Dict *secondary, std::set<i
static void recursiveMergeDicts(Dict *primary, const Dict *secondary)
{
- std::set<int> alreadySeenDicts;
+ RefRecursionChecker alreadySeenDicts;
recursiveMergeDicts(primary, secondary, &alreadySeenDicts);
}
diff --git a/poppler/FontInfo.cc b/poppler/FontInfo.cc
index 0be38923..551b98a1 100644
--- a/poppler/FontInfo.cc
+++ b/poppler/FontInfo.cc
@@ -134,21 +134,16 @@ void FontInfoScanner::scanFonts(XRef *xrefA, Dict *resDict, std::vector<FontInfo
for (int i = 0; i < objDict.dictGetLength(); ++i) {
Ref obj2Ref;
const Object obj2 = objDict.getDict()->getVal(i, &obj2Ref);
- if (obj2Ref != Ref::INVALID()) {
- // check for an already-seen object
- if (!visitedObjects.insert(obj2Ref.num).second) {
- continue;
- }
+ // check for an already-seen object
+ if (!visitedObjects.insert(obj2Ref)) {
+ continue;
}
if (obj2.isStream()) {
Ref resourcesRef;
const Object resObj = obj2.streamGetDict()->lookup("Resources", &resourcesRef);
-
- if (resourcesRef != Ref::INVALID()) {
- if (!visitedObjects.insert(resourcesRef.num).second) {
- continue;
- }
+ if (!visitedObjects.insert(resourcesRef)) {
+ continue;
}
if (resObj.isDict() && resObj.getDict() != resDict) {
diff --git a/poppler/FontInfo.h b/poppler/FontInfo.h
index d13ae978..24903cdb 100644
--- a/poppler/FontInfo.h
+++ b/poppler/FontInfo.h
@@ -101,7 +101,7 @@ private:
PDFDoc *doc;
int currentPage;
std::unordered_set<int> fonts;
- std::unordered_set<int> visitedObjects;
+ RefRecursionChecker visitedObjects;
void scanFonts(XRef *xrefA, Dict *resDict, std::vector<FontInfo *> *fontsList);
};
diff --git a/poppler/Object.h b/poppler/Object.h
index d0975100..10fffc04 100644
--- a/poppler/Object.h
+++ b/poppler/Object.h
@@ -113,6 +113,28 @@ inline bool operator<(const Ref lhs, const Ref rhs) noexcept
return lhs.gen < rhs.gen;
}
+struct RefRecursionChecker
+{
+ RefRecursionChecker() { }
+
+ RefRecursionChecker(const RefRecursionChecker &) = delete;
+ RefRecursionChecker &operator=(const RefRecursionChecker &) = delete;
+
+ bool insert(Ref ref)
+ {
+ if (ref == Ref::INVALID()) {
+ return true;
+ }
+
+ // insert returns std::pair<iterator,bool>
+ // where the bool is whether the insert succeeded
+ return alreadySeenRefs.insert(ref.num).second;
+ }
+
+private:
+ std::set<int> alreadySeenRefs;
+};
+
namespace std {
template<>
diff --git a/poppler/PageLabelInfo.cc b/poppler/PageLabelInfo.cc
index 40a6e7fc..9b67b455 100644
--- a/poppler/PageLabelInfo.cc
+++ b/poppler/PageLabelInfo.cc
@@ -60,7 +60,7 @@ PageLabelInfo::Interval::Interval(Object *dict, int baseA)
PageLabelInfo::PageLabelInfo(Object *tree, int numPages)
{
- std::set<int> alreadyParsedRefs;
+ RefRecursionChecker alreadyParsedRefs;
parse(tree, alreadyParsedRefs);
if (intervals.empty()) {
@@ -74,7 +74,7 @@ PageLabelInfo::PageLabelInfo(Object *tree, int numPages)
curr->length = std::max(0, numPages - curr->base);
}
-void PageLabelInfo::parse(const Object *tree, std::set<int> &alreadyParsedRefs)
+void PageLabelInfo::parse(const Object *tree, RefRecursionChecker &alreadyParsedRefs)
{
// leaf node
Object nums = tree->dictLookup("Nums");
@@ -103,13 +103,9 @@ void PageLabelInfo::parse(const Object *tree, std::set<int> &alreadyParsedRefs)
for (int i = 0; i < kidsArray->getLength(); ++i) {
Ref ref;
const Object kid = kidsArray->get(i, &ref);
- if (ref != Ref::INVALID()) {
- const int numObj = ref.num;
- if (alreadyParsedRefs.find(numObj) != alreadyParsedRefs.end()) {
- error(errSyntaxError, -1, "loop in PageLabelInfo (numObj: {0:d})", numObj);
- continue;
- }
- alreadyParsedRefs.insert(numObj);
+ if (!alreadyParsedRefs.insert(ref)) {
+ error(errSyntaxError, -1, "loop in PageLabelInfo (ref.num: {0:d})", ref.num);
+ continue;
}
if (kid.isDict()) {
parse(&kid, alreadyParsedRefs);
diff --git a/poppler/PageLabelInfo.h b/poppler/PageLabelInfo.h
index bec70d32..2cfec29a 100644
--- a/poppler/PageLabelInfo.h
+++ b/poppler/PageLabelInfo.h
@@ -37,7 +37,7 @@ public:
bool indexToLabel(int index, GooString *label) const;
private:
- void parse(const Object *tree, std::set<int> &parsedRefs);
+ void parse(const Object *tree, RefRecursionChecker &parsedRefs);
private:
struct Interval