File poppler-CVE-2025-11896.patch of Package poppler.41937

From 998c6a79571af968ba90af57a0c5dcbb5a53763c Mon Sep 17 00:00:00 2001
From: Sune Vuorela <sune@vuorela.dk>
Date: Mon, 13 Oct 2025 15:13:14 +0200
Subject: [PATCH] Limit recursion in cmap parsing

fixes #1632
---
 poppler/CMap.cc | 18 +++++++++++-------
 poppler/CMap.h  | 13 +++++++------
 2 files changed, 18 insertions(+), 13 deletions(-)

Index: poppler-22.01.0/poppler/CMap.cc
===================================================================
--- poppler-22.01.0.orig/poppler/CMap.cc
+++ poppler-22.01.0/poppler/CMap.cc
@@ -65,7 +65,7 @@ static int getCharFromStream(void *data)
 
 //------------------------------------------------------------------------
 
-CMap *CMap::parse(CMapCache *cache, const GooString *collectionA, Object *obj)
+CMap *CMap::parse(CMapCache *cache, const GooString *collectionA, Object *obj, int recursion)
 {
     CMap *cMap;
     GooString *cMapNameA;
@@ -77,7 +77,7 @@ CMap *CMap::parse(CMapCache *cache, cons
         }
         delete cMapNameA;
     } else if (obj->isStream()) {
-        if (!(cMap = CMap::parse(nullptr, collectionA, obj->getStream()))) {
+        if (!(cMap = CMap::parse(nullptr, collectionA, obj->getStream(), recursion + 1))) {
             error(errSyntaxError, -1, "Invalid CMap in Type 0 font");
         }
     } else {
@@ -114,12 +114,15 @@ CMap *CMap::parse(CMapCache *cache, cons
     return cMap;
 }
 
-CMap *CMap::parse(CMapCache *cache, const GooString *collectionA, Stream *str)
+CMap *CMap::parse(CMapCache *cache, const GooString *collectionA, Stream *str, int recursion)
 {
+    if (recursion > 50) {
+        return nullptr;
+    }
     CMap *cMap = new CMap(collectionA->copy(), nullptr);
     Object obj1 = str->getDict()->lookup("UseCMap");
     if (!obj1.isNull()) {
-        cMap->useCMap(cache, &obj1);
+        cMap->useCMap(cache, &obj1, recursion);
     }
 
     str->reset();
@@ -245,11 +248,11 @@ void CMap::useCMap(CMapCache *cache, con
     subCMap->decRefCnt();
 }
 
-void CMap::useCMap(CMapCache *cache, Object *obj)
+void CMap::useCMap(CMapCache *cache, Object *obj, int recursion)
 {
     CMap *subCMap;
 
-    subCMap = CMap::parse(cache, collection, obj);
+    subCMap = CMap::parse(cache, collection, obj, recursion + 1);
     if (!subCMap) {
         return;
     }
Index: poppler-22.01.0/poppler/CMap.h
===================================================================
--- poppler-22.01.0.orig/poppler/CMap.h
+++ poppler-22.01.0/poppler/CMap.h
@@ -28,6 +28,7 @@
 
 #include <atomic>
 
+#include "Object.h"
 #include "poppler-config.h"
 #include "CharTypes.h"
 
@@ -44,7 +45,7 @@ class CMap
 public:
     // Parse a CMap from <obj>, which can be a name or a stream.  Sets
     // the initial reference count to 1.  Returns NULL on failure.
-    static CMap *parse(CMapCache *cache, const GooString *collectionA, Object *obj);
+    static CMap *parse(CMapCache *cache, const GooString *collectionA, Object *obj, int recursion = 0);
 
     // Create the CMap specified by <collection> and <cMapName>.  Sets
     // the initial reference count to 1.  Returns NULL on failure.
@@ -52,7 +53,7 @@ public:
 
     // Parse a CMap from <str>.  Sets the initial reference count to 1.
     // Returns NULL on failure.
-    static CMap *parse(CMapCache *cache, const GooString *collectionA, Stream *str);
+    static CMap *parse(CMapCache *cache, const GooString *collectionA, Stream *str, int recursion);
 
     ~CMap();
 
@@ -86,7 +87,7 @@ private:
     CMap(GooString *collectionA, GooString *cMapNameA);
     CMap(GooString *collectionA, GooString *cMapNameA, int wModeA);
     void useCMap(CMapCache *cache, const char *useName);
-    void useCMap(CMapCache *cache, Object *obj);
+    void useCMap(CMapCache *cache, Object *obj, int recursion);
     void copyVector(CMapVectorEntry *dest, CMapVectorEntry *src);
     void addCIDs(unsigned int start, unsigned int end, unsigned int nBytes, CID firstCID);
     void freeCMapVector(CMapVectorEntry *vec);
openSUSE Build Service is sponsored by