diff options
author | David Benjamin <davidben@mit.edu> | 2009-06-19 00:30:35 +0200 |
---|---|---|
committer | Albert Astals Cid <aacid@kde.org> | 2009-06-19 00:34:39 +0200 |
commit | 47de8eef46300832556ce5ed869e391e477fd843 (patch) | |
tree | ae033633c4f260246f7bd13cbec35acd21aa6df4 | |
parent | d30b1013ea3ce45b5ea942fe7357c0fd07ff47f4 (diff) |
Fix some bugs in JBIG2Stream handling
For more info see bug 12014 and [poppler] Bug in JBIG2Stream from 08-June-2009
-rw-r--r-- | poppler/JBIG2Stream.cc | 88 | ||||
-rw-r--r-- | poppler/JBIG2Stream.h | 15 |
2 files changed, 63 insertions, 40 deletions
diff --git a/poppler/JBIG2Stream.cc b/poppler/JBIG2Stream.cc index 57ec42b3..fec0e2d8 100644 --- a/poppler/JBIG2Stream.cc +++ b/poppler/JBIG2Stream.cc @@ -16,6 +16,7 @@ // Copyright (C) 2006 Raj Kumar <rkumar@archive.org> // Copyright (C) 2006 Paul Walmsley <paul@booyaka.com> // Copyright (C) 2006-2009 Albert Astals Cid <aacid@kde.org> +// Copyright (C) 2009 David Benjamin <davidben@mit.edu> // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -1252,6 +1253,13 @@ int JBIG2Stream::lookChar() { return EOF; } +int JBIG2Stream::getPos() { + if (pageBitmap == NULL) { + return 0; + } + return dataPtr - pageBitmap->getDataPtr(); +} + GooString *JBIG2Stream::getPSFilter(int psLevel, char *indent) { return NULL; } @@ -1333,12 +1341,12 @@ void JBIG2Stream::readSegments() { } // keep track of the start of the segment data - segDataPos = getPos(); + segDataPos = curStr->getPos(); // check for missing page information segment if (!pageBitmap && ((segType >= 4 && segType <= 7) || (segType >= 20 && segType <= 43))) { - error(getPos(), "First JBIG2 segment associated with a page must be a page information segment"); + error(curStr->getPos(), "First JBIG2 segment associated with a page must be a page information segment"); goto syntaxError; } @@ -1410,7 +1418,7 @@ void JBIG2Stream::readSegments() { readExtensionSeg(segLength); break; default: - error(getPos(), "Unknown segment type in JBIG2 stream"); + error(curStr->getPos(), "Unknown segment type in JBIG2 stream"); for (i = 0; i < segLength; ++i) { if ((c1 = curStr->getChar()) == EOF) { goto eofError2; @@ -1425,7 +1433,7 @@ void JBIG2Stream::readSegments() { if (segLength != 0xffffffff) { - int segExtraBytes = segDataPos + segLength - getPos(); + int segExtraBytes = segDataPos + segLength - curStr->getPos(); if (segExtraBytes > 0) { // If we didn't read all of the bytes in the segment data, @@ -1436,7 +1444,7 @@ void JBIG2Stream::readSegments() { // arithmetic-coded symbol dictionary segments when numNewSyms // == 0. Segments like this often occur for blank pages. - error(getPos(), "%d extraneous byte%s after segment", + error(curStr->getPos(), "%d extraneous byte%s after segment", segExtraBytes, (segExtraBytes > 1) ? "s" : ""); // Burn through the remaining bytes -- inefficient, but @@ -1452,7 +1460,7 @@ void JBIG2Stream::readSegments() { // If we read more bytes than we should have, according to the // segment length field, note an error. - error(getPos(), "Previous segment handler read too many bytes"); + error(curStr->getPos(), "Previous segment handler read too many bytes"); } @@ -1470,7 +1478,7 @@ void JBIG2Stream::readSegments() { eofError2: gfree(refSegs); eofError1: - error(getPos(), "Unexpected EOF in JBIG2 stream"); + error(curStr->getPos(), "Unexpected EOF in JBIG2 stream"); } GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, @@ -1560,7 +1568,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, if (seg->getType() == jbig2SegSymbolDict) { j = ((JBIG2SymbolDict *)seg)->getSize(); if (numInputSyms > UINT_MAX - j) { - error(getPos(), "Too many input symbols in JBIG2 symbol dictionary"); + error(curStr->getPos(), "Too many input symbols in JBIG2 symbol dictionary"); delete codeTables; goto eofError; } @@ -1574,7 +1582,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, } } if (numInputSyms > UINT_MAX - numNewSyms) { - error(getPos(), "Too many input symbols in JBIG2 symbol dictionary"); + error(curStr->getPos(), "Too many input symbols in JBIG2 symbol dictionary"); delete codeTables; goto eofError; } @@ -1692,7 +1700,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, arithDecoder->decodeInt(&dh, iadhStats); } if (dh < 0 && (Guint)-dh >= symHeight) { - error(getPos(), "Bad delta-height value in JBIG2 symbol dictionary"); + error(curStr->getPos(), "Bad delta-height value in JBIG2 symbol dictionary"); goto syntaxError; } symHeight += dh; @@ -1714,12 +1722,12 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, } } if (dw < 0 && (Guint)-dw >= symWidth) { - error(getPos(), "Bad delta-height value in JBIG2 symbol dictionary"); + error(curStr->getPos(), "Bad delta-height value in JBIG2 symbol dictionary"); goto syntaxError; } symWidth += dw; if (i >= numNewSyms) { - error(getPos(), "Too many symbols in JBIG2 symbol dictionary"); + error(curStr->getPos(), "Too many symbols in JBIG2 symbol dictionary"); goto syntaxError; } @@ -1759,7 +1767,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, arithDecoder->decodeInt(&refDY, iardyStats); } if (symID >= numInputSyms + i) { - error(getPos(), "Invalid symbol ID in JBIG2 symbol dictionary"); + error(curStr->getPos(), "Invalid symbol ID in JBIG2 symbol dictionary"); goto syntaxError; } refBitmap = bitmaps[symID]; @@ -1834,7 +1842,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, } if (i + run > numInputSyms + numNewSyms || (ex && j + run > numExSyms)) { - error(getPos(), "Too many exported symbols in JBIG2 symbol dictionary"); + error(curStr->getPos(), "Too many exported symbols in JBIG2 symbol dictionary"); for ( ; j < numExSyms; ++j) symbolDict->setBitmap(j, NULL); delete symbolDict; goto syntaxError; @@ -1849,7 +1857,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, ex = !ex; } if (j != numExSyms) { - error(getPos(), "Too few symbols in JBIG2 symbol dictionary"); + error(curStr->getPos(), "Too few symbols in JBIG2 symbol dictionary"); for ( ; j < numExSyms; ++j) symbolDict->setBitmap(j, NULL); delete symbolDict; goto syntaxError; @@ -1877,7 +1885,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, return gTrue; codeTableError: - error(getPos(), "Missing code table in JBIG2 symbol dictionary"); + error(curStr->getPos(), "Missing code table in JBIG2 symbol dictionary"); delete codeTables; syntaxError: @@ -1893,7 +1901,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length, return gFalse; eofError: - error(getPos(), "Unexpected EOF in JBIG2 stream"); + error(curStr->getPos(), "Unexpected EOF in JBIG2 stream"); return gFalse; } @@ -1981,7 +1989,7 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, codeTables->append(seg); } } else { - error(getPos(), "Invalid segment reference in JBIG2 text region"); + error(curStr->getPos(), "Invalid segment reference in JBIG2 text region"); delete codeTables; return; } @@ -2190,13 +2198,13 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm, return; codeTableError: - error(getPos(), "Missing code table in JBIG2 text region"); + error(curStr->getPos(), "Missing code table in JBIG2 text region"); gfree(codeTables); delete syms; return; eofError: - error(getPos(), "Unexpected EOF in JBIG2 stream"); + error(curStr->getPos(), "Unexpected EOF in JBIG2 stream"); return; } @@ -2297,7 +2305,7 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine, } if (symID >= (Guint)numSyms) { - error(getPos(), "Invalid symbol number in JBIG2 text region"); + error(curStr->getPos(), "Invalid symbol number in JBIG2 text region"); } else { // get the symbol bitmap @@ -2464,7 +2472,7 @@ void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) { return; eofError: - error(getPos(), "Unexpected EOF in JBIG2 stream"); + error(curStr->getPos(), "Unexpected EOF in JBIG2 stream"); } void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm, @@ -2506,22 +2514,22 @@ void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm, goto eofError; } if (w == 0 || h == 0 || w >= INT_MAX / h) { - error(getPos(), "Bad bitmap size in JBIG2 halftone segment"); + error(curStr->getPos(), "Bad bitmap size in JBIG2 halftone segment"); return; } if (gridH == 0 || gridW >= INT_MAX / gridH) { - error(getPos(), "Bad grid size in JBIG2 halftone segment"); + error(curStr->getPos(), "Bad grid size in JBIG2 halftone segment"); return; } // get pattern dictionary if (nRefSegs != 1) { - error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment"); + error(curStr->getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment"); return; } seg = findSegment(refSegs[0]); if (seg == NULL || seg->getType() != jbig2SegPatternDict) { - error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment"); + error(curStr->getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment"); return; } @@ -2624,7 +2632,7 @@ void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm, return; eofError: - error(getPos(), "Unexpected EOF in JBIG2 stream"); + error(curStr->getPos(), "Unexpected EOF in JBIG2 stream"); } void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm, @@ -2700,14 +2708,14 @@ void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm, return; eofError: - error(getPos(), "Unexpected EOF in JBIG2 stream"); + error(curStr->getPos(), "Unexpected EOF in JBIG2 stream"); } inline void JBIG2Stream::mmrAddPixels(int a1, int blackPixels, int *codingLine, int *a0i, int w) { if (a1 > codingLine[*a0i]) { if (a1 > w) { - error(getPos(), "JBIG2 MMR row is wrong length (%d)", a1); + error(curStr->getPos(), "JBIG2 MMR row is wrong length (%d)", a1); a1 = w; } if ((*a0i & 1) ^ blackPixels) { @@ -2721,7 +2729,7 @@ inline void JBIG2Stream::mmrAddPixelsNeg(int a1, int blackPixels, int *codingLine, int *a0i, int w) { if (a1 > codingLine[*a0i]) { if (a1 > w) { - error(getPos(), "JBIG2 MMR row is wrong length (%d)", a1); + error(curStr->getPos(), "JBIG2 MMR row is wrong length (%d)", a1); a1 = w; } if ((*a0i & 1) ^ blackPixels) { @@ -2730,7 +2738,7 @@ inline void JBIG2Stream::mmrAddPixelsNeg(int a1, int blackPixels, codingLine[*a0i] = a1; } else if (a1 < codingLine[*a0i]) { if (a1 < 0) { - error(getPos(), "Invalid JBIG2 MMR code"); + error(curStr->getPos(), "Invalid JBIG2 MMR code"); a1 = 0; } while (*a0i > 0 && a1 <= codingLine[*a0i - 1]) { @@ -2767,7 +2775,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, mmrDecoder->reset(); if (w > INT_MAX - 2) { - error(getPos(), "Bad width in JBIG2 generic bitmap"); + error(curStr->getPos(), "Bad width in JBIG2 generic bitmap"); // force a call to gmalloc(-1), which will throw an exception w = -3; } @@ -2777,7 +2785,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, // ---> max refLine size = w + 2 codingLine = (int *)gmallocn(w + 1, sizeof(int)); refLine = (int *)gmallocn(w + 2, sizeof(int)); - codingLine[0] = w; + for (i = 0; i < w + 1; ++i) codingLine[i] = w; for (y = 0; y < h; ++y) { @@ -2921,7 +2929,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, mmrAddPixels(w, 0, codingLine, &a0i, w); break; default: - error(getPos(), "Illegal code in JBIG2 MMR bitmap data"); + error(curStr->getPos(), "Illegal code in JBIG2 MMR bitmap data"); mmrAddPixels(w, 0, codingLine, &a0i, w); break; } @@ -2944,7 +2952,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h, mmrDecoder->skipTo(mmrDataLength); } else { if (mmrDecoder->get24Bits() != 0x001001) { - error(getPos(), "Missing EOFB in JBIG2 MMR bitmap data"); + error(curStr->getPos(), "Missing EOFB in JBIG2 MMR bitmap data"); } } @@ -3184,13 +3192,13 @@ void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm, // get referenced bitmap if (nRefSegs > 1) { - error(getPos(), "Bad reference in JBIG2 generic refinement segment"); + error(curStr->getPos(), "Bad reference in JBIG2 generic refinement segment"); return; } if (nRefSegs == 1) { seg = findSegment(refSegs[0]); if (seg == NULL || seg->getType() != jbig2SegBitmap) { - error(getPos(), "Bad bitmap reference in JBIG2 generic refinement segment"); + error(curStr->getPos(), "Bad bitmap reference in JBIG2 generic refinement segment"); return; } refBitmap = (JBIG2Bitmap *)seg; @@ -3227,7 +3235,7 @@ void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm, return; eofError: - error(getPos(), "Unexpected EOF in JBIG2 stream"); + error(curStr->getPos(), "Unexpected EOF in JBIG2 stream"); } JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h, @@ -3456,7 +3464,7 @@ void JBIG2Stream::readPageInfoSeg(Guint length) { return; eofError: - error(getPos(), "Unexpected EOF in JBIG2 stream"); + error(curStr->getPos(), "Unexpected EOF in JBIG2 stream"); } void JBIG2Stream::readEndOfStripeSeg(Guint length) { @@ -3538,7 +3546,7 @@ void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint length) { return; eofError: - error(getPos(), "Unexpected EOF in JBIG2 stream"); + error(curStr->getPos(), "Unexpected EOF in JBIG2 stream"); } void JBIG2Stream::readExtensionSeg(Guint length) { diff --git a/poppler/JBIG2Stream.h b/poppler/JBIG2Stream.h index ca1fee7f..23d3d92d 100644 --- a/poppler/JBIG2Stream.h +++ b/poppler/JBIG2Stream.h @@ -6,6 +6,20 @@ // //======================================================================== +//======================================================================== +// +// Modified under the Poppler project - http://poppler.freedesktop.org +// +// All changes made under the Poppler project to this file are licensed +// under GPL version 2 or later +// +// Copyright (C) 2009 David Benjamin <davidben@mit.edu> +// +// To see a description of the changes please see the Changelog file that +// came with your tarball or type make ChangeLog if you are building from git +// +//======================================================================== + #ifndef JBIG2STREAM_H #define JBIG2STREAM_H @@ -36,6 +50,7 @@ public: virtual StreamKind getKind() { return strJBIG2; } virtual void reset(); virtual void close(); + virtual int getPos(); virtual int getChar(); virtual int lookChar(); virtual GooString *getPSFilter(int psLevel, char *indent); |