[poppler] poppler/JBIG2Stream.cc

Albert Astals Cid aacid at kemper.freedesktop.org
Mon Jun 11 11:15:00 PDT 2012


 poppler/JBIG2Stream.cc |   58 +++++++++++++++++++++++++++++++++++++------------
 1 file changed, 44 insertions(+), 14 deletions(-)

New commits:
commit 2e1410ea62fe99e52c94f878d02181f0b59f1cd5
Author: Albert Astals Cid <aacid at kde.org>
Date:   Mon Jun 11 15:17:59 2012 +0200

    Add some security checks to JBIG2Stream decoding
    
    Fixes crash in broken/fuzzed pdf sent by Mateusz "j00ru" Jurczyk and Gynvael Coldwind

diff --git a/poppler/JBIG2Stream.cc b/poppler/JBIG2Stream.cc
index a65746e..7ddcc81 100644
--- a/poppler/JBIG2Stream.cc
+++ b/poppler/JBIG2Stream.cc
@@ -1860,13 +1860,18 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
 				       0, gFalse, gFalse, NULL, NULL, NULL,
 				       bmSize);
       }
-      x = 0;
-      for (; j < i; ++j) {
-	bitmaps[numInputSyms + j] =
-	    collBitmap->getSlice(x, 0, symWidths[j], symHeight);
-	x += symWidths[j];
+      if (likely(collBitmap != NULL)) {
+	x = 0;
+	for (; j < i; ++j) {
+	  bitmaps[numInputSyms + j] =
+	      collBitmap->getSlice(x, 0, symWidths[j], symHeight);
+	  x += symWidths[j];
+	}
+	delete collBitmap;
+      } else {
+	error(errSyntaxError, curStr->getPos(), "collBitmap was null");
+	goto syntaxError;
       }
-      delete collBitmap;
     }
   }
 
@@ -2858,6 +2863,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));
+    memset(refLine, 0, (w + 2) * sizeof(int));
     for (i = 0; i < w + 1; ++i) codingLine[i] = w;
 
     for (y = 0; y < h; ++y) {
@@ -2884,6 +2890,9 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
 	code1 = mmrDecoder->get2DCode();
 	switch (code1) {
 	case twoDimPass:
+          if (unlikely(b1i + 1 >= w + 2)) {
+            break;
+          }
           mmrAddPixels(refLine[b1i + 1], blackPixels, codingLine, &a0i, w);
           if (refLine[b1i + 1] < w) {
             b1i += 2;
@@ -2912,51 +2921,66 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
             mmrAddPixels(codingLine[a0i] + code2, blackPixels ^ 1,
 			 codingLine, &a0i, w);
           }
-          while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
+          while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
             b1i += 2;
           }
           break;
 	case twoDimVertR3:
+          if (unlikely(b1i >= w + 2)) {
+            break;
+          }
           mmrAddPixels(refLine[b1i] + 3, blackPixels, codingLine, &a0i, w);
           blackPixels ^= 1;
           if (codingLine[a0i] < w) {
             ++b1i;
-            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
+            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
               b1i += 2;
             }
           }
           break;
 	case twoDimVertR2:
+          if (unlikely(b1i >= w + 2)) {
+            break;
+          }
           mmrAddPixels(refLine[b1i] + 2, blackPixels, codingLine, &a0i, w);
           blackPixels ^= 1;
           if (codingLine[a0i] < w) {
             ++b1i;
-            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
+            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
               b1i += 2;
             }
           }
           break;
 	case twoDimVertR1:
+          if (unlikely(b1i >= w + 2)) {
+            break;
+          }
           mmrAddPixels(refLine[b1i] + 1, blackPixels, codingLine, &a0i, w);
           blackPixels ^= 1;
           if (codingLine[a0i] < w) {
             ++b1i;
-            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
+            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
               b1i += 2;
             }
           }
           break;
 	case twoDimVert0:
+          if (unlikely(b1i >= w + 2)) {
+            break;
+          }
           mmrAddPixels(refLine[b1i], blackPixels, codingLine, &a0i, w);
           blackPixels ^= 1;
           if (codingLine[a0i] < w) {
             ++b1i;
-            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
+            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
               b1i += 2;
             }
           }
           break;
 	case twoDimVertL3:
+          if (unlikely(b1i >= w + 2)) {
+            break;
+          }
           mmrAddPixelsNeg(refLine[b1i] - 3, blackPixels, codingLine, &a0i, w);
           blackPixels ^= 1;
           if (codingLine[a0i] < w) {
@@ -2965,12 +2989,15 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
             } else {
               ++b1i;
             }
-            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
+            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
               b1i += 2;
             }
           }
           break;
 	case twoDimVertL2:
+          if (unlikely(b1i >= w + 2)) {
+            break;
+          }
           mmrAddPixelsNeg(refLine[b1i] - 2, blackPixels, codingLine, &a0i, w);
           blackPixels ^= 1;
           if (codingLine[a0i] < w) {
@@ -2979,12 +3006,15 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
             } else {
               ++b1i;
             }
-            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
+            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
               b1i += 2;
             }
           }
           break;
 	case twoDimVertL1:
+          if (unlikely(b1i >= w + 2)) {
+            break;
+          }
           mmrAddPixelsNeg(refLine[b1i] - 1, blackPixels, codingLine, &a0i, w);
           blackPixels ^= 1;
           if (codingLine[a0i] < w) {
@@ -2993,7 +3023,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
             } else {
               ++b1i;
             }
-            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
+            while (likely(b1i < w + 2) && refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
               b1i += 2;
             }
           }


More information about the poppler mailing list