[poppler] Branch 'poppler-0.20' - 7 commits - poppler/GfxState.cc poppler/JBIG2Stream.cc poppler/JPXStream.cc poppler/SplashOutputDev.cc poppler/Stream.cc

Albert Astals Cid aacid at kemper.freedesktop.org
Wed Sep 26 05:59:16 PDT 2012


 poppler/GfxState.cc        |   26 +++++++++--
 poppler/JBIG2Stream.cc     |  105 +++++++++++++++++++++++++++++++++++++++------
 poppler/JPXStream.cc       |   97 +++++++++++++++++++++++++++++++++++------
 poppler/SplashOutputDev.cc |    8 +++
 poppler/Stream.cc          |  100 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 304 insertions(+), 32 deletions(-)

New commits:
commit 2c0f70afff03798165c2b609e115dc7e9c034c57
Author: Thomas Freitag <Thomas.Freitag at alfa.de>
Date:   Wed Sep 26 14:58:05 2012 +0200

    More crash fixes for broken documents

diff --git a/poppler/JPXStream.cc b/poppler/JPXStream.cc
index 2cf616d..f1becc9 100644
--- a/poppler/JPXStream.cc
+++ b/poppler/JPXStream.cc
@@ -14,6 +14,7 @@
 // under GPL version 2 or later
 //
 // Copyright (C) 2008, 2012 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2012 Thomas Freitag <Thomas.Freitag at alfa.de>
 //
 // 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
@@ -257,6 +258,10 @@ JPXStream::JPXStream(Stream *strA):
   bitBufLen = 0;
   bitBufSkip = gFalse;
   byteCount = 0;
