fofi/FoFiType1C.cc | 20 +++++++++++++++----- fofi/FoFiType1C.h | 4 +++- 2 files changed, 18 insertions(+), 6 deletions(-)
New commits: commit 238dc045beeeb1eb619f3fb6cb699ba36813222d Author: Albert Astals Cid <[email protected]> Date: Mon Dec 21 22:57:44 2020 +0100 Fix infinite looping in cvtGlyph with broken files diff --git a/fofi/FoFiType1C.cc b/fofi/FoFiType1C.cc index ac78dc23..0387b0a8 100644 --- a/fofi/FoFiType1C.cc +++ b/fofi/FoFiType1C.cc @@ -526,7 +526,8 @@ void FoFiType1C::convertToCIDType0(const char *psName, const int *codeMap, int n if (!ok) { subrIdx.pos = -1; } - cvtGlyph(val.pos, val.len, charStrings, &subrIdx, &privateDicts[fdSelect ? fdSelect[gid] : 0], true); + std::set<int> offsetBeingParsed; + cvtGlyph(val.pos, val.len, charStrings, &subrIdx, &privateDicts[fdSelect ? fdSelect[gid] : 0], true, offsetBeingParsed); } } } @@ -1103,7 +1104,8 @@ void FoFiType1C::eexecCvtGlyph(Type1CEexecBuf *eb, const char *glyphName, int of // 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()); @@ -1114,7 +1116,7 @@ void FoFiType1C::eexecCvtGlyph(Type1CEexecBuf *eb, const char *glyphName, int of delete charBuf; } -void FoFiType1C::cvtGlyph(int offset, int nBytes, GooString *charBuf, const Type1CIndex *subrIdx, const Type1CPrivateDict *pDict, bool top) +void FoFiType1C::cvtGlyph(int offset, int nBytes, GooString *charBuf, const Type1CIndex *subrIdx, const Type1CPrivateDict *pDict, bool top, std::set<int> &offsetBeingParsed) { Type1CIndexVal val; bool ok, dFP; @@ -1123,6 +1125,12 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GooString *charBuf, const Type 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; @@ -1279,7 +1287,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GooString *charBuf, const Type 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"); @@ -1514,7 +1522,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GooString *charBuf, const Type 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"); @@ -1739,6 +1747,8 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GooString *charBuf, const Type r2 = (byte + r2) * 52845 + 22719; } } + + offsetBeingParsed.erase(offsetEmplaceResult.first); } void FoFiType1C::cvtGlyphWidth(bool useOp, GooString *charBuf, const Type1CPrivateDict *pDict) diff --git a/fofi/FoFiType1C.h b/fofi/FoFiType1C.h index 9652fcc6..b2ebc934 100644 --- a/fofi/FoFiType1C.h +++ b/fofi/FoFiType1C.h @@ -27,6 +27,8 @@ #include "FoFiBase.h" +#include <set> + class GooString; //------------------------------------------------------------------------ @@ -207,7 +209,7 @@ public: private: FoFiType1C(const char *fileA, int lenA, bool freeFileDataA); void eexecCvtGlyph(Type1CEexecBuf *eb, const char *glyphName, int offset, int nBytes, const Type1CIndex *subrIdx, const Type1CPrivateDict *pDict); - void cvtGlyph(int offset, int nBytes, GooString *charBuf, const Type1CIndex *subrIdx, const Type1CPrivateDict *pDict, bool top); + void cvtGlyph(int offset, int nBytes, GooString *charBuf, const Type1CIndex *subrIdx, const Type1CPrivateDict *pDict, bool top, std::set<int> &offsetBeingParsed); void cvtGlyphWidth(bool useOp, GooString *charBuf, const Type1CPrivateDict *pDict); void cvtNum(double x, bool isFP, GooString *charBuf) const; void eexecWrite(Type1CEexecBuf *eb, const char *s) const; _______________________________________________ poppler mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/poppler
