X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=pdf2swf%2Fxpdf%2FJBIG2Stream.cc;fp=pdf2swf%2Fxpdf%2FJBIG2Stream.cc;h=a90db80cbe640b038573ee2f1ce02c27ea9b0cea;hb=85c46a8011c7fd5e4bda282266006c972ea7606b;hp=c1bf4f78d0433bd9133e35d6a317de6824be1f0f;hpb=b0d012f83219d898e9cd92281d9996bc9ff13b5f;p=swftools.git diff --git a/pdf2swf/xpdf/JBIG2Stream.cc b/pdf2swf/xpdf/JBIG2Stream.cc index c1bf4f7..a90db80 100644 --- a/pdf2swf/xpdf/JBIG2Stream.cc +++ b/pdf2swf/xpdf/JBIG2Stream.cc @@ -681,7 +681,9 @@ JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, int wA, int hA): w = wA; h = hA; line = (wA + 7) >> 3; - data = (Guchar *)gmalloc(h * line); + // need to allocate one extra guard byte for use in combine() + data = (Guchar *)gmalloc(h * line + 1); + data[h * line] = 0; } JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap): @@ -690,8 +692,10 @@ JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap): w = bitmap->w; h = bitmap->h; line = bitmap->line; - data = (Guchar *)gmalloc(h * line); + // need to allocate one extra guard byte for use in combine() + data = (Guchar *)gmalloc(h * line + 1); memcpy(data, bitmap->data, h * line); + data[h * line] = 0; } JBIG2Bitmap::~JBIG2Bitmap() { @@ -719,13 +723,15 @@ void JBIG2Bitmap::expand(int newH, Guint pixel) { if (newH <= h) { return; } - data = (Guchar *)grealloc(data, newH * line); + // need to allocate one extra guard byte for use in combine() + data = (Guchar *)grealloc(data, newH * line + 1); if (pixel) { memset(data + h * line, 0xff, (newH - h) * line); } else { memset(data + h * line, 0x00, (newH - h) * line); } h = newH; + data[h * line] = 0; } void JBIG2Bitmap::clearToZero() { @@ -933,6 +939,10 @@ void JBIG2Bitmap::combine(JBIG2Bitmap *bitmap, int x, int y, } // right-most byte + // note: this last byte (src1) may not actually be used, depending + // on the values of s1, m1, and m2 - and in fact, it may be off + // the edge of the source bitmap, which means we need to allocate + // one extra guard byte at the end of each bitmap dest = *destPtr; src0 = src1; src1 = *srcPtr++; @@ -993,7 +1003,7 @@ JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA): JBIG2Segment(segNumA) { size = sizeA; - bitmaps = (JBIG2Bitmap **)gmalloc(size * sizeof(JBIG2Bitmap *)); + bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *)); genericRegionStats = NULL; refinementRegionStats = NULL; } @@ -1037,7 +1047,7 @@ JBIG2PatternDict::JBIG2PatternDict(Guint segNumA, Guint sizeA): JBIG2Segment(segNumA) { size = sizeA; - bitmaps = (JBIG2Bitmap **)gmalloc(size * sizeof(JBIG2Bitmap *)); + bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *)); } JBIG2PatternDict::~JBIG2PatternDict() { @@ -1233,7 +1243,7 @@ void JBIG2Stream::readSegments() { } // referred-to segment numbers - refSegs = (Guint *)gmalloc(nRefSegs * sizeof(Guint)); + refSegs = (Guint *)gmallocn(nRefSegs, sizeof(Guint)); if (segNum <= 256) { for (i = 0; i < nRefSegs; ++i) { if (!readUByte(&refSegs[i])) { @@ -1273,7 +1283,9 @@ void JBIG2Stream::readSegments() { // read the segment data switch (segType) { case 0: - readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs); + if (!readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs)) { + goto syntaxError; + } break; case 4: readTextRegionSeg(segNum, gFalse, gFalse, segLength, refSegs, nRefSegs); @@ -1350,14 +1362,18 @@ void JBIG2Stream::readSegments() { return; + syntaxError: + gfree(refSegs); + return; + eofError2: gfree(refSegs); eofError1: error(getPos(), "Unexpected EOF in JBIG2 stream"); } -void JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, - Guint *refSegs, Guint nRefSegs) { +GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, + Guint *refSegs, Guint nRefSegs) { JBIG2SymbolDict *symbolDict; JBIG2HuffmanTable *huffDHTable, *huffDWTable; JBIG2HuffmanTable *huffBMSizeTable, *huffAggInstTable; @@ -1451,8 +1467,11 @@ void JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, } // get the input symbol bitmaps - bitmaps = (JBIG2Bitmap **)gmalloc((numInputSyms + numNewSyms) * - sizeof(JBIG2Bitmap *)); + bitmaps = (JBIG2Bitmap **)gmallocn(numInputSyms + numNewSyms, + sizeof(JBIG2Bitmap *)); + for (i = 0; i < numInputSyms + numNewSyms; ++i) { + bitmaps[i] = NULL; + } k = 0; inputSymbolDict = NULL; for (i = 0; i < nRefSegs; ++i) { @@ -1527,7 +1546,7 @@ void JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, // allocate symbol widths storage symWidths = NULL; if (huff && !refAgg) { - symWidths = (Guint *)gmalloc(numNewSyms * sizeof(Guint)); + symWidths = (Guint *)gmallocn(numNewSyms, sizeof(Guint)); } symHeight = 0; @@ -1540,6 +1559,10 @@ void JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, } else { arithDecoder->decodeInt(&dh, iadhStats); } + if (dh < 0 && (Guint)-dh >= symHeight) { + error(getPos(), "Bad delta-height value in JBIG2 symbol dictionary"); + goto syntaxError; + } symHeight += dh; symWidth = 0; totalWidth = 0; @@ -1558,6 +1581,10 @@ void JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, break; } } + if (dw < 0 && (Guint)-dw >= symWidth) { + error(getPos(), "Bad delta-height value in JBIG2 symbol dictionary"); + goto syntaxError; + } symWidth += dw; // using a collective bitmap, so don't read a bitmap here @@ -1690,10 +1717,23 @@ void JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, // store the new symbol dict segments->append(symbolDict); - return; + return gTrue; + + syntaxError: + for (i = 0; i < numNewSyms; ++i) { + if (bitmaps[numInputSyms + i]) { + delete bitmaps[numInputSyms + i]; + } + } + gfree(bitmaps); + if (symWidths) { + gfree(symWidths); + } + return gFalse; eofError: error(getPos(), "Unexpected EOF in JBIG2 stream"); + return gFalse; } void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, @@ -1773,11 +1813,14 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, codeTables = new GList(); numSyms = 0; for (i = 0; i < nRefSegs; ++i) { - seg = findSegment(refSegs[i]); - if (seg->getType() == jbig2SegSymbolDict) { - numSyms += ((JBIG2SymbolDict *)seg)->getSize(); - } else if (seg->getType() == jbig2SegCodeTable) { - codeTables->append(seg); + if ((seg = findSegment(refSegs[i]))) { + if (seg->getType() == jbig2SegSymbolDict) { + numSyms += ((JBIG2SymbolDict *)seg)->getSize(); + } else if (seg->getType() == jbig2SegCodeTable) { + codeTables->append(seg); + } + } else { + error(getPos(), "Invalid segment reference in JBIG2 text region"); } } symCodeLen = 0; @@ -1788,14 +1831,15 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, } // get the symbol bitmaps - syms = (JBIG2Bitmap **)gmalloc(numSyms * sizeof(JBIG2Bitmap *)); + syms = (JBIG2Bitmap **)gmallocn(numSyms, sizeof(JBIG2Bitmap *)); kk = 0; for (i = 0; i < nRefSegs; ++i) { - seg = findSegment(refSegs[i]); - if (seg->getType() == jbig2SegSymbolDict) { - symbolDict = (JBIG2SymbolDict *)seg; - for (k = 0; k < symbolDict->getSize(); ++k) { - syms[kk++] = symbolDict->getBitmap(k); + if ((seg = findSegment(refSegs[i]))) { + if (seg->getType() == jbig2SegSymbolDict) { + symbolDict = (JBIG2SymbolDict *)seg; + for (k = 0; k < symbolDict->getSize(); ++k) { + syms[kk++] = symbolDict->getBitmap(k); + } } } } @@ -1888,8 +1932,8 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, runLengthTab[35].prefixLen = 0; runLengthTab[35].rangeLen = jbig2HuffmanEOT; huffDecoder->buildTable(runLengthTab, 35); - symCodeTab = (JBIG2HuffmanTable *)gmalloc((numSyms + 1) * - sizeof(JBIG2HuffmanTable)); + symCodeTab = (JBIG2HuffmanTable *)gmallocn(numSyms + 1, + sizeof(JBIG2HuffmanTable)); for (i = 0; i < numSyms; ++i) { symCodeTab[i].val = i; symCodeTab[i].rangeLen = 0; @@ -2052,85 +2096,90 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine, symID = arithDecoder->decodeIAID(symCodeLen, iaidStats); } - // get the symbol bitmap - symbolBitmap = NULL; - if (refine) { - if (huff) { - ri = (int)huffDecoder->readBit(); + if (symID >= (Guint)numSyms) { + error(getPos(), "Invalid symbol number in JBIG2 text region"); + } else { + + // get the symbol bitmap + symbolBitmap = NULL; + if (refine) { + if (huff) { + ri = (int)huffDecoder->readBit(); + } else { + arithDecoder->decodeInt(&ri, iariStats); + } } else { - arithDecoder->decodeInt(&ri, iariStats); + ri = 0; } - } else { - ri = 0; - } - if (ri) { - if (huff) { - huffDecoder->decodeInt(&rdw, huffRDWTable); - huffDecoder->decodeInt(&rdh, huffRDHTable); - huffDecoder->decodeInt(&rdx, huffRDXTable); - huffDecoder->decodeInt(&rdy, huffRDYTable); - huffDecoder->decodeInt(&bmSize, huffRSizeTable); - huffDecoder->reset(); - arithDecoder->start(); + if (ri) { + if (huff) { + huffDecoder->decodeInt(&rdw, huffRDWTable); + huffDecoder->decodeInt(&rdh, huffRDHTable); + huffDecoder->decodeInt(&rdx, huffRDXTable); + huffDecoder->decodeInt(&rdy, huffRDYTable); + huffDecoder->decodeInt(&bmSize, huffRSizeTable); + huffDecoder->reset(); + arithDecoder->start(); + } else { + arithDecoder->decodeInt(&rdw, iardwStats); + arithDecoder->decodeInt(&rdh, iardhStats); + arithDecoder->decodeInt(&rdx, iardxStats); + arithDecoder->decodeInt(&rdy, iardyStats); + } + refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx; + refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy; + + symbolBitmap = + readGenericRefinementRegion(rdw + syms[symID]->getWidth(), + rdh + syms[symID]->getHeight(), + templ, gFalse, syms[symID], + refDX, refDY, atx, aty); + //~ do we need to use the bmSize value here (in Huffman mode)? } else { - arithDecoder->decodeInt(&rdw, iardwStats); - arithDecoder->decodeInt(&rdh, iardhStats); - arithDecoder->decodeInt(&rdx, iardxStats); - arithDecoder->decodeInt(&rdy, iardyStats); + symbolBitmap = syms[symID]; } - refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx; - refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy; - - symbolBitmap = - readGenericRefinementRegion(rdw + syms[symID]->getWidth(), - rdh + syms[symID]->getHeight(), - templ, gFalse, syms[symID], - refDX, refDY, atx, aty); - //~ do we need to use the bmSize value here (in Huffman mode)? - } else { - symbolBitmap = syms[symID]; - } - // combine the symbol bitmap into the region bitmap - //~ something is wrong here - refCorner shouldn't degenerate into - //~ two cases - bw = symbolBitmap->getWidth() - 1; - bh = symbolBitmap->getHeight() - 1; - if (transposed) { - switch (refCorner) { - case 0: // bottom left - bitmap->combine(symbolBitmap, tt, s, combOp); - break; - case 1: // top left - bitmap->combine(symbolBitmap, tt, s, combOp); - break; - case 2: // bottom right - bitmap->combine(symbolBitmap, tt - bw, s, combOp); - break; - case 3: // top right - bitmap->combine(symbolBitmap, tt - bw, s, combOp); - break; + // combine the symbol bitmap into the region bitmap + //~ something is wrong here - refCorner shouldn't degenerate into + //~ two cases + bw = symbolBitmap->getWidth() - 1; + bh = symbolBitmap->getHeight() - 1; + if (transposed) { + switch (refCorner) { + case 0: // bottom left + bitmap->combine(symbolBitmap, tt, s, combOp); + break; + case 1: // top left + bitmap->combine(symbolBitmap, tt, s, combOp); + break; + case 2: // bottom right + bitmap->combine(symbolBitmap, tt - bw, s, combOp); + break; + case 3: // top right + bitmap->combine(symbolBitmap, tt - bw, s, combOp); + break; + } + s += bh; + } else { + switch (refCorner) { + case 0: // bottom left + bitmap->combine(symbolBitmap, s, tt - bh, combOp); + break; + case 1: // top left + bitmap->combine(symbolBitmap, s, tt, combOp); + break; + case 2: // bottom right + bitmap->combine(symbolBitmap, s, tt - bh, combOp); + break; + case 3: // top right + bitmap->combine(symbolBitmap, s, tt, combOp); + break; + } + s += bw; } - s += bh; - } else { - switch (refCorner) { - case 0: // bottom left - bitmap->combine(symbolBitmap, s, tt - bh, combOp); - break; - case 1: // top left - bitmap->combine(symbolBitmap, s, tt, combOp); - break; - case 2: // bottom right - bitmap->combine(symbolBitmap, s, tt - bh, combOp); - break; - case 3: // top right - bitmap->combine(symbolBitmap, s, tt, combOp); - break; + if (ri) { + delete symbolBitmap; } - s += bw; - } - if (ri) { - delete symbolBitmap; } // next instance @@ -2298,7 +2347,7 @@ void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm, } // read the gray-scale image - grayImg = (Guint *)gmalloc(gridW * gridH * sizeof(Guint)); + grayImg = (Guint *)gmallocn(gridW * gridH, sizeof(Guint)); memset(grayImg, 0, gridW * gridH * sizeof(Guint)); atx[0] = templ <= 1 ? 3 : 2; aty[0] = -1; atx[1] = -3; aty[1] = -1; @@ -2451,8 +2500,8 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, if (mmr) { mmrDecoder->reset(); - refLine = (int *)gmalloc((w + 2) * sizeof(int)); - codingLine = (int *)gmalloc((w + 2) * sizeof(int)); + refLine = (int *)gmallocn(w + 2, sizeof(int)); + codingLine = (int *)gmallocn(w + 2, sizeof(int)); codingLine[0] = codingLine[1] = w; for (y = 0; y < h; ++y) { @@ -3111,14 +3160,14 @@ void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint length) { huffDecoder->reset(); huffTabSize = 8; huffTab = (JBIG2HuffmanTable *) - gmalloc(huffTabSize * sizeof(JBIG2HuffmanTable)); + gmallocn(huffTabSize, sizeof(JBIG2HuffmanTable)); i = 0; val = lowVal; while (val < highVal) { if (i == huffTabSize) { huffTabSize *= 2; huffTab = (JBIG2HuffmanTable *) - grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable)); + greallocn(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable)); } huffTab[i].val = val; huffTab[i].prefixLen = huffDecoder->readBits(prefixBits); @@ -3129,7 +3178,7 @@ void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint length) { if (i + oob + 3 > huffTabSize) { huffTabSize = i + oob + 3; huffTab = (JBIG2HuffmanTable *) - grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable)); + greallocn(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable)); } huffTab[i].val = lowVal - 1; huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);