summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Astals Cid <aacid@kde.org>2009-10-16 23:17:22 +0200
committerAlbert Astals Cid <aacid@kde.org>2009-10-16 23:17:22 +0200
commit1082e1671afd8ab91583dabc876304008acb021c (patch)
treeb7201d70ac474f3ce0cc4e5e36ec6176205bac14
parentc2458275e02f56226779b82d73c13defcbbda563 (diff)
Some "security" fixes based on newly released Xpdf 3.02pl4
-rw-r--r--poppler/Stream.cc4
-rw-r--r--poppler/XRef.cc19
-rw-r--r--splash/Splash.cc7
-rw-r--r--splash/SplashBitmap.cc37
-rw-r--r--splash/SplashErrorCodes.h4
5 files changed, 59 insertions, 12 deletions
diff --git a/poppler/Stream.cc b/poppler/Stream.cc
index 7137c5ea..6634317a 100644
--- a/poppler/Stream.cc
+++ b/poppler/Stream.cc
@@ -405,6 +405,10 @@ ImageStream::ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA) {
} 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 --git a/poppler/XRef.cc b/poppler/XRef.cc
index 832a0384..e5fd92a7 100644
--- a/poppler/XRef.cc
+++ b/poppler/XRef.cc
@@ -76,6 +76,8 @@ public:
// generation 0.
ObjectStream(XRef *xref, int objStrNumA);
+ GBool isOk() { return ok; }
+
~ObjectStream();
// Return the object number of this object stream.
@@ -91,6 +93,7 @@ private:
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) {
@@ -104,6 +107,7 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
nObjects = 0;
objs = NULL;
objNums = NULL;
+ ok = gFalse;
if (!xref->fetch(objStrNum, 0, &objStr)->isStream()) {
goto err1;
@@ -129,11 +133,13 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
goto err1;
}
- if (nObjects >= INT_MAX / (int)sizeof(int)) {
- error(-1, "Invalid 'nObjects'");
+ // 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));
@@ -190,10 +196,10 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
}
gfree(offsets);
+ ok = gTrue;
err1:
objStr.free();
- return;
}
ObjectStream::~ObjectStream() {
@@ -970,6 +976,11 @@ Object *XRef::fetch(int num, int gen, Object *obj) {
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 --git a/splash/Splash.cc b/splash/Splash.cc
index a1deb854..834cb109 100644
--- a/splash/Splash.cc
+++ b/splash/Splash.cc
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <string.h>
+#include <limits.h>
#include "goo/gmem.h"
#include "SplashErrorCodes.h"
#include "SplashMath.h"
@@ -2001,6 +2002,9 @@ SplashError Splash::fillImageMask(SplashImageMaskSource src, void *srcData,
xq = w % scaledWidth;
// allocate pixel buffer
+ if (yp < 0 || yp > INT_MAX - 1) {
+ return splashErrBadArg;
+ }
pixBuf = (SplashColorPtr)gmallocn((yp + 1), w);
// initialize the pixel pipe
@@ -2301,6 +2305,9 @@ SplashError Splash::drawImage(SplashImageSource src, void *srcData,
xq = w % scaledWidth;
// allocate pixel buffers
+ if (yp < 0 || yp > INT_MAX - 1) {
+ return splashErrBadArg;
+ }
colorBuf = (SplashColorPtr)gmallocn3((yp + 1), w, nComps);
if (srcAlpha) {
alphaBuf = (Guchar *)gmallocn((yp + 1), w);
diff --git a/splash/SplashBitmap.cc b/splash/SplashBitmap.cc
index 2337a62c..999efd1a 100644
--- a/splash/SplashBitmap.cc
+++ b/splash/SplashBitmap.cc
@@ -29,6 +29,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <limits.h>
#include "goo/gmem.h"
#include "SplashErrorCodes.h"
#include "SplashBitmap.h"
@@ -48,26 +49,48 @@ SplashBitmap::SplashBitmap(int widthA, int heightA, int rowPad,
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;
case splashModeXBGR8:
- rowSize = width * 4;
+ if (width > 0 && width <= INT_MAX / 4) {
+ rowSize = width * 4;
+ } 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;
+ if (rowSize > 0) {
+ rowSize += rowPad - 1;
+ rowSize -= rowSize % rowPad;
+ }
data = (SplashColorPtr)gmallocn(rowSize, height);
if (!topDown) {
data += (height - 1) * rowSize;
diff --git a/splash/SplashErrorCodes.h b/splash/SplashErrorCodes.h
index 9c309826..d1f81f85 100644
--- a/splash/SplashErrorCodes.h
+++ b/splash/SplashErrorCodes.h
@@ -41,7 +41,9 @@
#define splashErrSingularMatrix 8 // matrix is singular
-#define splashErrZeroImage 9 // image of 0x0
+#define splashErrBadArg 9 // bad argument
+
+#define splashErrZeroImage 254 // image of 0x0
#define splashErrGeneric 255