diff options
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc')
-rw-r--r-- | Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc | 84 |
1 files changed, 59 insertions, 25 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc index 13c045f8b97..b4f0a061be9 100644 --- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc +++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc @@ -26,6 +26,8 @@ static char hexChars[17] = "0123456789ABCDEF"; +#define type1cSubrRecursionLimit 20 + //------------------------------------------------------------------------ GBool Type1COp::isZero() { @@ -39,28 +41,52 @@ GBool Type1COp::isZero() { GBool Type1COp::isNegative() { switch (kind) { - case type1COpInteger: return intgr < 0; - case type1COpFloat: return flt < 0; - case type1COpRational: return (rat.num < 0) != (rat.den < 0); - default: return gFalse; // shouldn't happen + case type1COpInteger: + return intgr < 0; + case type1COpFloat: + return flt < 0; + case type1COpRational: + return (rat.num < 0) != (rat.den < 0); + default: + // shouldn't happen + return gFalse; } } int Type1COp::toInt() { switch (kind) { - case type1COpInteger: return intgr; - case type1COpFloat: return (int)flt; - case type1COpRational: return rat.num / rat.den; - default: return 0; // shouldn't happen + case type1COpInteger: + return intgr; + case type1COpFloat: + if (flt < -2e9 || flt > 2e9) { + return 0; + } + return (int)flt; + case type1COpRational: + if (rat.den == 0) { + return 0; + } + return rat.num / rat.den; + default: + // shouldn't happen + return 0; } } double Type1COp::toFloat() { switch (kind) { - case type1COpInteger: return (double)intgr; - case type1COpFloat: return flt; - case type1COpRational: return (double)rat.num / (double)rat.den; - default: return 0.0; // shouldn't happen + case type1COpInteger: + return (double)intgr; + case type1COpFloat: + return flt; + case type1COpRational: + if (rat.den == 0) { + return 0; + } + return (double)rat.num / (double)rat.den; + default: + // shouldn't happen + return 0.0; } } @@ -607,7 +633,8 @@ void FoFiType1C::convertToCIDType0(char *psName, int *codeMap, int nCodes, subrIdx.pos = -1; } cvtGlyph(val.pos, val.len, charStrings, - &subrIdx, &privateDicts[fdSelect ? fdSelect[gid] : 0], gTrue); + &subrIdx, &privateDicts[fdSelect ? fdSelect[gid] : 0], + gTrue, 0); } } } @@ -969,6 +996,10 @@ void FoFiType1C::convertToType0(char *psName, int *codeMap, int nCodes, } } } + if (fd < 0 || fd >= nFDs) { + // this will only happen in a broken/damaged font + fd = 0; + } // font dictionary (unencrypted section) (*outputFunc)(outputStream, "16 dict begin\n", 14); @@ -1269,7 +1300,7 @@ void FoFiType1C::eexecCvtGlyph(Type1CEexecBuf *eb, const char *glyphName, // generate the charstring charBuf = new GString(); - cvtGlyph(offset, nBytes, charBuf, subrIdx, pDict, gTrue); + cvtGlyph(offset, nBytes, charBuf, subrIdx, pDict, gTrue, 0); buf = GString::format("/{0:s} {1:d} RD ", glyphName, charBuf->getLength()); eexecWrite(eb, buf->getCString()); @@ -1283,7 +1314,7 @@ void FoFiType1C::eexecCvtGlyph(Type1CEexecBuf *eb, const char *glyphName, void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, Type1CIndex *subrIdx, Type1CPrivateDict *pDict, - GBool top) { + GBool top, int recursion) { Type1CIndexVal val; Type1COp zero, tmp; GBool ok, dInt; @@ -1292,6 +1323,11 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, Guchar byte; int pos, subrBias, start, num, den, i, k; + if (recursion > type1cSubrRecursionLimit) { + //~ error(-1, "Recursive loop in Type1C glyph"); + return; + } + start = charBuf->getLength(); if (top) { charBuf->append((char)73); @@ -1504,7 +1540,8 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, ok = gTrue; getIndexVal(subrIdx, k, &val, &ok); if (ok) { - cvtGlyph(val.pos, val.len, charBuf, subrIdx, pDict, gFalse); + cvtGlyph(val.pos, val.len, charBuf, subrIdx, pDict, gFalse, + recursion + 1); } } else { //~ error(-1, "Too few args to Type 2 callsubr"); @@ -1739,7 +1776,8 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, ok = gTrue; getIndexVal(&gsubrIdx, k, &val, &ok); if (ok) { - cvtGlyph(val.pos, val.len, charBuf, subrIdx, pDict, gFalse); + cvtGlyph(val.pos, val.len, charBuf, subrIdx, pDict, gFalse, + recursion + 1); } } else { //~ error(-1, "Too few args to Type 2 callgsubr"); @@ -2945,11 +2983,10 @@ void FoFiType1C::readFDSelect() { int fdSelectFmt, pos, nRanges, gid0, gid1, fd, i, j; fdSelect = (Guchar *)gmalloc(nGlyphs); - if (topDict.fdSelectOffset == 0) { - for (i = 0; i < nGlyphs; ++i) { - fdSelect[i] = 0; - } - } else { + for (i = 0; i < nGlyphs; ++i) { + fdSelect[i] = 0; + } + if (topDict.fdSelectOffset != 0) { pos = topDict.fdSelectOffset; fdSelectFmt = getU8(pos++, &parsedOk); if (!parsedOk) { @@ -2992,9 +3029,6 @@ void FoFiType1C::readFDSelect() { } } else { //~ error(-1, "Unknown FDSelect table format in CID font"); - for (i = 0; i < nGlyphs; ++i) { - fdSelect[i] = 0; - } } } } |