Official patch http://www.foolabs.com/xpdf/xpdf-3.02pl4.patch Update of xpdfVersion in xpdf-3.02/xpdf/config.h diff -ur -N xpdf-3.02.orig/splash/Splash.cc xpdf-3.02/splash/Splash.cc --- xpdf-3.02.orig/splash/Splash.cc 2007-02-27 23:05:52.000000000 +0100 +++ xpdf-3.02/splash/Splash.cc 2009-08-14 23:05:08.000000000 +0200 @@ -12,6 +12,7 @@ #include #include +#include #include "gmem.h" #include "SplashErrorCodes.h" #include "SplashMath.h" @@ -1912,7 +1913,10 @@ xq = w % scaledWidth; // allocate pixel buffer - pixBuf = (SplashColorPtr)gmalloc((yp + 1) * w); + if (yp < 0 || yp > INT_MAX - 1) { + return splashErrBadArg; + } + pixBuf = (SplashColorPtr)gmallocn(yp + 1, w); // initialize the pixel pipe pipeInit(&pipe, 0, 0, state->fillPattern, NULL, state->fillAlpha, @@ -2208,9 +2212,12 @@ xq = w % scaledWidth; // allocate pixel buffers - colorBuf = (SplashColorPtr)gmalloc((yp + 1) * w * nComps); + if (yp < 0 || yp > INT_MAX - 1 || w > INT_MAX / nComps) { + return splashErrBadArg; + } + colorBuf = (SplashColorPtr)gmallocn(yp + 1, w * nComps); if (srcAlpha) { - alphaBuf = (Guchar *)gmalloc((yp + 1) * w); + alphaBuf = (Guchar *)gmallocn(yp + 1, w); } else { alphaBuf = NULL; } diff -ur -N xpdf-3.02.orig/splash/SplashBitmap.cc xpdf-3.02/splash/SplashBitmap.cc --- xpdf-3.02.orig/splash/SplashBitmap.cc 2007-02-27 23:05:52.000000000 +0100 +++ xpdf-3.02/splash/SplashBitmap.cc 2009-08-19 23:35:39.000000000 +0200 @@ -11,6 +11,7 @@ #endif #include +#include #include "gmem.h" #include "SplashErrorCodes.h" #include "SplashBitmap.h" @@ -27,30 +28,48 @@ mode = modeA; switch (mode) { case splashModeMono1: - rowSize = (width + 7) >> 3; + if (width > 0) { + rowSize = (width + 7) >> 3; + } else { + rowSize = -1; + } break; case splashModeMono8: - rowSize = width; + if (width > 0) { + rowSize = width; + } else { + rowSize = -1; + } break; case splashModeRGB8: case splashModeBGR8: - rowSize = width * 3; + if (width > 0 && width <= INT_MAX / 3) { + rowSize = width * 3; + } else { + rowSize = -1; + } break; #if SPLASH_CMYK case splashModeCMYK8: - rowSize = width * 4; + if (width > 0 && width <= INT_MAX / 4) { + rowSize = width * 4; + } else { + rowSize = -1; + } break; #endif } - rowSize += rowPad - 1; - rowSize -= rowSize % rowPad; - data = (SplashColorPtr)gmalloc(rowSize * height); + if (rowSize > 0) { + rowSize += rowPad - 1; + rowSize -= rowSize % rowPad; + } + data = (SplashColorPtr)gmallocn(height, rowSize); if (!topDown) { data += (height - 1) * rowSize; rowSize = -rowSize; } if (alphaA) { - alpha = (Guchar *)gmalloc(width * height); + alpha = (Guchar *)gmallocn(width, height); } else { alpha = NULL; } diff -ur -N xpdf-3.02.orig/splash/SplashErrorCodes.h xpdf-3.02/splash/SplashErrorCodes.h --- xpdf-3.02.orig/splash/SplashErrorCodes.h 2007-02-27 23:05:52.000000000 +0100 +++ xpdf-3.02/splash/SplashErrorCodes.h 2009-08-14 23:03:46.000000000 +0200 @@ -29,4 +29,6 @@ #define splashErrSingularMatrix 8 // matrix is singular +#define splashErrBadArg 9 // bad argument + #endif diff -ur -N xpdf-3.02.orig/xpdf/PSOutputDev.cc xpdf-3.02/xpdf/PSOutputDev.cc --- xpdf-3.02.orig/xpdf/PSOutputDev.cc 2007-02-27 23:05:52.000000000 +0100 +++ xpdf-3.02/xpdf/PSOutputDev.cc 2009-10-02 21:38:58.000000000 +0200 @@ -4301,7 +4301,7 @@ width, -height, height); // allocate a line buffer - lineBuf = (Guchar *)gmalloc(4 * width); + lineBuf = (Guchar *)gmallocn(width, 4); // set up to process the data stream imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), diff -ur -N xpdf-3.02.orig/xpdf/Stream.cc xpdf-3.02/xpdf/Stream.cc --- xpdf-3.02.orig/xpdf/Stream.cc 2007-11-12 13:27:21.000000000 +0100 +++ xpdf-3.02/xpdf/Stream.cc 2009-10-05 20:07:49.000000000 +0200 @@ -323,6 +323,10 @@ } else { imgLineSize = nVals; } + if (width > INT_MAX / nComps) { + // force a call to gmallocn(-1,...), which will throw an exception + imgLineSize = -1; + } imgLine = (Guchar *)gmallocn(imgLineSize, sizeof(Guchar)); imgIdx = nVals; } diff -ur -N xpdf-3.02.orig/xpdf/XRef.cc xpdf-3.02/xpdf/XRef.cc --- xpdf-3.02.orig/xpdf/XRef.cc 2007-02-27 23:05:52.000000000 +0100 +++ xpdf-3.02/xpdf/XRef.cc 2009-08-14 23:05:08.000000000 +0200 @@ -52,6 +52,8 @@ // generation 0. ObjectStream(XRef *xref, int objStrNumA); + GBool isOk() { return ok; } + ~ObjectStream(); // Return the object number of this object stream. @@ -67,6 +69,7 @@ int nObjects; // number of objects in the stream Object *objs; // the objects (length = nObjects) int *objNums; // the object numbers (length = nObjects) + GBool ok; }; ObjectStream::ObjectStream(XRef *xref, int objStrNumA) { @@ -80,6 +83,7 @@ nObjects = 0; objs = NULL; objNums = NULL; + ok = gFalse; if (!xref->fetch(objStrNum, 0, &objStr)->isStream()) { goto err1; @@ -105,6 +109,13 @@ goto err1; } + // this is an arbitrary limit to avoid integer overflow problems + // in the 'new Object[nObjects]' call (Acrobat apparently limits + // object streams to 100-200 objects) + if (nObjects > 1000000) { + error(-1, "Too many objects in an object stream"); + goto err1; + } objs = new Object[nObjects]; objNums = (int *)gmallocn(nObjects, sizeof(int)); offsets = (int *)gmallocn(nObjects, sizeof(int)); @@ -161,10 +172,10 @@ } gfree(offsets); + ok = gTrue; err1: objStr.free(); - return; } ObjectStream::~ObjectStream() { @@ -837,6 +848,11 @@ delete objStr; } objStr = new ObjectStream(this, e->offset); + if (!objStr->isOk()) { + delete objStr; + objStr = NULL; + goto err; + } } objStr->getObject(e->gen, num, obj); break; diff -ur -N xpdf-3.02.orig/xpdf/config.h xpdf-3.02/xpdf/config.h --- xpdf-3.02.orig/xpdf/config.h 2009-03-31 19:55:23.000000000 +0200 +++ xpdf-3.02/xpdf/config.h 2009-10-15 13:37:21.000000000 +0200 @@ -17,7 +17,7 @@ //------------------------------------------------------------------------ // xpdf version -#define xpdfVersion "3.02pl3" +#define xpdfVersion "3.02pl4" #define xpdfVersionNum 3.02 #define xpdfMajorVersion 3 #define xpdfMinorVersion 2