poppler/Annot.cc | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-)
New commits: commit 78e939131f868e3ea6541ee1c096d82cd548e706 Author: Albert Astals Cid <aa...@kde.org> Date: Mon Aug 1 21:33:25 2022 +0200 Fix infinite recursion in broken files oss-fuzz/49702 diff --git a/poppler/Annot.cc b/poppler/Annot.cc index b41fa982..7e4963ec 100644 --- a/poppler/Annot.cc +++ b/poppler/Annot.cc @@ -5347,25 +5347,48 @@ 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) +static void recursiveMergeDicts(Dict *primary, const Dict *secondary, std::set<int> *alreadySeenDicts) { for (int i = 0; i < secondary->getLength(); ++i) { const char *key = secondary->getKey(i); if (!primary->hasKey(key)) { primary->add(key, secondary->lookup(key).deepCopy()); } else { - Object primaryObj = primary->lookup(key); + Ref primaryRef; + Object primaryObj = primary->lookup(key, &primaryRef); if (primaryObj.isDict()) { - Object secondaryObj = secondary->lookup(key); + Ref secondaryRef; + Object secondaryObj = secondary->lookup(key, &secondaryRef); if (secondaryObj.isDict()) { - recursiveMergeDicts(primaryObj.getDict(), secondaryObj.getDict()); + if (!insertIfNotAlreadyPresent(primaryRef, alreadySeenDicts) || !insertIfNotAlreadyPresent(secondaryRef, alreadySeenDicts)) { + // bad PDF + return; + } + recursiveMergeDicts(primaryObj.getDict(), secondaryObj.getDict(), alreadySeenDicts); } } } } } +static void recursiveMergeDicts(Dict *primary, const Dict *secondary) +{ + std::set<int> alreadySeenDicts; + recursiveMergeDicts(primary, secondary, &alreadySeenDicts); +} + void AnnotWidget::generateFieldAppearance() { const GooString *da;