File poppler-CVE-2020-36023.patch of Package poppler.31330

From 238dc045beeeb1eb619f3fb6cb699ba36813222d Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <aacid@kde.org>
Date: Mon, 21 Dec 2020 22:57:44 +0100
Subject: [PATCH] Fix infinite looping in cvtGlyph with broken files

---
 fofi/FoFiType1C.cc | 20 +++++++++++++++-----
 fofi/FoFiType1C.h  |  4 +++-
 2 files changed, 18 insertions(+), 6 deletions(-)

Index: poppler-0.62.0/fofi/FoFiType1C.cc
===================================================================
--- poppler-0.62.0.orig/fofi/FoFiType1C.cc
+++ poppler-0.62.0/fofi/FoFiType1C.cc
@@ -551,8 +551,9 @@ void FoFiType1C::convertToCIDType0(char
 	if (!ok) {
 	  subrIdx.pos = -1;
 	}
+	std::set<int> offsetBeingParsed;
 	cvtGlyph(val.pos, val.len, charStrings,
-		 &subrIdx, &privateDicts[fdSelect ? fdSelect[gid] : 0], gTrue);
+		 &subrIdx, &privateDicts[fdSelect ? fdSelect[gid] : 0], gTrue, offsetBeingParsed);
       }
     }
   }
@@ -1183,7 +1184,8 @@ void FoFiType1C::eexecCvtGlyph(Type1CEex
 
   // generate the charstring
   charBuf = new GooString();
-  cvtGlyph(offset, nBytes, charBuf, subrIdx, pDict, gTrue);
+  std::set<int> offsetBeingParsed;
+  cvtGlyph(offset, nBytes, charBuf, subrIdx, pDict, gTrue, offsetBeingParsed);
 
   buf = GooString::format("/{0:s} {1:d} RD ", glyphName, charBuf->getLength());
   eexecWrite(eb, buf->getCString());
@@ -1197,7 +1199,7 @@ void FoFiType1C::eexecCvtGlyph(Type1CEex
 
 void FoFiType1C::cvtGlyph(int offset, int nBytes, GooString *charBuf,
 			  Type1CIndex *subrIdx, Type1CPrivateDict *pDict,
-			  GBool top) {
+			  GBool top,  std::set<int> &offsetBeingParsed) {
   Type1CIndexVal val;
   GBool ok, dFP;
   double d, dx, dy;
@@ -1205,6 +1207,12 @@ void FoFiType1C::cvtGlyph(int offset, in
   Guchar byte;
   int pos, subrBias, start, i, k;
 
+  if (offsetBeingParsed.find(offset) != offsetBeingParsed.end()) {
+     return;
+  }
+
+  auto offsetEmplaceResult = offsetBeingParsed.emplace(offset);
+
   start = charBuf->getLength();
   if (top) {
     charBuf->append((char)73);
@@ -1362,7 +1370,7 @@ void FoFiType1C::cvtGlyph(int offset, in
 	  ok = gTrue;
 	  getIndexVal(subrIdx, k, &val, &ok);
 	  if (likely(ok && val.pos != offset)) {
-	    cvtGlyph(val.pos, val.len, charBuf, subrIdx, pDict, gFalse);
+	    cvtGlyph(val.pos, val.len, charBuf, subrIdx, pDict, gFalse, offsetBeingParsed);
 	  }
 	} else {
 	  //~ error(-1, "Too few args to Type 2 callsubr");
@@ -1597,7 +1605,7 @@ void FoFiType1C::cvtGlyph(int offset, in
 	  ok = gTrue;
 	  getIndexVal(&gsubrIdx, k, &val, &ok);
 	  if (likely(ok && val.pos != offset)) {
-	    cvtGlyph(val.pos, val.len, charBuf, subrIdx, pDict, gFalse);
+	    cvtGlyph(val.pos, val.len, charBuf, subrIdx, pDict, gFalse, offsetBeingParsed);
 	  }
 	} else {
 	  //~ error(-1, "Too few args to Type 2 callgsubr");
@@ -1825,6 +1833,8 @@ void FoFiType1C::cvtGlyph(int offset, in
       r2 = (byte + r2) * 52845 + 22719;
     }
   }
+
+  offsetBeingParsed.erase(offsetEmplaceResult.first);
 }
 
 void FoFiType1C::cvtGlyphWidth(GBool useOp, GooString *charBuf,
Index: poppler-0.62.0/fofi/FoFiType1C.h
===================================================================
--- poppler-0.62.0.orig/fofi/FoFiType1C.h
+++ poppler-0.62.0/fofi/FoFiType1C.h
@@ -31,6 +31,8 @@
 #include "goo/gtypes.h"
 #include "FoFiBase.h"
 
+#include <set>
+
 class GooString;
 
 //------------------------------------------------------------------------
@@ -214,7 +216,7 @@ private:
 		     Type1CPrivateDict *pDict);
   void cvtGlyph(int offset, int nBytes, GooString *charBuf,
 		Type1CIndex *subrIdx, Type1CPrivateDict *pDict,
-		GBool top);
+		GBool top, std::set<int> &offsetBeingParsed);
   void cvtGlyphWidth(GBool useOp, GooString *charBuf,
 		     Type1CPrivateDict *pDict);
   void cvtNum(double x, GBool isFP, GooString *charBuf);
openSUSE Build Service is sponsored by