+
+  curX = curY = 0;
+  curComp = 0;
+  readBufLen = 0;
 }
 
 JPXStream::~JPXStream() {
@@ -410,6 +415,10 @@ void JPXStream::fillReadBuf() {
     tileIdx = ((curY - img.yTileOffset) / img.yTileSize) * img.nXTiles
               + (curX - img.xTileOffset) / img.xTileSize;
 #if 1 //~ ignore the palette, assume the PDF ColorSpace object is valid
+    if (img.tiles == NULL || tileIdx >= img.nXTiles * img.nYTiles || img.tiles[tileIdx].tileComps == NULL) {
+      error(errSyntaxError, getPos(), "Unexpected tileIdx in fillReadBuf in JPX stream");
+      return;
+    } 
     tileComp = &img.tiles[tileIdx].tileComps[curComp];
 #else
     tileComp = &img.tiles[tileIdx].tileComps[havePalette ? 0 : curComp];
@@ -420,6 +429,10 @@ void JPXStream::fillReadBuf() {
       error(errSyntaxError, getPos(), "Unexpected ty in fillReadBuf in JPX stream");
       return;
     }
+    if (unlikely(tx >= (tileComp->x1 - tileComp->x0))) {
+      error(errSyntaxError, getPos(), "Unexpected tx in fillReadBuf in JPX stream");
+      return;
+    }
     pix = (int)tileComp->data[ty * (tileComp->x1 - tileComp->x0) + tx];
     pixBits = tileComp->prec;
 #if 1 //~ ignore the palette, assume the PDF ColorSpace object is valid
@@ -535,7 +548,10 @@ void JPXStream::getImageParams(int *bitsPerComponent,
       } else {
 	cover(4);
 	for (i = 0; i < dataLen; ++i) {
-	  bufStr->getChar();
+	  if (unlikely(bufStr->getChar() == EOF)) {
+	    error(errSyntaxError, getPos(), "Unexpected EOF in getImageParams in JPX stream");
+	    break;
+	  }
 	}
       }
     }
@@ -592,6 +608,13 @@ GBool JPXStream::readBoxes() {
 
   haveImgHdr = gFalse;
 
+  // initialize in case there is a parse error
+  img.xSize = img.ySize = 0;
+  img.xOffset = img.yOffset = 0;
+  img.xTileSize = img.yTileSize = 0;
+  img.xTileOffset = img.yTileOffset = 0;
+  img.nComps = 0;
+
   // check for a naked JPEG 2000 codestream (without the JP2/JPX
   // wrapper) -- this appears to be a violation of the PDF spec, but
   // Acrobat allows it
@@ -895,7 +918,7 @@ GBool JPXStream::readCodestream(Guint len) {
   JPXTileComp *tileComp;
   int segType;
   GBool haveSIZ, haveCOD, haveQCD, haveSOT;
-  Guint precinctSize, style;
+  Guint precinctSize, style, nDecompLevels;
   Guint segLen, capabilities, comp, i, j, r;
 
   //----- main header
@@ -998,11 +1021,15 @@ GBool JPXStream::readCodestream(Guint len) {
 	      "JPX COD marker segment before SIZ segment");
 	return gFalse;
       }
+      if (img.tiles == NULL || img.nXTiles * img.nYTiles == 0 || img.tiles[0].tileComps == NULL) {
+	error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
+	return gFalse;
+      } 
       if (!readUByte(&img.tiles[0].tileComps[0].style) ||
 	  !readUByte(&img.tiles[0].progOrder) ||
 	  !readUWord(&img.tiles[0].nLayers) ||
 	  !readUByte(&img.tiles[0].multiComp) ||
-	  !readUByte(&img.tiles[0].tileComps[0].nDecompLevels) ||
+	  !readUByte(&nDecompLevels) ||
 	  !readUByte(&img.tiles[0].tileComps[0].codeBlockW) ||
 	  !readUByte(&img.tiles[0].tileComps[0].codeBlockH) ||
 	  !readUByte(&img.tiles[0].tileComps[0].codeBlockStyle) ||
@@ -1010,12 +1037,13 @@ GBool JPXStream::readCodestream(Guint len) {
 	error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
 	return gFalse;
       }
-      if (img.tiles[0].tileComps[0].nDecompLevels > 32 ||
+      if (nDecompLevels > 32 ||
 	  img.tiles[0].tileComps[0].codeBlockW > 8 ||
 	  img.tiles[0].tileComps[0].codeBlockH > 8) {
 	error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
 	return gFalse;
       }
+      img.tiles[0].tileComps[0].nDecompLevels = nDecompLevels;
       img.tiles[0].tileComps[0].codeBlockW += 2;
       img.tiles[0].tileComps[0].codeBlockH += 2;
       for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
@@ -1040,9 +1068,13 @@ GBool JPXStream::readCodestream(Guint len) {
 	        img.tiles[0].tileComps[0].transform;
 	  }
 	  img.tiles[i].tileComps[comp].resLevels =
-	      (JPXResLevel *)gmallocn(
+	      (JPXResLevel *)gmallocn_checkoverflow(
 		     (img.tiles[i].tileComps[comp].nDecompLevels + 1),
 		     sizeof(JPXResLevel));
+	  if (img.tiles[i].tileComps[comp].resLevels == NULL) {
+	    error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
+	    return gFalse;
+	  }
 	  for (r = 0; r <= img.tiles[i].tileComps[comp].nDecompLevels; ++r) {
 	    img.tiles[i].tileComps[comp].resLevels[r].precincts = NULL;
 	  }
@@ -1089,7 +1121,7 @@ GBool JPXStream::readCodestream(Guint len) {
 	  (img.nComps <= 256 && !readUByte(&comp)) ||
 	  comp >= img.nComps ||
 	  !readUByte(&style) ||
-	  !readUByte(&img.tiles[0].tileComps[comp].nDecompLevels) ||
+	  !readUByte(&nDecompLevels) ||
 	  !readUByte(&img.tiles[0].tileComps[comp].codeBlockW) ||
 	  !readUByte(&img.tiles[0].tileComps[comp].codeBlockH) ||
 	  !readUByte(&img.tiles[0].tileComps[comp].codeBlockStyle) ||
@@ -1097,12 +1129,13 @@ GBool JPXStream::readCodestream(Guint len) {
 	error(errSyntaxError, getPos(), "Error in JPX COC marker segment");
 	return gFalse;
       }
-      if (img.tiles[0].tileComps[comp].nDecompLevels > 32 ||
+      if (nDecompLevels > 32 ||
 	  img.tiles[0].tileComps[comp].codeBlockW > 8 ||
 	  img.tiles[0].tileComps[comp].codeBlockH > 8) {
 	error(errSyntaxError, getPos(), "Error in JPX COC marker segment");
 	return gFalse;
       }
+      img.tiles[0].tileComps[comp].nDecompLevels = nDecompLevels;
       img.tiles[0].tileComps[comp].style =
 	  (img.tiles[0].tileComps[comp].style & ~1) | (style & 1);
       img.tiles[0].tileComps[comp].codeBlockW += 2;
@@ -1494,7 +1527,7 @@ GBool JPXStream::readTilePart() {
   GBool haveSOD;
   Guint tileIdx, tilePartLen, tilePartIdx, nTileParts;
   GBool tilePartToEOC;
-  Guint precinctSize, style;
+  Guint precinctSize, style, nDecompLevels;
   Guint n, nSBs, nx, ny, sbx0, sby0, comp, segLen;
   Guint i, j, k, cbX, cbY, r, pre, sb, cbi, cbj;
   int segType, level;
@@ -1508,8 +1541,8 @@ GBool JPXStream::readTilePart() {
     return gFalse;
   }
 
-  if ((tilePartIdx > 0 && !img.tiles[tileIdx].init) ||
-      tileIdx >= img.nXTiles * img.nYTiles) {
+  if (tileIdx >= img.nXTiles * img.nYTiles ||
+      (tilePartIdx > 0 && !img.tiles[tileIdx].init)) {
     error(errSyntaxError, getPos(), "Weird tile index in JPX stream");
     return gFalse;
   }
@@ -1531,7 +1564,7 @@ GBool JPXStream::readTilePart() {
 	  !readUByte(&img.tiles[tileIdx].progOrder) ||
 	  !readUWord(&img.tiles[tileIdx].nLayers) ||
 	  !readUByte(&img.tiles[tileIdx].multiComp) ||
-	  !readUByte(&img.tiles[tileIdx].tileComps[0].nDecompLevels) ||
+	  !readUByte(&nDecompLevels) ||
 	  !readUByte(&img.tiles[tileIdx].tileComps[0].codeBlockW) ||
 	  !readUByte(&img.tiles[tileIdx].tileComps[0].codeBlockH) ||
 	  !readUByte(&img.tiles[tileIdx].tileComps[0].codeBlockStyle) ||
@@ -1539,12 +1572,13 @@ GBool JPXStream::readTilePart() {
 	error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
 	return gFalse;
       }
-      if (img.tiles[tileIdx].tileComps[0].nDecompLevels > 32 ||
+      if (nDecompLevels > 32 ||
 	  img.tiles[tileIdx].tileComps[0].codeBlockW > 8 ||
 	  img.tiles[tileIdx].tileComps[0].codeBlockH > 8) {
 	error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
 	return gFalse;
       }
+      img.tiles[tileIdx].tileComps[0].nDecompLevels = nDecompLevels;
       img.tiles[tileIdx].tileComps[0].codeBlockW += 2;
       img.tiles[tileIdx].tileComps[0].codeBlockH += 2;
       for (comp = 0; comp < img.nComps; ++comp) {
@@ -1605,7 +1639,7 @@ GBool JPXStream::readTilePart() {
 	  (img.nComps <= 256 && !readUByte(&comp)) ||
 	  comp >= img.nComps ||
 	  !readUByte(&style) ||
-	  !readUByte(&img.tiles[tileIdx].tileComps[comp].nDecompLevels) ||
+	  !readUByte(&nDecompLevels) ||
 	  !readUByte(&img.tiles[tileIdx].tileComps[comp].codeBlockW) ||
 	  !readUByte(&img.tiles[tileIdx].tileComps[comp].codeBlockH) ||
 	  !readUByte(&img.tiles[tileIdx].tileComps[comp].codeBlockStyle) ||
@@ -1613,12 +1647,13 @@ GBool JPXStream::readTilePart() {
 	error(errSyntaxError, getPos(), "Error in JPX COC marker segment");
 	return gFalse;
       }
-      if (img.tiles[tileIdx].tileComps[comp].nDecompLevels > 32 ||
+      if (nDecompLevels > 32 ||
 	  img.tiles[tileIdx].tileComps[comp].codeBlockW > 8 ||
 	  img.tiles[tileIdx].tileComps[comp].codeBlockH > 8) {
 	error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
 	return gFalse;
       }
+      img.tiles[tileIdx].tileComps[comp].nDecompLevels = nDecompLevels;
       img.tiles[tileIdx].tileComps[comp].style =
 	  (img.tiles[tileIdx].tileComps[comp].style & ~1) | (style & 1);
       img.tiles[tileIdx].tileComps[comp].codeBlockW += 2;
@@ -2350,6 +2385,12 @@ GBool JPXStream::readTilePartData(Guint tileIdx,
 	    tile->res = 0;
 	  }
 	}
+	tileComp = &tile->tileComps[tile->comp];
+	if (tile->res >= tileComp->nDecompLevels + 1) {
+	  if (++tile->comp == img.nComps) {
+	    return gTrue;
+	  }
+	}
       }
       break;
     case 3: // precinct, component, resolution level, layer
@@ -2840,7 +2881,13 @@ void JPXStream::inverseTransformLevel(JPXTileComp *tileComp,
     // i-quant parameters
     if (qStyle == 0) {
       cover(100);
-      eps = (tileComp->quantSteps[3*r - 2 + sb] >> 3) & 0x1f;
+      const Guint stepIndex = 3*r - 2 + sb;
+      if (unlikely(stepIndex >= tileComp->nQuantSteps)) {
+	error(errSyntaxError, getPos(),
+	      "Wrong index for quantSteps in inverseTransformLevel in JPX stream");
+	break;
+      }
+      eps = (tileComp->quantSteps[stepIndex] >> 3) & 0x1f;
       shift = guard + eps - 1;
       mu = 0; // make gcc happy
     } else {
@@ -2958,6 +3005,16 @@ void JPXStream::inverseTransformLevel(JPXTileComp *tileComp,
 	*bufPtr = dataPtr[x];
       }
     }
+    if (tileComp->x1 - tileComp->x0 > tileComp->y1 - tileComp->y0) {
+      x = tileComp->x1 - tileComp->x0 + 5;
+    } else {
+      x = tileComp->y1 - tileComp->y0 + 5;
+    }
+    if (offset + nx2 > x || nx2 == 0) {
+      error(errSyntaxError, getPos(),
+	"Invalid call of inverseTransform1D in inverseTransformLevel in JPX stream");
+      return;
+    }
     inverseTransform1D(tileComp, tileComp->buf, offset, nx2);
     for (x = 0, bufPtr = tileComp->buf + offset; x < nx2; ++x, ++bufPtr) {
       dataPtr[x] = *bufPtr;
@@ -2998,6 +3055,16 @@ void JPXStream::inverseTransformLevel(JPXTileComp *tileComp,
 	*bufPtr = dataPtr[y * tileComp->w];
       }
     }
+    if (tileComp->x1 - tileComp->x0 > tileComp->y1 - tileComp->y0) {
+      y = tileComp->x1 - tileComp->x0 + 5;
+    } else {
+      y = tileComp->y1 - tileComp->y0 + 5;
+    }
+    if (offset + ny2 > y || ny2 == 0) {
+      error(errSyntaxError, getPos(),
+	"Invalid call of inverseTransform1D in inverseTransformLevel in JPX stream");
+      return;
+    }
     inverseTransform1D(tileComp, tileComp->buf, offset, ny2);
     for (y = 0, bufPtr = tileComp->buf + offset; y < ny2; ++y, ++bufPtr) {
       dataPtr[y * tileComp->w] = *bufPtr;
commit 78558d24692c68212da35a88deb68069c5a06d81
Author: Thomas Freitag <Thomas.Freitag at alfa.de>
Date:   Wed Sep 26 14:32:05 2012 +0200

    Fix more crashes in broken files
    
    solves 1258.pdf.SIGSEGV.dee.288 and 1255.pdf.asan.38.285, extends 1043.pdf.asan.47.50 and 557.pdf.asan.47.894

diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 252e88d..b21c2b0 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -2173,10 +2173,16 @@ GfxColorSpace *GfxSeparationColorSpace::parse(Array *arr, Gfx *gfx, int recursio
   if (!(funcA = Function::parse(&obj1))) {
     goto err4;
   }
+  if (funcA->getInputSize() != 1) {
+    error(errSyntaxWarning, -1, "Bad SeparationColorSpace function");
+    goto err5;
+  }
   obj1.free();
   cs = new GfxSeparationColorSpace(nameA, altA, funcA);
   return cs;
 
+ err5:
+  delete funcA;
  err4:
   delete altA;
  err3:
@@ -3096,6 +3102,10 @@ void GfxUnivariateShading::getColor(double t, GfxColor *color) {
       out[i] = 0;
     }
     for (i = 0; i < nFuncs; ++i) {
+      if (funcs[i]->getInputSize() != 1) {
+        error(errSyntaxWarning, -1, "Invalid shading function (input != 1)");
+        break;
+      }
       funcs[i]->transform(&t, &out[i]);
     }
   }
@@ -3267,7 +3277,7 @@ GfxAxialShading *GfxAxialShading::parse(Dict *dict, Gfx *gfx) {
   dict->lookup("Function", &obj1);
   if (obj1.isArray()) {
     nFuncsA = obj1.arrayGetLength();
-    if (nFuncsA > gfxColorMaxComps) {
+    if (nFuncsA > gfxColorMaxComps || nFuncsA == 0) {
       error(errSyntaxWarning, -1, "Invalid Function array in shading dictionary");
       goto err1;
     }
@@ -3292,9 +3302,19 @@ GfxAxialShading *GfxAxialShading::parse(Dict *dict, Gfx *gfx) {
   extend0A = extend1A = gFalse;
   if (dict->lookup("Extend", &obj1)->isArray() &&
       obj1.arrayGetLength() == 2) {
-    extend0A = obj1.arrayGet(0, &obj2)->getBool();
+    obj1.arrayGet(0, &obj2);
+    if (obj2.isBool()) {
+      extend0A = obj2.getBool();
+    } else {
+      error(errSyntaxWarning, -1, "Invalid axial shading extend (0)");
+    }
     obj2.free();
-    extend1A = obj1.arrayGet(1, &obj2)->getBool();
+    obj1.arrayGet(1, &obj2);
+    if (obj2.isBool()) {
+      extend1A = obj2.getBool();
+    } else {
+      error(errSyntaxWarning, -1, "Invalid axial shading extend (1)");
+    }
     obj2.free();
   }
   obj1.free();
commit e8822c0f3a46195ec7c6e55c556dd0c5716be742
Author: Albert Astals Cid <aacid at kde.org>
Date:   Wed Sep 26 14:21:46 2012 +0200

    Add unlikelys

diff --git a/poppler/Stream.cc b/poppler/Stream.cc
index b94d923..f287406 100644
--- a/poppler/Stream.cc
+++ b/poppler/Stream.cc
@@ -1757,7 +1757,7 @@ int CCITTFaxStream::lookChar() {
 	  }
 	  while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
 	    b1i += 2;
-	    if (b1i > columns + 1) {
+	    if (unlikely(b1i > columns + 1)) {
 	      error(errSyntaxError, getPos(),
 		"Bad 2D code {0:04x} in CCITTFax stream", code1);
 	      err = gTrue;
@@ -1766,7 +1766,7 @@ int CCITTFaxStream::lookChar() {
 	  }
 	  break;
 	case twoDimVertR3:
-	  if (b1i > columns + 1) {
+	  if (unlikely(b1i > columns + 1)) {
 	    error(errSyntaxError, getPos(),
 	      "Bad 2D code {0:04x} in CCITTFax stream", code1);
 	    err = gTrue;
@@ -1778,7 +1778,7 @@ int CCITTFaxStream::lookChar() {
 	    ++b1i;
 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
 	      b1i += 2;
-	      if (b1i > columns + 1) {
+	      if (unlikely(b1i > columns + 1)) {
 		error(errSyntaxError, getPos(),
 		  "Bad 2D code {0:04x} in CCITTFax stream", code1);
 		err = gTrue;
@@ -1788,7 +1788,7 @@ int CCITTFaxStream::lookChar() {
 	  }
 	  break;
 	case twoDimVertR2:
-	  if (b1i > columns + 1) {
+	  if (unlikely(b1i > columns + 1)) {
 	    error(errSyntaxError, getPos(),
 	      "Bad 2D code {0:04x} in CCITTFax stream", code1);
 	    err = gTrue;
@@ -1800,7 +1800,7 @@ int CCITTFaxStream::lookChar() {
 	    ++b1i;
 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
 	      b1i += 2;
-	      if (b1i > columns + 1) {
+	      if (unlikely(b1i > columns + 1)) {
 		error(errSyntaxError, getPos(),
 		  "Bad 2D code {0:04x} in CCITTFax stream", code1);
 		err = gTrue;
@@ -1810,7 +1810,7 @@ int CCITTFaxStream::lookChar() {
 	  }
 	  break;
 	case twoDimVertR1:
-	  if (b1i > columns + 1) {
+	  if (unlikely(b1i > columns + 1)) {
 	    error(errSyntaxError, getPos(),
 	      "Bad 2D code {0:04x} in CCITTFax stream", code1);
 	    err = gTrue;
@@ -1822,7 +1822,7 @@ int CCITTFaxStream::lookChar() {
 	    ++b1i;
 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
 	      b1i += 2;
-	      if (b1i > columns + 1) {
+	      if (unlikely(b1i > columns + 1)) {
 		error(errSyntaxError, getPos(),
 		  "Bad 2D code {0:04x} in CCITTFax stream", code1);
 		err = gTrue;
@@ -1832,7 +1832,7 @@ int CCITTFaxStream::lookChar() {
 	  }
 	  break;
 	case twoDimVert0:
-	  if (b1i > columns + 1) {
+	  if (unlikely(b1i > columns + 1)) {
 	    error(errSyntaxError, getPos(),
 	      "Bad 2D code {0:04x} in CCITTFax stream", code1);
 	    err = gTrue;
@@ -1844,7 +1844,7 @@ int CCITTFaxStream::lookChar() {
 	    ++b1i;
 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
 	      b1i += 2;
-	      if (b1i > columns + 1) {
+	      if (unlikely(b1i > columns + 1)) {
 		error(errSyntaxError, getPos(),
 		  "Bad 2D code {0:04x} in CCITTFax stream", code1);
 		err = gTrue;
@@ -1854,7 +1854,7 @@ int CCITTFaxStream::lookChar() {
 	  }
 	  break;
 	case twoDimVertL3:
-	  if (b1i > columns + 1) {
+	  if (unlikely(b1i > columns + 1)) {
 	    error(errSyntaxError, getPos(),
 	      "Bad 2D code {0:04x} in CCITTFax stream", code1);
 	    err = gTrue;
@@ -1870,7 +1870,7 @@ int CCITTFaxStream::lookChar() {
 	    }
 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
 	      b1i += 2;
-	      if (b1i > columns + 1) {
+	      if (unlikely(b1i > columns + 1)) {
 		error(errSyntaxError, getPos(),
 		  "Bad 2D code {0:04x} in CCITTFax stream", code1);
 		err = gTrue;
@@ -1880,7 +1880,7 @@ int CCITTFaxStream::lookChar() {
 	  }
 	  break;
 	case twoDimVertL2:
-	  if (b1i > columns + 1) {
+	  if (unlikely(b1i > columns + 1)) {
 	    error(errSyntaxError, getPos(),
 	      "Bad 2D code {0:04x} in CCITTFax stream", code1);
 	    err = gTrue;
@@ -1896,7 +1896,7 @@ int CCITTFaxStream::lookChar() {
 	    }
 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
 	      b1i += 2;
-	      if (b1i > columns + 1) {
+	      if (unlikely(b1i > columns + 1)) {
 	        error(errSyntaxError, getPos(),
 		  "Bad 2D code {0:04x} in CCITTFax stream", code1);
 	        err = gTrue;
@@ -1906,7 +1906,7 @@ int CCITTFaxStream::lookChar() {
 	  }
 	  break;
 	case twoDimVertL1:
-	  if (b1i > columns + 1) {
+	  if (unlikely(b1i > columns + 1)) {
 	    error(errSyntaxError, getPos(),
 	      "Bad 2D code {0:04x} in CCITTFax stream", code1);
 	    err = gTrue;
@@ -1922,7 +1922,7 @@ int CCITTFaxStream::lookChar() {
 	    }
 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
 	      b1i += 2;
-	      if (b1i > columns + 1) {
+	      if (unlikely(b1i > columns + 1)) {
 		error(errSyntaxError, getPos(),
 		  "Bad 2D code {0:04x} in CCITTFax stream", code1);
 		err = gTrue;
@@ -2111,7 +2111,7 @@ int CCITTFaxStream::lookChar() {
 	outputBits = 0;
 	if (codingLine[a0i] < columns) {
 	  ++a0i;
-	  if (a0i > columns) {
+	  if (unlikely(a0i > columns)) {
 	    error(errSyntaxError, getPos(),
 	      "Bad bits {0:04x} in CCITTFax stream", bits);
 	      err = gTrue;
commit 31874f2e065b0d68f726ef404de98f42489c80c7
Author: Thomas Freitag <Thomas.Freitag at alfa.de>
Date:   Wed Sep 26 14:17:00 2012 +0200

    Less crashes in broken files
    
    rebased patch for 1001.pdf.asan.2a.4, extends patch for 100.pdf.asan.38.2

diff --git a/poppler/Stream.cc b/poppler/Stream.cc
index 4ce6c00..b94d923 100644
--- a/poppler/Stream.cc
+++ b/poppler/Stream.cc
@@ -1707,7 +1707,7 @@ int CCITTFaxStream::lookChar() {
 
     // 2-D encoding
     if (nextLine2D) {
-      for (i = 0; codingLine[i] < columns; ++i) {
+      for (i = 0; i < columns && codingLine[i] < columns; ++i) {
 	refLine[i] = codingLine[i];
       }
       refLine[i++] = columns;
@@ -1723,7 +1723,7 @@ int CCITTFaxStream::lookChar() {
       //   codingLine[a0i = 0] = refLine[b1i = 0] = 0 is possible
       // exception at right edge:
       //   refLine[b1i] = refLine[b1i+1] = columns is possible
-      while (codingLine[a0i] < columns) {
+      while (codingLine[a0i] < columns && !err) {
 	code1 = getTwoDimCode();
 	switch (code1) {
 	case twoDimPass:
@@ -1757,49 +1757,109 @@ int CCITTFaxStream::lookChar() {
 	  }
 	  while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
 	    b1i += 2;
+	    if (b1i > columns + 1) {
+	      error(errSyntaxError, getPos(),
+		"Bad 2D code {0:04x} in CCITTFax stream", code1);
+	      err = gTrue;
+	      break;
+	    }
 	  }
 	  break;
 	case twoDimVertR3:
+	  if (b1i > columns + 1) {
+	    error(errSyntaxError, getPos(),
+	      "Bad 2D code {0:04x} in CCITTFax stream", code1);
+	    err = gTrue;
+	    break;
+	  }
 	  addPixels(refLine[b1i] + 3, blackPixels);
 	  blackPixels ^= 1;
 	  if (codingLine[a0i] < columns) {
 	    ++b1i;
 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
 	      b1i += 2;
+	      if (b1i > columns + 1) {
+		error(errSyntaxError, getPos(),
+		  "Bad 2D code {0:04x} in CCITTFax stream", code1);
+		err = gTrue;
+		break;
+	      }
 	    }
 	  }
 	  break;
 	case twoDimVertR2:
+	  if (b1i > columns + 1) {
+	    error(errSyntaxError, getPos(),
+	      "Bad 2D code {0:04x} in CCITTFax stream", code1);
+	    err = gTrue;
+	    break;
+	  }
 	  addPixels(refLine[b1i] + 2, blackPixels);
 	  blackPixels ^= 1;
 	  if (codingLine[a0i] < columns) {
 	    ++b1i;
 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
 	      b1i += 2;
+	      if (b1i > columns + 1) {
+		error(errSyntaxError, getPos(),
+		  "Bad 2D code {0:04x} in CCITTFax stream", code1);
+		err = gTrue;
+		break;
+	      }
 	    }
 	  }
 	  break;
 	case twoDimVertR1:
+	  if (b1i > columns + 1) {
+	    error(errSyntaxError, getPos(),
+	      "Bad 2D code {0:04x} in CCITTFax stream", code1);
+	    err = gTrue;
+	    break;
+	  }
 	  addPixels(refLine[b1i] + 1, blackPixels);
 	  blackPixels ^= 1;
 	  if (codingLine[a0i] < columns) {
 	    ++b1i;
 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
 	      b1i += 2;
+	      if (b1i > columns + 1) {
+		error(errSyntaxError, getPos(),
+		  "Bad 2D code {0:04x} in CCITTFax stream", code1);
+		err = gTrue;
+		break;
+	      }
 	    }
 	  }
 	  break;
 	case twoDimVert0:
+	  if (b1i > columns + 1) {
+	    error(errSyntaxError, getPos(),
+	      "Bad 2D code {0:04x} in CCITTFax stream", code1);
+	    err = gTrue;
+	    break;
+	  }
 	  addPixels(refLine[b1i], blackPixels);
 	  blackPixels ^= 1;
 	  if (codingLine[a0i] < columns) {
 	    ++b1i;
 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
 	      b1i += 2;
+	      if (b1i > columns + 1) {
+		error(errSyntaxError, getPos(),
+		  "Bad 2D code {0:04x} in CCITTFax stream", code1);
+		err = gTrue;
+		break;
+	      }
 	    }
 	  }
 	  break;
 	case twoDimVertL3:
+	  if (b1i > columns + 1) {
+	    error(errSyntaxError, getPos(),
+	      "Bad 2D code {0:04x} in CCITTFax stream", code1);
+	    err = gTrue;
+	    break;
+	  }
 	  addPixelsNeg(refLine[b1i] - 3, blackPixels);
 	  blackPixels ^= 1;
 	  if (codingLine[a0i] < columns) {
@@ -1810,10 +1870,22 @@ int CCITTFaxStream::lookChar() {
 	    }
 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
 	      b1i += 2;
+	      if (b1i > columns + 1) {
+		error(errSyntaxError, getPos(),
+		  "Bad 2D code {0:04x} in CCITTFax stream", code1);
+		err = gTrue;
+		break;
+	      }
 	    }
 	  }
 	  break;
 	case twoDimVertL2:
+	  if (b1i > columns + 1) {
+	    error(errSyntaxError, getPos(),
+	      "Bad 2D code {0:04x} in CCITTFax stream", code1);
+	    err = gTrue;
+	    break;
+	  }
 	  addPixelsNeg(refLine[b1i] - 2, blackPixels);
 	  blackPixels ^= 1;
 	  if (codingLine[a0i] < columns) {
@@ -1824,10 +1896,22 @@ int CCITTFaxStream::lookChar() {
 	    }
 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
 	      b1i += 2;
+	      if (b1i > columns + 1) {
+	        error(errSyntaxError, getPos(),
+		  "Bad 2D code {0:04x} in CCITTFax stream", code1);
+	        err = gTrue;
+	        break;
+	      }
 	    }
 	  }
 	  break;
 	case twoDimVertL1:
+	  if (b1i > columns + 1) {
+	    error(errSyntaxError, getPos(),
+	      "Bad 2D code {0:04x} in CCITTFax stream", code1);
+	    err = gTrue;
+	    break;
+	  }
 	  addPixelsNeg(refLine[b1i] - 1, blackPixels);
 	  blackPixels ^= 1;
 	  if (codingLine[a0i] < columns) {
@@ -1838,6 +1922,12 @@ int CCITTFaxStream::lookChar() {
 	    }
 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
 	      b1i += 2;
+	      if (b1i > columns + 1) {
+		error(errSyntaxError, getPos(),
+		  "Bad 2D code {0:04x} in CCITTFax stream", code1);
+		err = gTrue;
+		break;
+	      }
 	    }
 	  }
 	  break;
@@ -2021,6 +2111,12 @@ int CCITTFaxStream::lookChar() {
 	outputBits = 0;
 	if (codingLine[a0i] < columns) {
 	  ++a0i;
+	  if (a0i > columns) {
+	    error(errSyntaxError, getPos(),
+	      "Bad bits {0:04x} in CCITTFax stream", bits);
+	      err = gTrue;
+	      break;
+	  }
 	  outputBits = codingLine[a0i] - codingLine[a0i - 1];
 	} else if (bits > 0) {
 	  buf <<= bits;
commit 81b1d9207840ec1e66eef469b29a36a8556b7265
Author: Albert Astals Cid <aacid at kde.org>
Date:   Wed Sep 26 13:38:54 2012 +0200

    Add some unlikelys

diff --git a/poppler/JBIG2Stream.cc b/poppler/JBIG2Stream.cc
index 5789959..afba8c6 100644
--- a/poppler/JBIG2Stream.cc
+++ b/poppler/JBIG2Stream.cc
@@ -586,7 +586,7 @@ int JBIG2MMRDecoder::getBlackCode() {
       } else {
 	code = buf >> (bufLen - 12);
       }
-      if ((code & 0xff) < 64) {
+      if (unlikely((code & 0xff) < 64)) {
         break;
       }
       p = &blackTab2[(code & 0xff) - 64];
@@ -1105,7 +1105,7 @@ public:
   virtual ~JBIG2PatternDict();
   virtual JBIG2SegmentType getType() { return jbig2SegPatternDict; }
   Guint getSize() { return size; }
-  void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { if (idx < size) bitmaps[idx] = bitmap; }
+  void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { if (likely(idx < size)) bitmaps[idx] = bitmap; }
   JBIG2Bitmap *getBitmap(Guint idx) { return (idx < size) ? bitmaps[idx] : NULL; }
 
 private:
@@ -1766,7 +1766,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
       goto syntaxError;
     }
     symHeight += dh;
-    if (symHeight > 0x40000000) {
+    if (unlikely(symHeight > 0x40000000)) {
       error(errSyntaxError, curStr->getPos(), "Bad height value in JBIG2 symbol dictionary");
       goto syntaxError;
     }
@@ -1837,7 +1837,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
 	    goto syntaxError;
 	  }
 	  refBitmap = bitmaps[symID];
-	  if (!refBitmap) {
+	  if (unlikely(refBitmap == NULL)) {
 	    error(errSyntaxError, curStr->getPos(), "Invalid ref bitmap for symbol ID {0:d} in JBIG2 symbol dictionary", symID);
 	    goto syntaxError;
 	  }
@@ -1876,7 +1876,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
 	collBitmap = new JBIG2Bitmap(0, totalWidth, symHeight);
 	bmSize = symHeight * ((totalWidth + 7) >> 3);
 	p = collBitmap->getDataPtr();
-	if (p == NULL) {
+	if (unlikely(p == NULL)) {
 	  delete collBitmap;
 	  goto syntaxError;
 	}
@@ -2229,7 +2229,7 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
 	  symCodeTab[i++].prefixLen = 0;
 	}
       } else if (j > 0x100) {
-	if (i == 0) ++i;
+	if (unlikely(i == 0)) ++i;
 	for (j -= 0x100; j && i < numSyms; --j) {
 	  symCodeTab[i].prefixLen = symCodeTab[i-1].prefixLen;
 	  ++i;
@@ -2397,7 +2397,7 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
 
       if (symID >= (Guint)numSyms) {
 	error(errSyntaxError, curStr->getPos(), "Invalid symbol number in JBIG2 text region");
-	if (numInstances - inst > 0x800) {
+	if (unlikely(numInstances - inst > 0x800)) {
 	  // don't loop too often with damaged JBIg2 streams
 	  delete bitmap;
 	  return NULL;
@@ -2453,7 +2453,7 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
 	  //~ something is wrong here - refCorner shouldn't degenerate into
 	  //~   two cases
 	  bw = symbolBitmap->getWidth() - 1;
-	  if (symbolBitmap->getHeight() == 0) {
+	  if (unlikely(symbolBitmap->getHeight() == 0)) {
 	    error(errSyntaxError, curStr->getPos(), "Invalid symbol bitmap height");
 	    if (ri) {
 	      delete symbolBitmap;
@@ -2463,7 +2463,7 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
 	  }
 	  bh = symbolBitmap->getHeight() - 1;
 	  if (transposed) {
-	    if (s > 2 * bitmap->getHeight()) {
+	    if (unlikely(s > 2 * bitmap->getHeight())) {
 	      error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine");
 	      if (ri) {
 	        delete symbolBitmap;
@@ -2489,7 +2489,7 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
 	  } else {
 	    switch (refCorner) {
 	    case 0: // bottom left
-	      if (tt - (int) bh > 2 * bitmap->getHeight()) {
+	      if (unlikely(tt - (int) bh > 2 * bitmap->getHeight())) {
 		error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine");
 		if (ri) {
 		  delete symbolBitmap;
@@ -2500,7 +2500,7 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
 	      bitmap->combine(symbolBitmap, s, tt - bh, combOp);
 	      break;
 	    case 1: // top left
-	      if (tt > 2 * bitmap->getHeight()) {
+	      if (unlikely(tt > 2 * bitmap->getHeight())) {
 		error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine");
 		if (ri) {
 		  delete symbolBitmap;
@@ -2511,7 +2511,7 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
 	      bitmap->combine(symbolBitmap, s, tt, combOp);
 	      break;
 	    case 2: // bottom right
-	      if (tt - (int) bh > 2 * bitmap->getHeight()) {
+	      if (unlikely(tt - (int) bh > 2 * bitmap->getHeight())) {
 		error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine");
 		if (ri) {
 		  delete symbolBitmap;
@@ -2522,7 +2522,7 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
 	      bitmap->combine(symbolBitmap, s, tt - bh, combOp);
 	      break;
 	    case 3: // top right
-	      if (tt > 2 * bitmap->getHeight()) {
+	      if (unlikely(tt > 2 * bitmap->getHeight())) {
 		error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine");
 		if (ri) {
 		  delete symbolBitmap;
@@ -2756,7 +2756,7 @@ void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm,
     for (n = 0; n < gridW; ++n) {
       if (!(enableSkip && skipBitmap->getPixel(n, m))) {
 	patternBitmap = patternDict->getBitmap(grayImg[i]);
-	if (patternBitmap == NULL) {
+	if (unlikely(patternBitmap == NULL)) {
 	  error(errSyntaxError, curStr->getPos(), "Bad pattern bitmap");
 	  return;
 	}
commit 9ae1184e3049cabc695c8645a10eaef748b6e641
Author: Thomas Freitag <Thomas.Freitag at alfa.de>
Date:   Wed Sep 26 12:32:26 2012 +0200

    More fixes against broken files
    
    solves 121.pdf.asan.6f.235, extends 682.pdf.SIGFPE.f3.1033 and 569.pdf.SIGSEGV.c1.907, extends Patch for 829. and 839. asan and sigsegv series

diff --git a/poppler/JBIG2Stream.cc b/poppler/JBIG2Stream.cc
index 78a205d..5789959 100644
--- a/poppler/JBIG2Stream.cc
+++ b/poppler/JBIG2Stream.cc
@@ -19,6 +19,7 @@
 // Copyright (C) 2009 David Benjamin <davidben at mit.edu>
 // Copyright (C) 2011 Edward Jiang <ejiang at google.com>
 // Copyright (C) 2012 William Bader <williambader at hotmail.com>
+// Copyright (C) 2012 Thomas Freitag <Thomas.Freitag at alfa.de>
 //
 // 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
@@ -585,6 +586,9 @@ int JBIG2MMRDecoder::getBlackCode() {
       } else {
 	code = buf >> (bufLen - 12);
       }
+      if ((code & 0xff) < 64) {
+        break;
+      }
       p = &blackTab2[(code & 0xff) - 64];
     } else {
       if (bufLen <= 6) {
@@ -713,8 +717,10 @@ JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, int wA, int hA):
     return;
   }
   // need to allocate one extra guard byte for use in combine()
-  data = (Guchar *)gmalloc(h * line + 1);
-  data[h * line] = 0;
+  data = (Guchar *)gmalloc_checkoverflow(h * line + 1);
+  if (data != NULL) {
+    data[h * line] = 0;
+  }
 }
 
 JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap):
@@ -1099,8 +1105,8 @@ public:
   virtual ~JBIG2PatternDict();
   virtual JBIG2SegmentType getType() { return jbig2SegPatternDict; }
   Guint getSize() { return size; }
-  void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
-  JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
+  void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { if (idx < size) bitmaps[idx] = bitmap; }
+  JBIG2Bitmap *getBitmap(Guint idx) { return (idx < size) ? bitmaps[idx] : NULL; }
 
 private:
 
@@ -1111,8 +1117,13 @@ private:
 JBIG2PatternDict::JBIG2PatternDict(Guint segNumA, Guint sizeA):
   JBIG2Segment(segNumA)
 {
-  size = sizeA;
-  bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
+  bitmaps = (JBIG2Bitmap **)gmallocn_checkoverflow(sizeA, sizeof(JBIG2Bitmap *));
+  if (bitmaps) {
+    size = sizeA;
+  } else {
+    size = 0;
+    error(errSyntaxError, -1, "JBIG2PatternDict: can't allocate bitmaps");
+  }
 }
 
 JBIG2PatternDict::~JBIG2PatternDict() {
@@ -1755,6 +1766,10 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
       goto syntaxError;
     }
     symHeight += dh;
+    if (symHeight > 0x40000000) {
+      error(errSyntaxError, curStr->getPos(), "Bad height value in JBIG2 symbol dictionary");
+      goto syntaxError;
+    }
     symWidth = 0;
     totalWidth = 0;
     j = i;
@@ -1822,6 +1837,10 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
 	    goto syntaxError;
 	  }
 	  refBitmap = bitmaps[symID];
+	  if (!refBitmap) {
+	    error(errSyntaxError, curStr->getPos(), "Invalid ref bitmap for symbol ID {0:d} in JBIG2 symbol dictionary", symID);
+	    goto syntaxError;
+	  }
 	  bitmaps[numInputSyms + i] =
 	      readGenericRefinementRegion(symWidth, symHeight,
 					  sdrTemplate, gFalse,
@@ -1857,6 +1876,10 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
 	collBitmap = new JBIG2Bitmap(0, totalWidth, symHeight);
 	bmSize = symHeight * ((totalWidth + 7) >> 3);
 	p = collBitmap->getDataPtr();
+	if (p == NULL) {
+	  delete collBitmap;
+	  goto syntaxError;
+	}
 	for (k = 0; k < (Guint)bmSize; ++k) {
 	  if ((c = curStr->getChar()) == EOF) {
 	    break;
@@ -2206,6 +2229,7 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
 	  symCodeTab[i++].prefixLen = 0;
 	}
       } else if (j > 0x100) {
+	if (i == 0) ++i;
 	for (j -= 0x100; j && i < numSyms; --j) {
 	  symCodeTab[i].prefixLen = symCodeTab[i-1].prefixLen;
 	  ++i;
@@ -2373,6 +2397,11 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
 
       if (symID >= (Guint)numSyms) {
 	error(errSyntaxError, curStr->getPos(), "Invalid symbol number in JBIG2 text region");
+	if (numInstances - inst > 0x800) {
+	  // don't loop too often with damaged JBIg2 streams
+	  delete bitmap;
+	  return NULL;
+	}
       } else {
 
 	// get the symbol bitmap
@@ -2424,8 +2453,24 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
 	  //~ something is wrong here - refCorner shouldn't degenerate into
 	  //~   two cases
 	  bw = symbolBitmap->getWidth() - 1;
+	  if (symbolBitmap->getHeight() == 0) {
+	    error(errSyntaxError, curStr->getPos(), "Invalid symbol bitmap height");
+	    if (ri) {
+	      delete symbolBitmap;
+	    }
+	    delete bitmap;
+	    return NULL;
+	  }
 	  bh = symbolBitmap->getHeight() - 1;
 	  if (transposed) {
+	    if (s > 2 * bitmap->getHeight()) {
+	      error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine");
+	      if (ri) {
+	        delete symbolBitmap;
+	      }
+	      delete bitmap;
+	      return NULL;
+	    }
 	    switch (refCorner) {
 	    case 0: // bottom left
 	      bitmap->combine(symbolBitmap, tt, s, combOp);
@@ -2444,15 +2489,47 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
 	  } else {
 	    switch (refCorner) {
 	    case 0: // bottom left
+	      if (tt - (int) bh > 2 * bitmap->getHeight()) {
+		error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine");
+		if (ri) {
+		  delete symbolBitmap;
+		}
+		delete bitmap;
+		return NULL;
+	      }
 	      bitmap->combine(symbolBitmap, s, tt - bh, combOp);
 	      break;
 	    case 1: // top left
+	      if (tt > 2 * bitmap->getHeight()) {
+		error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine");
+		if (ri) {
+		  delete symbolBitmap;
+		}
+		delete bitmap;
+		return NULL;
+	      }
 	      bitmap->combine(symbolBitmap, s, tt, combOp);
 	      break;
 	    case 2: // bottom right
+	      if (tt - (int) bh > 2 * bitmap->getHeight()) {
+		error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine");
+		if (ri) {
+		  delete symbolBitmap;
+		}
+		delete bitmap;
+		return NULL;
+	      }
 	      bitmap->combine(symbolBitmap, s, tt - bh, combOp);
 	      break;
 	    case 3: // top right
+	      if (tt > 2 * bitmap->getHeight()) {
+		error(errSyntaxError, curStr->getPos(), "Invalid JBIG2 combine");
+		if (ri) {
+		  delete symbolBitmap;
+		}
+		delete bitmap;
+		return NULL;
+	      }
 	      bitmap->combine(symbolBitmap, s, tt, combOp);
 	      break;
 	    }
@@ -2528,7 +2605,7 @@ void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) {
 
   // split up the bitmap
   x = 0;
-  for (i = 0; i <= grayMax; ++i) {
+  for (i = 0; i <= grayMax && i < patternDict->getSize(); ++i) {
     patternDict->setBitmap(i, bitmap->getSlice(x, 0, patternW, patternH));
     x += patternW;
   }
@@ -2679,6 +2756,10 @@ void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm,
     for (n = 0; n < gridW; ++n) {
       if (!(enableSkip && skipBitmap->getPixel(n, m))) {
 	patternBitmap = patternDict->getBitmap(grayImg[i]);
+	if (patternBitmap == NULL) {
+	  error(errSyntaxError, curStr->getPos(), "Bad pattern bitmap");
+	  return;
+	}
 	bitmap->combine(patternBitmap, xx >> 8, yy >> 8, combOp);
       }
       xx += stepX;
@@ -3135,7 +3216,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
 	    atx[2] >= -8 && atx[2] <= 8 &&
 	    atx[3] >= -8 && atx[3] <= 8) {
 	  // set up the adaptive context
-	  if (y + aty[0] >= 0) {
+	  if (y + aty[0] >= 0 && y + aty[0] < bitmap->getHeight()) {
 	    atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
 	    atBuf0 = *atP0++ << 8;
 	  } else {
@@ -3143,7 +3224,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
 	    atBuf0 = 0;
 	  }
 	  atShift0 = 15 - atx[0];
-	  if (y + aty[1] >= 0) {
+	  if (y + aty[1] >= 0 && y + aty[1] < bitmap->getHeight()) {
 	    atP1 = bitmap->getDataPtr() + (y + aty[1]) * bitmap->getLineSize();
 	    atBuf1 = *atP1++ << 8;
 	  } else {
@@ -3151,7 +3232,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
 	    atBuf1 = 0;
 	  }
 	  atShift1 = 15 - atx[1];
-	  if (y + aty[2] >= 0) {
+	  if (y + aty[2] >= 0 && y + aty[2] < bitmap->getHeight()) {
 	    atP2 = bitmap->getDataPtr() + (y + aty[2]) * bitmap->getLineSize();
 	    atBuf2 = *atP2++ << 8;
 	  } else {
@@ -3159,7 +3240,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
 	    atBuf2 = 0;
 	  }
 	  atShift2 = 15 - atx[2];
-	  if (y + aty[3] >= 0) {
+	  if (y + aty[3] >= 0 && y + aty[3] < bitmap->getHeight()) {
 	    atP3 = bitmap->getDataPtr() + (y + aty[3]) * bitmap->getLineSize();
 	    atBuf3 = *atP3++ << 8;
 	  } else {
@@ -3678,7 +3759,7 @@ void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
 				       refBitmap, 0, 0, atx, aty);
 
   // combine the region bitmap into the page bitmap
-  if (imm) {
+  if (imm && bitmap) {
     pageBitmap->combine(bitmap, x, y, extCombOp);
     delete bitmap;
 
commit 1d72c14b3877ae730ac0aa92f36923269e8a2004
Author: Thomas Freitag <Thomas.Freitag at alfa.de>
Date:   Wed Sep 26 11:48:14 2012 +0200

    Fix crash in 158.pdf.asan.d.451

diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc
index 9e07060..79c4900 100644
--- a/poppler/SplashOutputDev.cc
+++ b/poppler/SplashOutputDev.cc
@@ -2282,6 +2282,14 @@ GBool SplashOutputDev::beginType3Char(GfxState *state, double x, double y,
 
       // create new entry in the font cache
       if (nT3Fonts == splashOutT3FontCacheSize) {
+	t3gs = t3GlyphStack;
+	while (t3gs != NULL) {
+	  if (t3gs->cache == t3FontCache[nT3Fonts - 1]) {
+	    error(errSyntaxWarning, -1, "t3FontCache reaches limit but font still on stack in SplashOutputDev::beginType3Char");
+	    return gTrue;
+	  }
+	  t3gs = t3gs->next;
+	}
 	delete t3FontCache[nT3Fonts - 1];
 	--nT3Fonts;
       }


More information about the poppler mailing list