[poppler] Branch 'xpdf303merge' - poppler/JBIG2Stream.cc poppler/JBIG2Stream.h

Albert Astals Cid aacid at kemper.freedesktop.org
Mon Sep 5 11:48:46 PDT 2011


 poppler/JBIG2Stream.cc |   91 +++++++++++++++++++++++++++----------------------
 poppler/JBIG2Stream.h  |    1 
 2 files changed, 52 insertions(+), 40 deletions(-)

New commits:
commit b36d150931cd555b84ee996d505e8b91e2afde19
Author: Albert Astals Cid <aacid at kde.org>
Date:   Mon Sep 5 20:52:05 2011 +0200

    xpdf303: Take xpdf way of handling bug 6500

diff --git a/poppler/JBIG2Stream.cc b/poppler/JBIG2Stream.cc
index 0f3c4d8..fe908f4 100644
--- a/poppler/JBIG2Stream.cc
+++ b/poppler/JBIG2Stream.cc
@@ -326,15 +326,20 @@ public:
   // Sort the table by prefix length and assign prefix values.
   void buildTable(JBIG2HuffmanTable *table, Guint len);
 
+  void resetByteCounter() { byteCounter = 0; }
+  Guint getByteCounter() { return byteCounter; }
+
 private:
 
   Stream *str;
   Guint buf;
   Guint bufLen;
+  Guint byteCounter;
 };
 
 JBIG2HuffmanDecoder::JBIG2HuffmanDecoder() {
   str = NULL;
+  byteCounter = 0;
   reset();
 }
 
