[poppler] poppler/Annot.cc

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Aug 1 19:39:38 UTC 2022


 poppler/Annot.cc |   31 +++++++++++++++++++++++++++----
 1 file changed, 27 insertions(+), 4 deletions(-)

New commits:
commit 78e939131f868e3ea6541ee1c096d82cd548e706
Author: Albert Astals Cid <aacid at 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;


More information about the poppler mailing list