File poppler-CVE-2022-37052.patch of Package poppler.34111

Index: poppler-0.24.4/poppler/PDFDoc.cc
===================================================================
--- poppler-0.24.4.orig/poppler/PDFDoc.cc
+++ poppler-0.24.4/poppler/PDFDoc.cc
@@ -693,7 +693,14 @@ int PDFDoc::savePageAs(GooString *name,
   pagesDict->lookup("Resources", &resourcesObj);
   if (resourcesObj.isDict())
     markPageObjects(resourcesObj.getDict(), yRef, countRef, 0);
-  markPageObjects(catDict, yRef, countRef, 0);
+  if (!markPageObjects(catDict, yRef, countRef, 0)) {
+    fclose(f);
+    delete yRef;
+    delete countRef;
+    delete outStr;
+    error(errSyntaxError, -1, "markPageObjects failed");
+    return errDamaged;
+  }
 
   Dict *pageDict = page.getDict();
   markPageObjects(pageDict, yRef, countRef, 0);
@@ -1415,16 +1422,21 @@ void PDFDoc::writeHeader(OutStream *outS
    outStr->printf("%%\xE2\xE3\xCF\xD3\n");
 }
 
-void PDFDoc::markDictionnary (Dict* dict, XRef * xRef, XRef *countRef, Guint numOffset)
+bool PDFDoc::markDictionnary (Dict* dict, XRef * xRef, XRef *countRef, Guint numOffset)
 {
   Object obj1;
   for (int i=0; i<dict->getLength(); i++) {
-    markObject(dict->getValNF(i, &obj1), xRef, countRef, numOffset);
+    static bool success = markObject(dict->getValNF(i, &obj1), xRef, countRef, numOffset);
+    if (unlikely(!success)) {
+      return false;
+    }
     obj1.free();
   }
+
+  return true;
 }
 
-void PDFDoc::markObject (Object* obj, XRef *xRef, XRef *countRef, Guint numOffset)
+bool PDFDoc::markObject (Object* obj, XRef *xRef, XRef *countRef, Guint numOffset)
 {
   Array *array;
   Object obj1;
@@ -1433,26 +1445,40 @@ void PDFDoc::markObject (Object* obj, XR
     case objArray:
       array = obj->getArray();
       for (int i=0; i<array->getLength(); i++) {
-        markObject(array->getNF(i, &obj1), xRef, countRef, numOffset);
+        const bool success = markObject(array->getNF(i, &obj1), xRef, countRef, numOffset);
+        if (unlikely(!success)) {
+          return false;
+        }
         obj1.free();
       }
       break;
     case objDict:
-      markDictionnary (obj->getDict(), xRef, countRef, numOffset);
+      {
+        int success = markDictionnary (obj->getDict(), xRef, countRef, numOffset);
+        if (unlikely(!success)) {
+          return false;
+        }
+      }
       break;
     case objStream: 
       {
         Stream *stream = obj->getStream();
-        markDictionnary (stream->getDict(), xRef, countRef, numOffset);
+        const bool success = markDictionnary (stream->getDict(), xRef, countRef, numOffset);
+        if (unlikely(!success)) {
+          return false;
+        }
       }
       break;
     case objRef:
       {
         if (obj->getRef().num + (int) numOffset >= xRef->getNumObjects() || xRef->getEntry(obj->getRef().num + numOffset)->type == xrefEntryFree) {
           if (getXRef()->getEntry(obj->getRef().num)->type == xrefEntryFree) {
-            return;  // already marked as free => should be replaced
+            return true;  // already marked as free => should be replaced
+          }
+          const bool success = xRef->add(obj->getRef().num + numOffset, obj->getRef().gen, 0, gTrue);
+          if (unlikely(!success)) {
+            return false;
           }
-          xRef->add(obj->getRef().num + numOffset, obj->getRef().gen, 0, gTrue);
           if (getXRef()->getEntry(obj->getRef().num)->type == xrefEntryCompressed) {
             xRef->getEntry(obj->getRef().num + numOffset)->type = xrefEntryCompressed;
           }
@@ -1469,13 +1495,18 @@ void PDFDoc::markObject (Object* obj, XR
         } 
         Object obj1;
         getXRef()->fetch(obj->getRef().num, obj->getRef().gen, &obj1);
-        markObject(&obj1, xRef, countRef, numOffset);
+        const bool success = markObject(&obj1, xRef, countRef, numOffset);
+        if (unlikely(!success)) {
+          return false;
+        }
         obj1.free();
       }
       break;
     default:
       break;
   }
+
+  return true;
 }
 
 void PDFDoc::replacePageDict(int pageNo, int rotate,
@@ -1559,7 +1590,7 @@ void PDFDoc::replacePageDict(int pageNo,
   page.free();
 }
 
-void PDFDoc::markPageObjects(Dict *pageDict, XRef *xRef, XRef *countRef, Guint numOffset) 
+bool PDFDoc::markPageObjects(Dict *pageDict, XRef *xRef, XRef *countRef, Guint numOffset) 
 {
   pageDict->remove("Names");
   pageDict->remove("OpenAction");
@@ -1572,10 +1603,14 @@ void PDFDoc::markPageObjects(Dict *pageD
     if (strcmp(key, "Parent") != 0 &&
 	      strcmp(key, "Pages") != 0 &&
         strcmp(key, "Root") != 0) {
-      markObject(&value, xRef, countRef, numOffset);
+      const bool success = markObject(&value, xRef, countRef, numOffset);
+      if (unlikely(!success)) {
+        return false;
+      }
     }
     value.free();
   }
+  return true;
 }
 
 Guint PDFDoc::writePageObjects(OutStream *outStr, XRef *xRef, Guint numOffset, GBool combine) 
Index: poppler-0.24.4/poppler/PDFDoc.h
===================================================================
--- poppler-0.24.4.orig/poppler/PDFDoc.h
+++ poppler-0.24.4/poppler/PDFDoc.h
@@ -246,7 +246,7 @@ public:
 
   // rewrite pageDict with MediaBox, CropBox and new page CTM
   void replacePageDict(int pageNo, int rotate, PDFRectangle *mediaBox, PDFRectangle *cropBox, Object *pageCTM);
-  void markPageObjects(Dict *pageDict, XRef *xRef, XRef *countRef, Guint numOffset);
+  bool markPageObjects(Dict *pageDict, XRef *xRef, XRef *countRef, Guint numOffset);
   // write all objects used by pageDict to outStr
   Guint writePageObjects(OutStream *outStr, XRef *xRef, Guint numOffset, GBool combine = gFalse);
   static void writeObject (Object *obj, OutStream* outStr, XRef *xref, Guint numOffset, Guchar *fileKey,
@@ -263,8 +263,8 @@ public:
 
 private:
   // insert referenced objects in XRef
-  void markDictionnary (Dict* dict, XRef *xRef, XRef *countRef, Guint numOffset);
-  void markObject (Object *obj, XRef *xRef, XRef *countRef, Guint numOffset);
+  bool markDictionnary (Dict* dict, XRef *xRef, XRef *countRef, Guint numOffset);
+  bool markObject (Object *obj, XRef *xRef, XRef *countRef, Guint numOffset);
   static void writeDictionnary (Dict* dict, OutStream* outStr, XRef *xRef, Guint numOffset, Guchar *fileKey,
                                 CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen);
 
Index: poppler-0.24.4/poppler/XRef.cc
===================================================================
--- poppler-0.24.4.orig/poppler/XRef.cc
+++ poppler-0.24.4/poppler/XRef.cc
@@ -1325,11 +1325,16 @@ int XRef::getNumEntry(Goffset offset)
   else return -1;
 }
 
-void XRef::add(int num, int gen, Goffset offs, GBool used) {
+bool XRef::add(int num, int gen, Goffset offs, GBool used) {
   xrefLocker();
   if (num >= size) {
     if (num >= capacity) {
-      entries = (XRefEntry *)greallocn(entries, num + 1, sizeof(XRefEntry));
+      entries = (XRefEntry *)greallocn_checkoverflow(entries, num + 1, sizeof(XRefEntry));
+      if (unlikely(entries == nullptr)) {
+        size = 0;
+        capacity = 0;
+        return false;
+      }
       capacity = num + 1;
     }
     for (int i = size; i < num + 1; ++i) {
@@ -1352,6 +1357,7 @@ void XRef::add(int num, int gen, Goffset
     e->type = xrefEntryFree;
     e->offset = 0;
   }
+  return true;
 }
 
 void XRef::setModifiedObject (Object* o, Ref r) {
Index: poppler-0.24.4/poppler/XRef.h
===================================================================
--- poppler-0.24.4.orig/poppler/XRef.h
+++ poppler-0.24.4/poppler/XRef.h
@@ -180,7 +180,7 @@ public:
   void setModifiedObject(Object* o, Ref r);
   Ref addIndirectObject (Object* o);
   void removeIndirectObject(Ref r);
-  void add(int num, int gen,  Goffset offs, GBool used);
+  bool add(int num, int gen,  Goffset offs, GBool used);
 
   // Output XRef table to stream
   void writeTableToFile(OutStream* outStr, GBool writeAllEntries);
openSUSE Build Service is sponsored by