[poppler] 8 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 06:00:28 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 397d7b4597ad4bc8ab41fd7a99078473a3c93eb0
Merge: 6013d49... 2c0f70a...
Author: Albert Astals Cid <aacid at kde.org>
Date: Wed Sep 26 15:00:04 2012 +0200
Merge remote-tracking branch 'origin/poppler-0.20'
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