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

Albert Astals Cid aacid at kemper.freedesktop.org
Tue Sep 6 12:53:28 PDT 2011


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

New commits:
commit d768204e51e6bdbcac4d6b43537297616cbedbf3
Author: Albert Astals Cid <aacid at kde.org>
Date:   Tue Sep 6 21:56:43 2011 +0200

    xpdf303: Revert b36d150931cd555b84ee996d505e8b91e2afde19
    
    Breaks bug164568-2.pdf so our fix was better :-)

diff --git a/poppler/JBIG2Stream.cc b/poppler/JBIG2Stream.cc
index fe908f4..0f3c4d8 100644
--- a/poppler/JBIG2Stream.cc
+++ b/poppler/JBIG2Stream.cc
@@ -326,20 +326,15 @@ 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();
 }
 
@@ -394,12 +389,10 @@ 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));
     }
@@ -410,7 +403,6 @@ Guint JBIG2HuffmanDecoder::readBits(Guint n) {
 Guint JBIG2HuffmanDecoder::readBit() {
   if (bufLen == 0) {
     buf = str->getChar();
-    ++byteCounter;
     bufLen = 8;
   }
   --bufLen;
@@ -474,8 +466,6 @@ public:
   int getBlackCode();
   int getWhiteCode();
   Guint get24Bits();
-  void resetByteCounter() { byteCounter = 0; }
-  Guint getByteCounter() { return byteCounter; }
   void skipTo(Guint length);
 
 private:
@@ -484,12 +474,10 @@ private:
   Guint buf;
   Guint bufLen;
   Guint nBytesRead;
-  Guint byteCounter;
 };
 
 JBIG2MMRDecoder::JBIG2MMRDecoder() {
   str = NULL;
-  byteCounter = 0;
   reset();
 }
 
@@ -509,7 +497,6 @@ 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];
@@ -519,7 +506,6 @@ int JBIG2MMRDecoder::get2DCode() {
       buf = (buf << 8) | (str->getChar() & 0xff);
       bufLen += 8;
       ++nBytesRead;
-      ++byteCounter;
       p = &twoDimTab1[(buf >> (bufLen - 7)) & 0x7f];
     }
   }
@@ -539,7 +525,6 @@ int JBIG2MMRDecoder::getWhiteCode() {
     buf = str->getChar() & 0xff;
     bufLen = 8;
     ++nBytesRead;
-    ++byteCounter;
   }
   while (1) {
     if (bufLen >= 11 && ((buf >> (bufLen - 7)) & 0x7f) == 0) {
@@ -567,7 +552,6 @@ 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
@@ -584,7 +568,6 @@ int JBIG2MMRDecoder::getBlackCode() {
     buf = str->getChar() & 0xff;
     bufLen = 8;
     ++nBytesRead;
-    ++byteCounter;
   }
   while (1) {
     if (bufLen >= 10 && ((buf >> (bufLen - 6)) & 0x3f) == 0) {
@@ -1301,6 +1284,7 @@ void JBIG2Stream::readSegments() {
   Guint segNum, segFlags, segType, page, segLength;
   Guint refFlags, nRefSegs;
   Guint *refSegs;
+  int segDataPos;
   int c1, c2, c3;
   Guint i;
 
@@ -1370,6 +1354,9 @@ 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))) {
@@ -1378,10 +1365,6 @@ 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)) {
@@ -1458,30 +1441,45 @@ void JBIG2Stream::readSegments() {
       break;
     }
 
-    // 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;
+    // 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);
 	}
-	++byteCounter;
+	
+      } 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");
+	
       }
-    }
 
+    }
+    
     gfree(refSegs);
   }
 
@@ -1834,7 +1832,6 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
 	    break;
 	  }
 	  *p++ = (Guchar)c;
-	  ++byteCounter;
 	}
       } else {
 	collBitmap = readGenericBitmap(gTrue, totalWidth, symHeight,
@@ -3885,7 +3882,6 @@ void JBIG2Stream::readEndOfStripeSeg(Guint length) {
     if (curStr->getChar() == EOF) {
       break;
     }
-    ++byteCounter;
   }
 }
 
@@ -3897,7 +3893,6 @@ void JBIG2Stream::readProfilesSeg(Guint length) {
     if (curStr->getChar() == EOF) {
       break;
     }
-    ++byteCounter;
   }
 }
 
@@ -3973,7 +3968,6 @@ void JBIG2Stream::readExtensionSeg(Guint length) {
     if (curStr->getChar() == EOF) {
       break;
     }
-    ++byteCounter;
   }
 }
 
@@ -4088,7 +4082,6 @@ GBool JBIG2Stream::readUByte(Guint *x) {
   if ((c0 = curStr->getChar()) == EOF) {
     return gFalse;
   }
-  ++byteCounter;
   *x = (Guint)c0;
   return gTrue;
 }
@@ -4099,7 +4092,6 @@ GBool JBIG2Stream::readByte(int *x) {
   if ((c0 = curStr->getChar()) == EOF) {
     return gFalse;
   }
-  ++byteCounter;
   *x = c0;
   if (c0 & 0x80) {
     *x |= -1 - 0xff;
@@ -4114,7 +4106,6 @@ GBool JBIG2Stream::readUWord(Guint *x) {
       (c1 = curStr->getChar()) == EOF) {
     return gFalse;
   }
-  byteCounter += 2;
   *x = (Guint)((c0 << 8) | c1);
   return gTrue;
 }
@@ -4128,7 +4119,6 @@ GBool JBIG2Stream::readULong(Guint *x) {
       (c3 = curStr->getChar()) == EOF) {
     return gFalse;
   }
-  byteCounter += 4;
   *x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
   return gTrue;
 }
@@ -4142,7 +4132,6 @@ 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 04b3b1f..504ecea 100644
--- a/poppler/JBIG2Stream.h
+++ b/poppler/JBIG2Stream.h
@@ -137,7 +137,6 @@ private:
   Stream *curStr;
   Guchar *dataPtr;
   Guchar *dataEnd;
-  Guint byteCounter;
 
   JArithmeticDecoder *arithDecoder;
   JArithmeticDecoderStats *genericRegionStats;


More information about the poppler mailing list