diff --git a/fofi/FoFiType1C.cc b/fofi/FoFiType1C.cc index d0ea888..135d3f9 100644 --- a/fofi/FoFiType1C.cc +++ b/fofi/FoFiType1C.cc @@ -78,6 +78,7 @@ FoFiType1C::FoFiType1C(char *fileA, int lenA, GBool freeFileDataA): privateDicts = NULL; fdSelect = NULL; charset = NULL; + charsetLength = 0; } FoFiType1C::~FoFiType1C() { @@ -121,6 +122,8 @@ GooString *FoFiType1C::getGlyphName(int gid) { GBool ok; ok = gTrue; + if (gid < 0 || gid >= charsetLength) + return NULL; getString(charset[gid], buf, &ok); if (!ok) { return NULL; @@ -141,7 +144,7 @@ int *FoFiType1C::getCIDToGIDMap(int *nCIDs) { // in a CID font, the charset data is the GID-to-CID mapping, so all // we have to do is reverse it n = 0; - for (i = 0; i < nGlyphs; ++i) { + for (i = 0; i < nGlyphs && i < charsetLength; ++i) { if (charset[i] > n) { n = charset[i]; } @@ -461,7 +464,7 @@ void FoFiType1C::convertToType1(char *psName, const char **newEncoding, GBool as for (i = 0; i < nGlyphs; ++i) { ok = gTrue; getIndexVal(&charStringsIdx, i, &val, &ok); - if (ok) { + if (ok && i < charsetLength) { getString(charset[i], buf2, &ok); if (ok) { eexecCvtGlyph(&eb, buf2, val.pos, val.len, &subrIdx, &privateDicts[0]); @@ -512,7 +515,7 @@ void FoFiType1C::convertToCIDType0(char *psName, int *codeMap, int nCodes, } } else if (topDict.firstOp == 0x0c1e) { nCIDs = 0; - for (i = 0; i < nGlyphs; ++i) { + for (i = 0; i < nGlyphs && i < charsetLength; ++i) { if (charset[i] >= nCIDs) { nCIDs = charset[i] + 1; } @@ -521,7 +524,7 @@ void FoFiType1C::convertToCIDType0(char *psName, int *codeMap, int nCodes, for (i = 0; i < nCIDs; ++i) { cidMap[i] = -1; } - for (i = 0; i < nGlyphs; ++i) { + for (i = 0; i < nGlyphs && i < charsetLength; ++i) { cidMap[charset[i]] = i; } } else { @@ -855,7 +858,7 @@ void FoFiType1C::convertToType0(char *psName, int *codeMap, int nCodes, } } else if (topDict.firstOp == 0x0c1e) { nCIDs = 0; - for (i = 0; i < nGlyphs; ++i) { + for (i = 0; i < nGlyphs && i < charsetLength; ++i) { if (charset[i] >= nCIDs) { nCIDs = charset[i] + 1; } @@ -864,7 +867,7 @@ void FoFiType1C::convertToType0(char *psName, int *codeMap, int nCodes, for (i = 0; i < nCIDs; ++i) { cidMap[i] = -1; } - for (i = 0; i < nGlyphs; ++i) { + for (i = 0; i < nGlyphs && i < charsetLength; ++i) { cidMap[charset[i]] = i; } } else { @@ -2415,7 +2418,7 @@ void FoFiType1C::buildEncoding() { if (nCodes > nGlyphs) { nCodes = nGlyphs; } - for (i = 1; i < nCodes; ++i) { + for (i = 1; i < nCodes && i < charsetLength; ++i) { c = getU8(pos++, &parsedOk); if (!parsedOk) { return; @@ -2437,7 +2440,7 @@ void FoFiType1C::buildEncoding() { if (!parsedOk) { return; } - for (j = 0; j <= nLeft && nCodes < nGlyphs; ++j) { + for (j = 0; j <= nLeft && nCodes < nGlyphs && nCodes < charsetLength; ++j) { if (c < 256) { if (encoding[c]) { gfree(encoding[c]); @@ -2480,12 +2483,16 @@ GBool FoFiType1C::readCharset() { if (topDict.charsetOffset == 0) { charset = fofiType1CISOAdobeCharset; + charsetLength = sizeof(fofiType1CISOAdobeCharset) / sizeof(Gushort); } else if (topDict.charsetOffset == 1) { charset = fofiType1CExpertCharset; + charsetLength = sizeof(fofiType1CExpertCharset) / sizeof(Gushort); } else if (topDict.charsetOffset == 2) { charset = fofiType1CExpertSubsetCharset; + charsetLength = sizeof(fofiType1CExpertSubsetCharset) / sizeof(Gushort); } else { charset = (Gushort *)gmallocn(nGlyphs, sizeof(Gushort)); + charsetLength = nGlyphs; for (i = 0; i < nGlyphs; ++i) { charset[i] = 0; } @@ -2530,6 +2537,7 @@ GBool FoFiType1C::readCharset() { if (!parsedOk) { gfree(charset); charset = NULL; + charsetLength = 0; return gFalse; } } diff --git a/fofi/FoFiType1C.h b/fofi/FoFiType1C.h index b9e1933..5af4bf9 100644 --- a/fofi/FoFiType1C.h +++ b/fofi/FoFiType1C.h @@ -250,6 +250,7 @@ private: int nFDs; Guchar *fdSelect; Gushort *charset; + Gushort charsetLength; int gsubrBias; GBool parsedOk; diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc index d7684d6..69a2bb4 100644 --- a/poppler/Gfx.cc +++ b/poppler/Gfx.cc @@ -1671,6 +1671,10 @@ void Gfx::opSetStrokeColorN(Object args[], int numArgs) { state->setStrokeColor(&color); out->updateStrokeColor(state); } + if (numArgs <= 0) { + error(errSyntaxError, getPos(), "Incorrect number of arguments in 'SCN' command"); + return; + } if (args[numArgs-1].isName() && (pattern = res->lookupPattern(args[numArgs-1].getName(), this))) { state->setStrokePattern(pattern);