Commit 0f97bca0 authored by Enrico Ros's avatar Enrico Ros
Browse files

Synced to HEAD. Merging security fixes in xpdf.

svn path=/branches/kpdf_experiments/kdegraphics/kpdf/; revision=356974
parent a5ddb766
......@@ -64,6 +64,15 @@ Catalog::Catalog(XRef *xrefA) {
}
pagesSize = numPages0 = (int)obj.getNum();
obj.free();
// The gcc doesnt optimize this away, so this check is ok,
// even if it looks like a pagesSize != pagesSize check
if (pagesSize*sizeof(Page *)/sizeof(Page *) != (unsigned int)pagesSize ||
pagesSize*sizeof(Ref)/sizeof(Ref) != (unsigned int)pagesSize) {
error(-1, "Invalid 'pagesSize'");
ok = gFalse;
return;
}
pages = (Page **)gmalloc(pagesSize * sizeof(Page *));
pageRefs = (Ref *)gmalloc(pagesSize * sizeof(Ref));
for (i = 0; i < pagesSize; ++i) {
......@@ -191,6 +200,11 @@ int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start) {
}
if (start >= pagesSize) {
pagesSize += 32;
if (pagesSize*sizeof(Page *)/sizeof(Page *) != (unsigned int)pagesSize ||
pagesSize*sizeof(Ref)/sizeof(Ref) != (unsigned int)pagesSize) {
error(-1, "Invalid 'pagesSize' parameter.");
goto err3;
}
pages = (Page **)grealloc(pages, pagesSize * sizeof(Page *));
pageRefs = (Ref *)grealloc(pageRefs, pagesSize * sizeof(Ref));
for (j = pagesSize - 32; j < pagesSize; ++j) {
......
......@@ -96,7 +96,7 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
}
nObjects = obj1.getInt();
obj1.free();
if (nObjects == 0) {
if (nObjects <= 0) {
goto err1;
}
......@@ -106,7 +106,15 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
}
first = obj1.getInt();
obj1.free();
if (first < 0) {
goto err1;
}
if (nObjects*sizeof(int)/sizeof(int) != (uint)nObjects) {
error(-1, "Invalid 'nObjects'");
goto err1;
}
objs = new Object[nObjects];
objNums = (int *)gmalloc(nObjects * sizeof(int));
offsets = (int *)gmalloc(nObjects * sizeof(int));
......@@ -130,6 +138,12 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
offsets[i] = obj2.getInt();
obj1.free();
obj2.free();
if (objNums[i] < 0 || offsets[i] < 0 ||
(i > 0 && offsets[i] < offsets[i-1])) {
delete parser;
gfree(offsets);
goto err1;
}
}
while (str->getChar() != EOF) ;
delete parser;
......@@ -369,10 +383,21 @@ GBool XRef::readXRefTable(Parser *parser, Guint *pos) {
}
n = obj.getInt();
obj.free();
if (first < 0 || n < 0 || first + n < 0) {
goto err1;
}
if (first + n > size) {
for (newSize = size ? 2 * size : 1024;
first + n > newSize;
first + n > newSize && newSize > 0;
newSize <<= 1) ;
if (newSize < 0) {
goto err1;
}
if (newSize*sizeof(XRefEntry)/sizeof(XRefEntry) != (uint)newSize) {
error(-1, "Invalid 'obj' parameters'");
goto err1;
}
entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry));
for (i = size; i < newSize; ++i) {
entries[i].offset = 0xffffffff;
......@@ -443,7 +468,7 @@ GBool XRef::readXRefTable(Parser *parser, Guint *pos) {
// check for an 'XRefStm' key
if (obj.getDict()->lookup("XRefStm", &obj2)->isInt()) {
pos2 = obj2.getInt();
pos2 = (Guint)obj2.getInt();
readXRef(&pos2);
if (!ok) {
goto err1;
......@@ -474,7 +499,14 @@ GBool XRef::readXRefStream(Stream *xrefStr, Guint *pos) {
}
newSize = obj.getInt();
obj.free();
if (newSize < 0) {
goto err1;
}
if (newSize > size) {
if (newSize * sizeof(XRefEntry)/sizeof(XRefEntry) != (uint)newSize) {
error(-1, "Invalid 'size' parameter.");
return gFalse;
}
entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry));
for (i = size; i < newSize; ++i) {
entries[i].offset = 0xffffffff;
......@@ -494,6 +526,9 @@ GBool XRef::readXRefStream(Stream *xrefStr, Guint *pos) {
}
w[i] = obj2.getInt();
obj2.free();
if (w[i] < 0 || w[i] > 4) {
goto err1;
}
}
obj.free();
......@@ -513,13 +548,14 @@ GBool XRef::readXRefStream(Stream *xrefStr, Guint *pos) {
}
n = obj.getInt();
obj.free();
if (!readXRefStreamSection(xrefStr, w, first, n)) {
if (first < 0 || n < 0 ||
!readXRefStreamSection(xrefStr, w, first, n)) {
idx.free();
goto err0;
}
}
} else {
if (!readXRefStreamSection(xrefStr, w, 0, size)) {
if (!readXRefStreamSection(xrefStr, w, 0, newSize)) {
idx.free();
goto err0;
}
......@@ -551,10 +587,20 @@ GBool XRef::readXRefStreamSection(Stream *xrefStr, int *w, int first, int n) {
Guint offset;
int type, gen, c, newSize, i, j;
if (first + n < 0) {
return gFalse;
}
if (first + n > size) {
for (newSize = size ? 2 * size : 1024;
first + n > newSize;
first + n > newSize && newSize > 0;
newSize <<= 1) ;
if (newSize < 0) {
return gFalse;
}
if (newSize*sizeof(XRefEntry)/sizeof(XRefEntry) != (uint)newSize) {
error(-1, "Invalid 'size' inside xref table.");
return gFalse;
}
entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry));
for (i = size; i < newSize; ++i) {
entries[i].offset = 0xffffffff;
......@@ -585,24 +631,26 @@ GBool XRef::readXRefStreamSection(Stream *xrefStr, int *w, int first, int n) {
}
gen = (gen << 8) + c;
}
switch (type) {
case 0:
entries[i].offset = offset;
entries[i].gen = gen;
entries[i].type = xrefEntryFree;
break;
case 1:
entries[i].offset = offset;
entries[i].gen = gen;
entries[i].type = xrefEntryUncompressed;
break;
case 2:
entries[i].offset = offset;
entries[i].gen = gen;
entries[i].type = xrefEntryCompressed;
break;
default:
return gFalse;
if (entries[i].offset == 0xffffffff) {
switch (type) {
case 0:
entries[i].offset = offset;
entries[i].gen = gen;
entries[i].type = xrefEntryFree;
break;
case 1:
entries[i].offset = offset;
entries[i].gen = gen;
entries[i].type = xrefEntryUncompressed;
break;
case 2:
entries[i].offset = offset;
entries[i].gen = gen;
entries[i].type = xrefEntryCompressed;
break;
default:
return gFalse;
}
}
}
......@@ -664,38 +712,48 @@ GBool XRef::constructXRef() {
// look for object
} else if (isdigit(*p)) {
num = atoi(p);
do {
++p;
} while (*p && isdigit(*p));
if (isspace(*p)) {
if (num > 0) {
do {
++p;
} while (*p && isspace(*p));
if (isdigit(*p)) {
gen = atoi(p);
} while (*p && isdigit(*p));
if (isspace(*p)) {
do {
++p;
} while (*p && isdigit(*p));
if (isspace(*p)) {
} while (*p && isspace(*p));
if (isdigit(*p)) {
gen = atoi(p);
do {
++p;
} while (*p && isspace(*p));
if (!strncmp(p, "obj", 3)) {
if (num >= size) {
newSize = (num + 1 + 255) & ~255;
entries = (XRefEntry *)
grealloc(entries, newSize * sizeof(XRefEntry));
for (i = size; i < newSize; ++i) {
entries[i].offset = 0xffffffff;
entries[i].type = xrefEntryFree;
} while (*p && isdigit(*p));
if (isspace(*p)) {
do {
++p;
} while (*p && isspace(*p));
if (!strncmp(p, "obj", 3)) {
if (num >= size) {
newSize = (num + 1 + 255) & ~255;
if (newSize < 0) {
error(-1, "Bad object number");
return gFalse;
}
if (newSize*sizeof(XRefEntry)/sizeof(XRefEntry) != (uint)newSize) {
error(-1, "Invalid 'obj' parameters.");
return gFalse;
}
entries = (XRefEntry *)
grealloc(entries, newSize * sizeof(XRefEntry));
for (i = size; i < newSize; ++i) {
entries[i].offset = 0xffffffff;
entries[i].type = xrefEntryFree;
}
size = newSize;
}
if (entries[num].type == xrefEntryFree ||
gen >= entries[num].gen) {
entries[num].offset = pos - start;
entries[num].gen = gen;
entries[num].type = xrefEntryUncompressed;
}
size = newSize;
}
if (entries[num].type == xrefEntryFree ||
gen >= entries[num].gen) {
entries[num].offset = pos - start;
entries[num].gen = gen;
entries[num].type = xrefEntryUncompressed;
}
}
}
......@@ -705,6 +763,10 @@ GBool XRef::constructXRef() {
} else if (!strncmp(p, "endstream", 9)) {
if (streamEndsLen == streamEndsSize) {
streamEndsSize += 64;
if (streamEndsSize*sizeof(int)/sizeof(int) != (uint)streamEndsSize) {
error(-1, "Invalid 'endstream' parameter.");
return gFalse;
}
streamEnds = (Guint *)grealloc(streamEnds,
streamEndsSize * sizeof(int));
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment