diff --git a/poppler/JBIG2Stream.cc b/poppler/JBIG2Stream.cc index 7ddcc81..04f111b 100644 --- a/poppler/JBIG2Stream.cc +++ b/poppler/JBIG2Stream.cc @@ -584,6 +584,9 @@ int JBIG2MMRDecoder::getBlackCode() { } else { code = buf >> (bufLen - 12); } + if ((code & 0xff) < 64) { + break; + } p = &blackTab2[(code & 0xff) - 64]; } else { if (bufLen <= 6) { @@ -712,13 +715,20 @@ JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, int wA, int hA): return; } // need to allocate one extra guard byte for use in combine() - data = (Guchar *)gmalloc(h * line + 1); - data[h * line] = 0; + data = (Guchar *)gmalloc_checkoverflow(h * line + 1); + if (data != NULL) { + data[h * line] = 0; + } } JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap): JBIG2Segment(segNumA) { + if (bitmap == NULL) { + error(errSyntaxError, -1, "invalid bitmap"); + data = NULL; + return; + } w = bitmap->w; h = bitmap->h; line = bitmap->line; @@ -1814,6 +1824,10 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, goto syntaxError; } refBitmap = bitmaps[symID]; + if (refBitmap == NULL) { + error(errSyntaxError, curStr->getPos(), "Invalid symbol ID in JBIG2 symbol dictionary"); + goto syntaxError; + } bitmaps[numInputSyms + i] = readGenericRefinementRegion(symWidth, symHeight, sdrTemplate, gFalse, @@ -1849,6 +1863,10 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, collBitmap = new JBIG2Bitmap(0, totalWidth, symHeight); bmSize = symHeight * ((totalWidth + 7) >> 3); p = collBitmap->getDataPtr(); + if (p == NULL) { + delete collBitmap; + goto syntaxError; + } for (k = 0; k < (Guint)bmSize; ++k) { if ((c = curStr->getChar()) == EOF) { break; @@ -2198,6 +2216,7 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, symCodeTab[i++].prefixLen = 0; } } else if (j > 0x100) { + if (i == 0) ++i; for (j -= 0x100; j && i < numSyms; --j) { symCodeTab[i].prefixLen = symCodeTab[i-1].prefixLen; ++i; @@ -2365,6 +2384,11 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine, if (symID >= (Guint)numSyms) { error(errSyntaxError, curStr->getPos(), "Invalid symbol number in JBIG2 text region"); + if (numInstances - inst > 0x800) { + // don't loop too often with damaged JBIg2 streams + delete bitmap; + return NULL; + } } else { // get the symbol bitmap @@ -2416,8 +2440,24 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine, //~ something is wrong here - refCorner shouldn't degenerate into //~ two cases bw = symbolBitmap->getWidth() - 1; + if (symbolBitmap->getHeight() == 0) { + error(errSyntaxError, curStr->getPos(), "Invalid symbol bitmap height"); + if (ri) { + delete symbolBitmap; + } + delete bitmap; + return NULL; + } bh = symbolBitmap->getHeight() - 1; if (transposed) { + if (s > 2 * bitmap->getHeight()) { + error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine"); + if (ri) { + delete symbolBitmap; + } + delete bitmap; + return NULL; + } switch (refCorner) { case 0: // bottom left bitmap->combine(symbolBitmap, tt, s, combOp); @@ -2432,19 +2472,51 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine, bitmap->combine(symbolBitmap, tt - bw, s, combOp); break; } - s += bh; + s += bh; } else { switch (refCorner) { case 0: // bottom left + if (tt - (int) bh > 2 * bitmap->getHeight()) { + error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine"); + if (ri) { + delete symbolBitmap; + } + delete bitmap; + return NULL; + } bitmap->combine(symbolBitmap, s, tt - bh, combOp); break; case 1: // top left + if (tt > 2 * bitmap->getHeight()) { + error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine"); + if (ri) { + delete symbolBitmap; + } + delete bitmap; + return NULL; + } bitmap->combine(symbolBitmap, s, tt, combOp); break; case 2: // bottom right + if (tt - (int) bh > 2 * bitmap->getHeight()) { + error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine"); + if (ri) { + delete symbolBitmap; + } + delete bitmap; + return NULL; + } bitmap->combine(symbolBitmap, s, tt - bh, combOp); break; case 3: // top right + if (tt > 2 * bitmap->getHeight()) { + error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine"); + if (ri) { + delete symbolBitmap; + } + delete bitmap; + return NULL; + } bitmap->combine(symbolBitmap, s, tt, combOp); break; } @@ -3127,7 +3199,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, atx[2] >= -8 && atx[2] <= 8 && atx[3] >= -8 && atx[3] <= 8) { // set up the adaptive context - if (y + aty[0] >= 0) { + if (y + aty[0] >= 0 && y + aty[0] < bitmap->getHeight()) { atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize(); atBuf0 = *atP0++ << 8; } else { @@ -3135,7 +3207,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, atBuf0 = 0; } atShift0 = 15 - atx[0]; - if (y + aty[1] >= 0) { + if (y + aty[1] >= 0 && y + aty[1] < bitmap->getHeight()) { atP1 = bitmap->getDataPtr() + (y + aty[1]) * bitmap->getLineSize(); atBuf1 = *atP1++ << 8; } else { @@ -3143,7 +3215,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, atBuf1 = 0; } atShift1 = 15 - atx[1]; - if (y + aty[2] >= 0) { + if (y + aty[2] >= 0 && y + aty[2] < bitmap->getHeight()) { atP2 = bitmap->getDataPtr() + (y + aty[2]) * bitmap->getLineSize(); atBuf2 = *atP2++ << 8; } else { @@ -3151,7 +3223,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, atBuf2 = 0; } atShift2 = 15 - atx[2]; - if (y + aty[3] >= 0) { + if (y + aty[3] >= 0 && y + aty[3] < bitmap->getHeight()) { atP3 = bitmap->getDataPtr() + (y + aty[3]) * bitmap->getLineSize(); atBuf3 = *atP3++ << 8; } else { @@ -3670,7 +3742,7 @@ void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm, refBitmap, 0, 0, atx, aty); // combine the region bitmap into the page bitmap - if (imm) { + if (imm && bitmap) { pageBitmap->combine(bitmap, x, y, extCombOp); delete bitmap;