@@ -389,10 +394,12 @@ Guint JBIG2HuffmanDecoder::readBits(Guint n) {
     bufLen = 0;
     while (nLeft >= 8) {
       x = (x << 8) | (str->getChar() & 0xff);
+      ++byteCounter;
       nLeft -= 8;
     }
     if (nLeft > 0) {
       buf = str->getChar();
+      ++byteCounter;
       bufLen = 8 - nLeft;
       x = (x << nLeft) | ((buf >> bufLen) & ((1 << nLeft) - 1));
     }
@@ -403,6 +410,7 @@ Guint JBIG2HuffmanDecoder::readBits(Guint n) {
 Guint JBIG2HuffmanDecoder::readBit() {
   if (bufLen == 0) {
     buf = str->getChar();
+    ++byteCounter;
     bufLen = 8;
   }
   --bufLen;
@@ -466,6 +474,8 @@ public:
   int getBlackCode();
   int getWhiteCode();
   Guint get24Bits();
+  void resetByteCounter() { byteCounter = 0; }
+  Guint getByteCounter() { return byteCounter; }
   void skipTo(Guint length);
 
 private:
@@ -474,10 +484,12 @@ private:
   Guint buf;
   Guint bufLen;
   Guint nBytesRead;
+  Guint byteCounter;
 };
 
 JBIG2MMRDecoder::JBIG2MMRDecoder() {
   str = NULL;
+  byteCounter = 0;
   reset();
 }
 
@@ -497,6 +509,7 @@ int JBIG2MMRDecoder::get2DCode() {
     buf = str->getChar() & 0xff;
     bufLen = 8;
     ++nBytesRead;
+    ++byteCounter;
     p = &twoDimTab1[(buf >> 1) & 0x7f];
   } else if (bufLen == 8) {
     p = &twoDimTab1[(buf >> 1) & 0x7f];
@@ -506,6 +519,7 @@ int JBIG2MMRDecoder::get2DCode() {
       buf = (buf << 8) | (str->getChar() & 0xff);
       bufLen += 8;
       ++nBytesRead;
+      ++byteCounter;
       p = &twoDimTab1[(buf >> (bufLen - 7)) & 0x7f];
     }
   }
@@ -525,6 +539,7 @@ int JBIG2MMRDecoder::getWhiteCode() {
     buf = str->getChar() & 0xff;
     bufLen = 8;
     ++nBytesRead;
+    ++byteCounter;
   }
   while (1) {
     if (bufLen >= 11 && ((buf >> (bufLen - 7)) & 0x7f) == 0) {
@@ -552,6 +567,7 @@ int JBIG2MMRDecoder::getWhiteCode() {
     buf = (buf << 8) | (str->getChar() & 0xff);
     bufLen += 8;
     ++nBytesRead;
+    ++byteCounter;
   }
   error(errSyntaxError, str->getPos(), "Bad white code in JBIG2 MMR stream");
   // eat a bit and return a positive number so that the caller doesn't
@@ -568,6 +584,7 @@ int JBIG2MMRDecoder::getBlackCode() {
     buf = str->getChar() & 0xff;
     bufLen = 8;
     ++nBytesRead;
+    ++byteCounter;
   }
   while (1) {
     if (bufLen >= 10 && ((buf >> (bufLen - 6)) & 0x3f) == 0) {
@@ -1284,7 +1301,6 @@ void JBIG2Stream::readSegments() {
   Guint segNum, segFlags, segType, page, segLength;
   Guint refFlags, nRefSegs;
   Guint *refSegs;
-  int segDataPos;
   int c1, c2, c3;
   Guint i;
 
@@ -1354,9 +1370,6 @@ void JBIG2Stream::readSegments() {
       goto eofError2;
     }
 
-    // keep track of the start of the segment data 
-    segDataPos = curStr->getPos();
-
     // check for missing page information segment
     if (!pageBitmap && ((segType >= 4 && segType <= 7) ||
 			(segType >= 20 && segType <= 43))) {
@@ -1365,6 +1378,10 @@ void JBIG2Stream::readSegments() {
     }
 
     // read the segment data
+    arithDecoder->resetByteCounter();
+    huffDecoder->resetByteCounter();
+    mmrDecoder->resetByteCounter();
+    byteCounter = 0;
     switch (segType) {
     case 0:
       if (!readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs)) {
@@ -1441,45 +1458,30 @@ void JBIG2Stream::readSegments() {
       break;
     }
 
-    // Make sure the segment handler read all of the bytes in the 
-    // segment data, unless this segment is marked as having an
-    // unknown length (section 7.2.7 of the JBIG2 Final Committee Draft)
-
-    if (segLength != 0xffffffff) {
-
-      int segExtraBytes = segDataPos + segLength - curStr->getPos();
-      if (segExtraBytes > 0) {
-
-	// If we didn't read all of the bytes in the segment data,
-	// indicate an error, and throw away the rest of the data.
-	
-	// v.3.1.01.13 of the LuraTech PDF Compressor Server will
-	// sometimes generate an extraneous NULL byte at the end of
-	// arithmetic-coded symbol dictionary segments when numNewSyms
-	// == 0.  Segments like this often occur for blank pages.
-	
-	error(errSyntaxError, curStr->getPos(), "{0:d} extraneous byte{1:s} after segment",
-	      segExtraBytes, (segExtraBytes > 1) ? "s" : "");
-	
-	// Burn through the remaining bytes -- inefficient, but
-	// hopefully we're not doing this much
-	
-	int trash;
-	for (int i = segExtraBytes; i > 0; i--) {
-	  readByte(&trash);
+    // skip any unused data at the end of the segment
+    // (except for immediate generic region segments which have
+    // 0xffffffff = unspecified length)
+    if (!(segType == 38 && segLength == 0xffffffff)) {
+      byteCounter += arithDecoder->getByteCounter();
+      byteCounter += huffDecoder->getByteCounter();
+      byteCounter += mmrDecoder->getByteCounter();
+      // do a sanity check on byteCounter vs segLength -- if there is
+      // a problem, abort the decode
+      if (byteCounter > segLength ||
+	  segLength - byteCounter > 65536) {
+	error(errSyntaxError, getPos(),
+	      "Invalid segment length in JBIG2 stream");
+	gfree(refSegs);
+	break;
+      }
+      while (byteCounter < segLength) {
+	if (curStr->getChar() == EOF) {
+	  break;
 	}
-	
-      } else if (segExtraBytes < 0) {
-	
-	// If we read more bytes than we should have, according to the 
-	// segment length field, note an error.
-	
-	error(errSyntaxError, curStr->getPos(), "Previous segment handler read too many bytes");
-	
+	++byteCounter;
       }
-
     }
-    
+
     gfree(refSegs);
   }
 
@@ -1832,6 +1834,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
 	    break;
 	  }
 	  *p++ = (Guchar)c;
+	  ++byteCounter;
 	}
       } else {
 	collBitmap = readGenericBitmap(gTrue, totalWidth, symHeight,
@@ -3882,6 +3885,7 @@ void JBIG2Stream::readEndOfStripeSeg(Guint length) {
     if (curStr->getChar() == EOF) {
       break;
     }
+    ++byteCounter;
   }
 }
 
@@ -3893,6 +3897,7 @@ void JBIG2Stream::readProfilesSeg(Guint length) {
     if (curStr->getChar() == EOF) {
       break;
     }
+    ++byteCounter;
   }
 }
 
@@ -3968,6 +3973,7 @@ void JBIG2Stream::readExtensionSeg(Guint length) {
     if (curStr->getChar() == EOF) {
       break;
     }
+    ++byteCounter;
   }
 }
 
@@ -4082,6 +4088,7 @@ GBool JBIG2Stream::readUByte(Guint *x) {
   if ((c0 = curStr->getChar()) == EOF) {
     return gFalse;
   }
+  ++byteCounter;
   *x = (Guint)c0;
   return gTrue;
 }
@@ -4092,6 +4099,7 @@ GBool JBIG2Stream::readByte(int *x) {
   if ((c0 = curStr->getChar()) == EOF) {
     return gFalse;
   }
+  ++byteCounter;
   *x = c0;
   if (c0 & 0x80) {
     *x |= -1 - 0xff;
@@ -4106,6 +4114,7 @@ GBool JBIG2Stream::readUWord(Guint *x) {
       (c1 = curStr->getChar()) == EOF) {
     return gFalse;
   }
+  byteCounter += 2;
   *x = (Guint)((c0 << 8) | c1);
   return gTrue;
 }
@@ -4119,6 +4128,7 @@ GBool JBIG2Stream::readULong(Guint *x) {
       (c3 = curStr->getChar()) == EOF) {
     return gFalse;
   }
+  byteCounter += 4;
   *x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
   return gTrue;
 }
@@ -4132,6 +4142,7 @@ GBool JBIG2Stream::readLong(int *x) {
       (c3 = curStr->getChar()) == EOF) {
     return gFalse;
   }
+  byteCounter += 4;
   *x = ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
   if (c0 & 0x80) {
     *x |= -1 - (int)0xffffffff;
diff --git a/poppler/JBIG2Stream.h b/poppler/JBIG2Stream.h
index 504ecea..04b3b1f 100644
--- a/poppler/JBIG2Stream.h
+++ b/poppler/JBIG2Stream.h
@@ -137,6 +137,7 @@ private:
   Stream *curStr;
   Guchar *dataPtr;
   Guchar *dataEnd;
+  Guint byteCounter;
 
   JArithmeticDecoder *arithDecoder;
   JArithmeticDecoderStats *genericRegionStats;


More information about the poppler mailing list