From 182914fd1e41183282630675594c255e519f580a Mon Sep 17 00:00:00 2001
From: xiongyi <xiongyi@uniontech.com>
Date: Wed, 29 Nov 2023 14:29:46 +0800
Subject: [PATCH] backport-CVE-2020-36023

Signed-off-by: xiongyi <xiongyi@uniontech.com>
---
 fofi/FoFiType1C.cc | 20 +++++++++++++++-----
 fofi/FoFiType1C.h  |  4 +++-
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/fofi/FoFiType1C.cc b/fofi/FoFiType1C.cc
index 9a39063..c8241f2 100644
--- a/fofi/FoFiType1C.cc
+++ b/fofi/FoFiType1C.cc
@@ -551,8 +551,9 @@ void FoFiType1C::convertToCIDType0(const char *psName, const int *codeMap, int n
 	if (!ok) {
 	  subrIdx.pos = -1;
 	}
+	std::set<int> offsetBeingParsed;
 	cvtGlyph(val.pos, val.len, charStrings,
-		 &subrIdx, &privateDicts[fdSelect ? fdSelect[gid] : 0], true);
+		 &subrIdx, &privateDicts[fdSelect ? fdSelect[gid] : 0], true, offsetBeingParsed);
       }
     }
   }
@@ -1183,7 +1184,8 @@ void FoFiType1C::eexecCvtGlyph(Type1CEexecBuf *eb, const char *glyphName,
 
   // generate the charstring
   charBuf = new GooString();
-  cvtGlyph(offset, nBytes, charBuf, subrIdx, pDict, true);
+  std::set<int> offsetBeingParsed;
+  cvtGlyph(offset, nBytes, charBuf, subrIdx, pDict, true, offsetBeingParsed);
 
   buf = GooString::format("/{0:s} {1:d} RD ", glyphName, charBuf->getLength());
   eexecWrite(eb, buf->c_str());
@@ -1197,7 +1199,7 @@ void FoFiType1C::eexecCvtGlyph(Type1CEexecBuf *eb, const char *glyphName,
 
 void FoFiType1C::cvtGlyph(int offset, int nBytes, GooString *charBuf,
 			  const Type1CIndex *subrIdx, const Type1CPrivateDict *pDict,
-			  bool top) {
+			  bool top, std::set<int> &offsetBeingParsed) {
   Type1CIndexVal val;
   bool ok, dFP;
   double d, dx, dy;
@@ -1205,6 +1207,12 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GooString *charBuf,
   unsigned char 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('\x49'); //73;
@@ -1362,7 +1370,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GooString *charBuf,
 	  ok = true;
 	  getIndexVal(subrIdx, k, &val, &ok);
 	  if (likely(ok && val.pos != offset)) {
-	    cvtGlyph(val.pos, val.len, charBuf, subrIdx, pDict, false);
+	    cvtGlyph(val.pos, val.len, charBuf, subrIdx, pDict, false, offsetBeingParsed);
 	  }
 	} else {
 	  //~ error(-1, "Too few args to Type 2 callsubr");
@@ -1597,7 +1605,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GooString *charBuf,
 	  ok = true;
 	  getIndexVal(&gsubrIdx, k, &val, &ok);
 	  if (likely(ok && val.pos != offset)) {
-	    cvtGlyph(val.pos, val.len, charBuf, subrIdx, pDict, false);
+	    cvtGlyph(val.pos, val.len, charBuf, subrIdx, pDict, false, offsetBeingParsed);
 	  }
 	} else {
 	  //~ error(-1, "Too few args to Type 2 callgsubr");
@@ -1825,6 +1833,8 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GooString *charBuf,
       r2 = (byte + r2) * 52845 + 22719;
     }
   }
+
+  offsetBeingParsed.erase(offsetEmplaceResult.first);
 }
 
 void FoFiType1C::cvtGlyphWidth(bool useOp, GooString *charBuf,
diff --git a/fofi/FoFiType1C.h b/fofi/FoFiType1C.h
index 067ab99..b1b48fe 100644
--- a/fofi/FoFiType1C.h
+++ b/fofi/FoFiType1C.h
@@ -27,6 +27,8 @@
 
 #include "FoFiBase.h"
 
+#include <set>
+
 class GooString;
 
 //------------------------------------------------------------------------
@@ -210,7 +212,7 @@ private:
 		     const Type1CPrivateDict *pDict);
   void cvtGlyph(int offset, int nBytes, GooString *charBuf,
 		const Type1CIndex *subrIdx, const Type1CPrivateDict *pDict,
-		bool top);
+		bool top, std::set<int> &offsetBeingParsed);
   void cvtGlyphWidth(bool useOp, GooString *charBuf,
 		     const Type1CPrivateDict *pDict);
   void cvtNum(double x, bool isFP, GooString *charBuf) const;
-- 
2.33.0

