summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Lohrke <carlo@gentoo.org>2004-11-03 17:35:58 +0000
committerCarsten Lohrke <carlo@gentoo.org>2004-11-03 17:35:58 +0000
commit1f0af5330fcc606b08d76b80006107c2f1d5010c (patch)
tree1dbed06741b5b6d40843b63bbf11b4484423dcfe /kde-base/kdegraphics
parentmarked 0.7.3 as ~mips for testing and 0.7.2 as stable. (diff)
downloadhistorical-1f0af5330fcc606b08d76b80006107c2f1d5010c.tar.gz
historical-1f0af5330fcc606b08d76b80006107c2f1d5010c.tar.bz2
historical-1f0af5330fcc606b08d76b80006107c2f1d5010c.zip
integer overflow vulnerability, #69936
Diffstat (limited to 'kde-base/kdegraphics')
-rw-r--r--kde-base/kdegraphics/ChangeLog11
-rw-r--r--kde-base/kdegraphics/Manifest41
-rw-r--r--kde-base/kdegraphics/files/digest-kdegraphics-3.2.3-r21
-rw-r--r--kde-base/kdegraphics/files/digest-kdegraphics-3.3.0-r21
-rw-r--r--kde-base/kdegraphics/files/digest-kdegraphics-3.3.1-r21
-rw-r--r--kde-base/kdegraphics/files/post-3.2.3-kdegraphics_2.diff92
-rw-r--r--kde-base/kdegraphics/files/post-3.3.0-kdegraphics_2.diff1081
-rw-r--r--kde-base/kdegraphics/files/post-3.3.1-kdegraphics_2.diff115
-rw-r--r--kde-base/kdegraphics/kdegraphics-3.2.3-r2.ebuild45
-rw-r--r--kde-base/kdegraphics/kdegraphics-3.3.0-r1.ebuild5
-rw-r--r--kde-base/kdegraphics/kdegraphics-3.3.0-r2.ebuild55
-rw-r--r--kde-base/kdegraphics/kdegraphics-3.3.1-r2.ebuild55
12 files changed, 1484 insertions, 19 deletions
diff --git a/kde-base/kdegraphics/ChangeLog b/kde-base/kdegraphics/ChangeLog
index a0af5662ccf7..ce5d3652dbad 100644
--- a/kde-base/kdegraphics/ChangeLog
+++ b/kde-base/kdegraphics/ChangeLog
@@ -1,6 +1,15 @@
# ChangeLog for kde-base/kdegraphics
# Copyright 2002-2004 Gentoo Foundation; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/kde-base/kdegraphics/ChangeLog,v 1.119 2004/10/27 22:10:09 kugelfang Exp $
+# $Header: /var/cvsroot/gentoo-x86/kde-base/kdegraphics/ChangeLog,v 1.120 2004/11/03 17:35:57 carlo Exp $
+
+*kdegraphics-3.3.1-r2 (03 Nov 2004)
+
+ 03 Nov 2004; Carsten Lohrke <carlo@gentoo.org>
+ +files/post-3.2.3-kdegraphics_2.diff, +files/post-3.3.0-kdegraphics_2.diff,
+ +files/post-3.3.1-kdegraphics_2.diff, +kdegraphics-3.2.3-r2.ebuild,
+ kdegraphics-3.3.0-r1.ebuild, +kdegraphics-3.3.0-r2.ebuild,
+ +kdegraphics-3.3.1-r2.ebuild:
+ integer overflow vulnerability, #69936
28 Oct 2004; Danny van Dyk <kugelfang@gentoo.org>
kdegraphics-3.2.3-r1.ebuild, kdegraphics-3.3.0-r1.ebuild:
diff --git a/kde-base/kdegraphics/Manifest b/kde-base/kdegraphics/Manifest
index 34da4f5047ae..66879c19456a 100644
--- a/kde-base/kdegraphics/Manifest
+++ b/kde-base/kdegraphics/Manifest
@@ -1,25 +1,34 @@
-MD5 0e300e181e98876d232659540fc22481 ChangeLog 16387
-MD5 feb2b4270d15a98a32173a5ae04a19fb kdegraphics-3.1.5.ebuild 1048
-MD5 d34737e0c554fe641ce3a353c8b7fe8d kdegraphics-3.2.0.ebuild 1330
-MD5 5a60aa7288a3e688931b84fce55c4b6a kdegraphics-3.3.0.ebuild 1430
-MD5 14889ab75f97d76e58b0c1154e7683a9 metadata.xml 161
MD5 0c557af25ca14e9133483d1ff8414c74 kdegraphics-3.2.2.ebuild 1224
-MD5 8e48bc60a542000e2ca8ca2173a21113 kdegraphics-3.2.3.ebuild 1226
+MD5 e720f7455cef7015497f5ad795a6108b kdegraphics-3.2.3-r2.ebuild 1280
+MD5 5a60aa7288a3e688931b84fce55c4b6a kdegraphics-3.3.0.ebuild 1430
+MD5 fbd70cd93878a0622071cf149368b28e kdegraphics-3.3.0-r2.ebuild 1486
MD5 0dcbff375e401ca8c354637670a32c43 kdegraphics-3.3.1-r1.ebuild 1485
-MD5 6b3fabad5f11df10503b136be549dc16 kdegraphics-3.3.1.ebuild 1434
MD5 749ee0be0aab8c1f4ee11978a8d16ae2 kdegraphics-3.2.3-r1.ebuild 1278
-MD5 56a089ed5daa7593c3de723de82c04d3 kdegraphics-3.3.0-r1.ebuild 1485
-MD5 80f49f2fcc0bb31559666e47fc28b047 files/digest-kdegraphics-3.2.2 71
+MD5 f8ea687ae1a7ff4a4771f5cf4050a125 kdegraphics-3.3.0-r1.ebuild 1499
+MD5 feb2b4270d15a98a32173a5ae04a19fb kdegraphics-3.1.5.ebuild 1048
+MD5 8e48bc60a542000e2ca8ca2173a21113 kdegraphics-3.2.3.ebuild 1226
+MD5 6b3fabad5f11df10503b136be549dc16 kdegraphics-3.3.1.ebuild 1434
+MD5 72fc1a303f72c2ca82bd65b874f8596c ChangeLog 16752
+MD5 aa961a56755f8305d8d4e979059f5845 kdegraphics-3.3.1-r2.ebuild 1487
+MD5 d34737e0c554fe641ce3a353c8b7fe8d kdegraphics-3.2.0.ebuild 1330
+MD5 14889ab75f97d76e58b0c1154e7683a9 metadata.xml 161
+MD5 33d7a652f3ae6f9e66d79fb818b684f6 files/digest-kdegraphics-3.3.0-r1 71
+MD5 33d7a652f3ae6f9e66d79fb818b684f6 files/digest-kdegraphics-3.3.0-r2 71
+MD5 fecf5cb3209323e56be3368df325411a files/digest-kdegraphics-3.3.1-r1 71
+MD5 fecf5cb3209323e56be3368df325411a files/digest-kdegraphics-3.3.1-r2 71
+MD5 eb03ab721af71700a0b445f1c50b55f8 files/kdegraphics-3.2.2-gcc34-compile.patch 7723
MD5 78ab0a172f24863df0ba35300e95a890 files/digest-kdegraphics-3.1.5 71
MD5 8c9db7f8d52169b544da66be07e9979a files/digest-kdegraphics-3.2.0 71
-MD5 33d7a652f3ae6f9e66d79fb818b684f6 files/digest-kdegraphics-3.3.0 71
-MD5 eb03ab721af71700a0b445f1c50b55f8 files/kdegraphics-3.2.2-gcc34-compile.patch 7723
+MD5 80f49f2fcc0bb31559666e47fc28b047 files/digest-kdegraphics-3.2.2 71
MD5 e43eeb201ab38aa05917d4de1573ff59 files/digest-kdegraphics-3.2.3 71
+MD5 33d7a652f3ae6f9e66d79fb818b684f6 files/digest-kdegraphics-3.3.0 71
MD5 fecf5cb3209323e56be3368df325411a files/digest-kdegraphics-3.3.1 71
-MD5 d97c962408abd235435f6857fc405ebf files/kdegraphics-3.2.3-gcc34-compile.patch 7162
-MD5 fecf5cb3209323e56be3368df325411a files/digest-kdegraphics-3.3.1-r1 71
-MD5 e43eeb201ab38aa05917d4de1573ff59 files/digest-kdegraphics-3.2.3-r1 71
-MD5 33d7a652f3ae6f9e66d79fb818b684f6 files/digest-kdegraphics-3.3.0-r1 71
+MD5 8d995a343d5083ba8ac84f1d4136d359 files/xpdf-3.3.0-kdegraphics.diff 1630
MD5 4f854adb507f4d04e997702e44ffc2ea files/post-3.2.3-kdegraphics.diff 3853
+MD5 d97c962408abd235435f6857fc405ebf files/kdegraphics-3.2.3-gcc34-compile.patch 7162
+MD5 a93abae30c47739bd9247d230d1769d2 files/post-3.3.0-kdegraphics_2.diff 26941
+MD5 870d90051bb236753070fb553890f95d files/post-3.2.3-kdegraphics_2.diff 3205
MD5 651fba579516ea947fbefee373f40a6c files/post-3.3.1-kdegraphics.diff 1533
-MD5 8d995a343d5083ba8ac84f1d4136d359 files/xpdf-3.3.0-kdegraphics.diff 1630
+MD5 6c3f55477c5f566c711563caa3c51296 files/post-3.3.1-kdegraphics_2.diff 3887
+MD5 e43eeb201ab38aa05917d4de1573ff59 files/digest-kdegraphics-3.2.3-r1 71
+MD5 e43eeb201ab38aa05917d4de1573ff59 files/digest-kdegraphics-3.2.3-r2 71
diff --git a/kde-base/kdegraphics/files/digest-kdegraphics-3.2.3-r2 b/kde-base/kdegraphics/files/digest-kdegraphics-3.2.3-r2
new file mode 100644
index 000000000000..2e0072d98c01
--- /dev/null
+++ b/kde-base/kdegraphics/files/digest-kdegraphics-3.2.3-r2
@@ -0,0 +1 @@
+MD5 af7092f2afc5a8565eb5017ecee6b67e kdegraphics-3.2.3.tar.bz2 5676995
diff --git a/kde-base/kdegraphics/files/digest-kdegraphics-3.3.0-r2 b/kde-base/kdegraphics/files/digest-kdegraphics-3.3.0-r2
new file mode 100644
index 000000000000..6aa32ec56f90
--- /dev/null
+++ b/kde-base/kdegraphics/files/digest-kdegraphics-3.3.0-r2
@@ -0,0 +1 @@
+MD5 7bb9843f7b03cd2716079ac83b9c9304 kdegraphics-3.3.0.tar.bz2 6444906
diff --git a/kde-base/kdegraphics/files/digest-kdegraphics-3.3.1-r2 b/kde-base/kdegraphics/files/digest-kdegraphics-3.3.1-r2
new file mode 100644
index 000000000000..484cea392932
--- /dev/null
+++ b/kde-base/kdegraphics/files/digest-kdegraphics-3.3.1-r2
@@ -0,0 +1 @@
+MD5 18f063ec6fad27b304ae97cf4b480140 kdegraphics-3.3.1.tar.bz2 6419816
diff --git a/kde-base/kdegraphics/files/post-3.2.3-kdegraphics_2.diff b/kde-base/kdegraphics/files/post-3.2.3-kdegraphics_2.diff
new file mode 100644
index 000000000000..4f8401096c8e
--- /dev/null
+++ b/kde-base/kdegraphics/files/post-3.2.3-kdegraphics_2.diff
@@ -0,0 +1,92 @@
+--- kdegraphics/kpdf/xpdf/Catalog.cc 2003/08/20 21:25:12 1.3
++++ kdegraphics/kpdf/xpdf/Catalog.cc 2004/10/28 09:25:05 1.3.2.3
+@@ -12,6 +12,7 @@
+ #pragma implementation
+ #endif
+
++#include <limits.h>
+ #include <stddef.h>
+ #include "gmem.h"
+ #include "Object.h"
+@@ -63,6 +64,12 @@ Catalog::Catalog(XRef *xrefA) {
+ }
+ pagesSize = numPages0 = obj.getInt();
+ obj.free();
++ if ((unsigned) pagesSize >= INT_MAX / sizeof(Page *) ||
++ (unsigned) pagesSize >= INT_MAX / sizeof(Ref)) {
++ 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) {
+@@ -190,6 +197,11 @@ int Catalog::readPageTree(Dict *pagesDic
+ }
+ if (start >= pagesSize) {
+ pagesSize += 32;
++ if ((unsigned) pagesSize >= INT_MAX / sizeof(Page *) ||
++ (unsigned) pagesSize >= INT_MAX / sizeof(Ref)) {
++ 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) {
+--- kdegraphics/kpdf/xpdf/XRef.cc 2003/08/20 21:25:12 1.3
++++ kdegraphics/kpdf/xpdf/XRef.cc 2004/10/28 09:35:21 1.3.2.4
+@@ -12,6 +12,7 @@
+ #pragma implementation
+ #endif
+
++#include <limits.h>
+ #include <stdlib.h>
+ #include <stddef.h>
+ #include <string.h>
+@@ -76,6 +77,12 @@ XRef::XRef(BaseStream *strA, GString *ow
+
+ // trailer is ok - read the xref table
+ } else {
++ if ((unsigned) size >= INT_MAX / sizeof(XRefEntry)) {
++ error(-1, "Invalid 'size' inside xref table.");
++ ok = gFalse;
++ errCode = errDamaged;
++ return;
++ }
+ entries = (XRefEntry *)gmalloc(size * sizeof(XRefEntry));
+ for (i = 0; i < size; ++i) {
+ entries[i].offset = 0xffffffff;
+@@ -267,6 +274,10 @@ GBool XRef::readXRef(Guint *pos) {
+ // table size
+ if (first + n > size) {
+ newSize = size + 256;
++ if ((unsigned) newSize >= INT_MAX / sizeof(XRefEntry)) {
++ error(-1, "Invalid 'newSize'");
++ goto err2;
++ }
+ entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry));
+ for (i = size; i < newSize; ++i) {
+ entries[i].offset = 0xffffffff;
+@@ -415,6 +426,10 @@ GBool XRef::constructXRef() {
+ if (!strncmp(p, "obj", 3)) {
+ if (num >= size) {
+ newSize = (num + 1 + 255) & ~255;
++ if ((unsigned) newSize >= INT_MAX / sizeof(XRefEntry)) {
++ error(-1, "Invalid 'obj' parameters.");
++ return gFalse;
++ }
+ entries = (XRefEntry *)
+ grealloc(entries, newSize * sizeof(XRefEntry));
+ for (i = size; i < newSize; ++i) {
+@@ -436,6 +451,11 @@ GBool XRef::constructXRef() {
+ } else if (!strncmp(p, "endstream", 9)) {
+ if (streamEndsLen == streamEndsSize) {
+ streamEndsSize += 64;
++ if ((unsigned) streamEndsSize >= INT_MAX / sizeof(int)) {
++ error(-1, "Invalid 'endstream' parameter.");
++ return gFalse;
++ }
++
+ streamEnds = (Guint *)grealloc(streamEnds,
+ streamEndsSize * sizeof(int));
+ }
diff --git a/kde-base/kdegraphics/files/post-3.3.0-kdegraphics_2.diff b/kde-base/kdegraphics/files/post-3.3.0-kdegraphics_2.diff
new file mode 100644
index 000000000000..23ddb97bdba6
--- /dev/null
+++ b/kde-base/kdegraphics/files/post-3.3.0-kdegraphics_2.diff
@@ -0,0 +1,1081 @@
+--- kdegraphics/kpdf/xpdf/Catalog.cc 2003/08/20 21:25:12 1.3
++++ kdegraphics/kpdf/xpdf/Catalog.cc 2004/10/28 09:42:53 1.3.4.4
+@@ -12,6 +12,7 @@
+ #pragma implementation
+ #endif
+
++#include <limits.h>
+ #include <stddef.h>
+ #include "gmem.h"
+ #include "Object.h"
+@@ -56,13 +57,22 @@ Catalog::Catalog(XRef *xrefA) {
+ goto err2;
+ }
+ pagesDict.dictLookup("Count", &obj);
+- if (!obj.isInt()) {
++ // some PDF files actually use real numbers here ("/Count 9.0")
++ if (!obj.isNum()) {
+ error(-1, "Page count in top-level pages object is wrong type (%s)",
+ obj.getTypeName());
+ goto err3;
+ }
+- pagesSize = numPages0 = obj.getInt();
++ pagesSize = numPages0 = (int)obj.getNum();
+ obj.free();
++ if (((unsigned) pagesSize >= INT_MAX / sizeof(Page *)) ||
++ ((unsigned) pagesSize >= INT_MAX / sizeof(Ref)))
++ {
++ 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) {
+@@ -190,6 +200,11 @@ int Catalog::readPageTree(Dict *pagesDic
+ }
+ if (start >= pagesSize) {
+ pagesSize += 32;
++ if ((unsigned) pagesSize >= INT_MAX / sizeof(Page*) ||
++ (unsigned) pagesSize >= INT_MAX / sizeof(Ref)) {
++ 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) {
+@@ -307,8 +322,8 @@ Object *Catalog::findDestInTree(Object *
+ } else if (cmp < 0) {
+ done = gTrue;
+ }
+- name1.free();
+ }
++ name1.free();
+ }
+ names.free();
+ if (!found)
+--- kdegraphics/kpdf/xpdf/XRef.cc 2003/08/20 21:25:12 1.3
++++ kdegraphics/kpdf/xpdf/XRef.cc 2004/10/28 09:42:53 1.3.4.5
+@@ -12,6 +12,7 @@
+ #pragma implementation
+ #endif
+
++#include <limits.h>
+ #include <stdlib.h>
+ #include <stddef.h>
+ #include <string.h>
+@@ -47,12 +48,162 @@
+ #endif
+
+ //------------------------------------------------------------------------
++// ObjectStream
++//------------------------------------------------------------------------
++
++class ObjectStream {
++public:
++
++ // Create an object stream, using object number <objStrNum>,
++ // generation 0.
++ ObjectStream(XRef *xref, int objStrNumA);
++
++ ~ObjectStream();
++
++ // Return the object number of this object stream.
++ int getObjStrNum() { return objStrNum; }
++
++ // Get the <objIdx>th object from this stream, which should be
++ // object number <objNum>, generation 0.
++ Object *getObject(int objIdx, int objNum, Object *obj);
++
++private:
++
++ int objStrNum; // object number of the object stream
++ int nObjects; // number of objects in the stream
++ Object *objs; // the objects (length = nObjects)
++ int *objNums; // the object numbers (length = nObjects)
++};
++
++ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
++ Stream *str;
++ Parser *parser;
++ int *offsets;
++ Object objStr, obj1, obj2;
++ int first, i;
++
++ objStrNum = objStrNumA;
++ nObjects = 0;
++ objs = NULL;
++ objNums = NULL;
++
++ if (!xref->fetch(objStrNum, 0, &objStr)->isStream()) {
++ goto err1;
++ }
++
++ if (!objStr.streamGetDict()->lookup("N", &obj1)->isInt()) {
++ obj1.free();
++ goto err1;
++ }
++ nObjects = obj1.getInt();
++ obj1.free();
++ if (nObjects <= 0) {
++ goto err1;
++ }
++
++ if (!objStr.streamGetDict()->lookup("First", &obj1)->isInt()) {
++ obj1.free();
++ goto err1;
++ }
++ first = obj1.getInt();
++ obj1.free();
++ if (first < 0) {
++ goto err1;
++ }
++
++ if ((unsigned) nObjects >= INT_MAX / sizeof(int)) {
++ error(-1, "Invalid 'nObjects'");
++ goto err1;
++ }
++
++ objs = new Object[nObjects];
++ objNums = (int *)gmalloc(nObjects * sizeof(int));
++ offsets = (int *)gmalloc(nObjects * sizeof(int));
++
++ // parse the header: object numbers and offsets
++ objStr.streamReset();
++ obj1.initNull();
++ str = new EmbedStream(objStr.getStream(), &obj1, gTrue, first);
++ parser = new Parser(xref, new Lexer(xref, str));
++ for (i = 0; i < nObjects; ++i) {
++ parser->getObj(&obj1);
++ parser->getObj(&obj2);
++ if (!obj1.isInt() || !obj2.isInt()) {
++ obj1.free();
++ obj2.free();
++ delete parser;
++ gfree(offsets);
++ goto err1;
++ }
++ objNums[i] = obj1.getInt();
++ 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;
++
++ // skip to the first object - this shouldn't be necessary because
++ // the First key is supposed to be equal to offsets[0], but just in
++ // case...
++ for (i = first; i < offsets[0]; ++i) {
++ objStr.getStream()->getChar();
++ }
++
++ // parse the objects
++ for (i = 0; i < nObjects; ++i) {
++ obj1.initNull();
++ if (i == nObjects - 1) {
++ str = new EmbedStream(objStr.getStream(), &obj1, gFalse, 0);
++ } else {
++ str = new EmbedStream(objStr.getStream(), &obj1, gTrue,
++ offsets[i+1] - offsets[i]);
++ }
++ parser = new Parser(xref, new Lexer(xref, str));
++ parser->getObj(&objs[i]);
++ while (str->getChar() != EOF) ;
++ delete parser;
++ }
++
++ gfree(offsets);
++
++ err1:
++ objStr.free();
++ return;
++}
++
++ObjectStream::~ObjectStream() {
++ int i;
++
++ if (objs) {
++ for (i = 0; i < nObjects; ++i) {
++ objs[i].free();
++ }
++ delete[] objs;
++ }
++ gfree(objNums);
++}
++
++Object *ObjectStream::getObject(int objIdx, int objNum, Object *obj) {
++ if (objIdx < 0 || objIdx >= nObjects || objNum != objNums[objIdx]) {
++ return obj->initNull();
++ }
++ return objs[objIdx].copy(obj);
++}
++
++//------------------------------------------------------------------------
+ // XRef
+ //------------------------------------------------------------------------
+
+ XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
+ Guint pos;
+- int i;
++ Object obj;
+
+ ok = gTrue;
+ errCode = errNone;
+@@ -60,35 +211,28 @@ XRef::XRef(BaseStream *strA, GString *ow
+ entries = NULL;
+ streamEnds = NULL;
+ streamEndsLen = 0;
++ objStr = NULL;
+
+ // read the trailer
+ str = strA;
+ start = str->getStart();
+- pos = readTrailer();
++ pos = getStartXref();
+
+- // if there was a problem with the trailer,
+- // try to reconstruct the xref table
++ // if there was a problem with the 'startxref' position, try to
++ // reconstruct the xref table
+ if (pos == 0) {
+ if (!(ok = constructXRef())) {
+ errCode = errDamaged;
+ return;
+ }
+
+- // trailer is ok - read the xref table
++ // read the xref table
+ } else {
+- entries = (XRefEntry *)gmalloc(size * sizeof(XRefEntry));
+- for (i = 0; i < size; ++i) {
+- entries[i].offset = 0xffffffff;
+- entries[i].used = gFalse;
+- }
+ while (readXRef(&pos)) ;
+
+ // if there was a problem with the xref table,
+ // try to reconstruct it
+ if (!ok) {
+- gfree(entries);
+- size = 0;
+- entries = NULL;
+ if (!(ok = constructXRef())) {
+ errCode = errDamaged;
+ return;
+@@ -96,6 +240,20 @@ XRef::XRef(BaseStream *strA, GString *ow
+ }
+ }
+
++ // get the root dictionary (catalog) object
++ trailerDict.dictLookupNF("Root", &obj);
++ if (obj.isRef()) {
++ rootNum = obj.getRefNum();
++ rootGen = obj.getRefGen();
++ obj.free();
++ } else {
++ obj.free();
++ if (!(ok = constructXRef())) {
++ errCode = errDamaged;
++ return;
++ }
++ }
++
+ // now set the trailer dictionary's xref pointer so we can fetch
+ // indirect objects from it
+ trailerDict.getDict()->setXRef(this);
+@@ -117,188 +275,165 @@ XRef::~XRef() {
+ if (streamEnds) {
+ gfree(streamEnds);
+ }
++ if (objStr) {
++ delete objStr;
++ }
+ }
+
+-// Read startxref position, xref table size, and root. Returns
+-// first xref position.
+-Guint XRef::readTrailer() {
+- Parser *parser;
+- Object obj;
++// Read the 'startxref' position.
++Guint XRef::getStartXref() {
+ char buf[xrefSearchSize+1];
+- int n;
+- Guint pos, pos1;
+ char *p;
+- int c;
+- int i;
++ int c, n, i;
+
+ // read last xrefSearchSize bytes
+ str->setPos(xrefSearchSize, -1);
+ for (n = 0; n < xrefSearchSize; ++n) {
+- if ((c = str->getChar()) == EOF)
++ if ((c = str->getChar()) == EOF) {
+ break;
++ }
+ buf[n] = c;
+ }
+ buf[n] = '\0';
+
+ // find startxref
+ for (i = n - 9; i >= 0; --i) {
+- if (!strncmp(&buf[i], "startxref", 9))
++ if (!strncmp(&buf[i], "startxref", 9)) {
+ break;
++ }
+ }
+- if (i < 0)
++ if (i < 0) {
+ return 0;
++ }
+ for (p = &buf[i+9]; isspace(*p); ++p) ;
+- pos = lastXRefPos = strToUnsigned(p);
++ lastXRefPos = strToUnsigned(p);
+
+- // find trailer dict by looking after first xref table
+- // (NB: we can't just use the trailer dict at the end of the file --
+- // this won't work for linearized files.)
+- str->setPos(start + pos);
+- for (i = 0; i < 4; ++i)
+- buf[i] = str->getChar();
+- if (strncmp(buf, "xref", 4))
+- return 0;
+- pos1 = pos + 4;
+- while (1) {
+- str->setPos(start + pos1);
+- for (i = 0; i < 35; ++i) {
+- if ((c = str->getChar()) == EOF)
+- return 0;
+- buf[i] = c;
+- }
+- if (!strncmp(buf, "trailer", 7))
+- break;
+- p = buf;
+- while (isspace(*p)) ++p;
+- while ('0' <= *p && *p <= '9') ++p;
+- while (isspace(*p)) ++p;
+- n = atoi(p);
+- while ('0' <= *p && *p <= '9') ++p;
+- while (isspace(*p)) ++p;
+- if (p == buf)
+- return 0;
+- pos1 += (p - buf) + n * 20;
+- }
+- pos1 += 7;
++ return lastXRefPos;
++}
+
+- // read trailer dict
++// Read one xref table section. Also reads the associated trailer
++// dictionary, and returns the prev pointer (if any).
++GBool XRef::readXRef(Guint *pos) {
++ Parser *parser;
++ Object obj;
++ GBool more;
++
++ // start up a parser, parse one token
+ obj.initNull();
+ parser = new Parser(NULL,
+ new Lexer(NULL,
+- str->makeSubStream(start + pos1, gFalse, 0, &obj)));
+- parser->getObj(&trailerDict);
+- if (trailerDict.isDict()) {
+- trailerDict.dictLookupNF("Size", &obj);
+- if (obj.isInt())
+- size = obj.getInt();
+- else
+- pos = 0;
++ str->makeSubStream(start + *pos, gFalse, 0, &obj)));
++ parser->getObj(&obj);
++
++ // parse an old-style xref table
++ if (obj.isCmd("xref")) {
+ obj.free();
+- trailerDict.dictLookupNF("Root", &obj);
+- if (obj.isRef()) {
+- rootNum = obj.getRefNum();
+- rootGen = obj.getRefGen();
+- } else {
+- pos = 0;
++ more = readXRefTable(parser, pos);
++
++ // parse an xref stream
++ } else if (obj.isInt()) {
++ obj.free();
++ if (!parser->getObj(&obj)->isInt()) {
++ goto err1;
++ }
++ obj.free();
++ if (!parser->getObj(&obj)->isCmd("obj")) {
++ goto err1;
+ }
+ obj.free();
++ if (!parser->getObj(&obj)->isStream()) {
++ goto err1;
++ }
++ more = readXRefStream(obj.getStream(), pos);
++ obj.free();
++
+ } else {
+- pos = 0;
++ goto err1;
+ }
++
+ delete parser;
++ return more;
+
+- // return first xref position
+- return pos;
++ err1:
++ obj.free();
++ delete parser;
++ ok = gFalse;
++ return gFalse;
+ }
+
+-// Read an xref table and the prev pointer from the trailer.
+-GBool XRef::readXRef(Guint *pos) {
+- Parser *parser;
+- Object obj, obj2;
+- char s[20];
++GBool XRef::readXRefTable(Parser *parser, Guint *pos) {
++ XRefEntry entry;
+ GBool more;
+- int first, newSize, n, i, j;
+- int c;
+-
+- // seek to xref in stream
+- str->setPos(start + *pos);
+-
+- // make sure it's an xref table
+- while ((c = str->getChar()) != EOF && isspace(c)) ;
+- s[0] = (char)c;
+- s[1] = (char)str->getChar();
+- s[2] = (char)str->getChar();
+- s[3] = (char)str->getChar();
+- if (!(s[0] == 'x' && s[1] == 'r' && s[2] == 'e' && s[3] == 'f')) {
+- goto err2;
+- }
++ Object obj, obj2;
++ Guint pos2;
++ int first, n, newSize, i;
+
+- // read xref
+ while (1) {
+- while ((c = str->lookChar()) != EOF && isspace(c)) {
+- str->getChar();
+- }
+- if (c == 't') {
++ parser->getObj(&obj);
++ if (obj.isCmd("trailer")) {
++ obj.free();
+ break;
+ }
+- for (i = 0; (c = str->getChar()) != EOF && isdigit(c) && i < 20; ++i) {
+- s[i] = (char)c;
++ if (!obj.isInt()) {
++ goto err1;
+ }
+- if (i == 0) {
+- goto err2;
++ first = obj.getInt();
++ obj.free();
++ if (!parser->getObj(&obj)->isInt()) {
++ goto err1;
+ }
+- s[i] = '\0';
+- first = atoi(s);
+- while ((c = str->lookChar()) != EOF && isspace(c)) {
+- str->getChar();
+- }
+- for (i = 0; (c = str->getChar()) != EOF && isdigit(c) && i < 20; ++i) {
+- s[i] = (char)c;
+- }
+- if (i == 0) {
+- goto err2;
+- }
+- s[i] = '\0';
+- n = atoi(s);
+- while ((c = str->lookChar()) != EOF && isspace(c)) {
+- str->getChar();
++ n = obj.getInt();
++ obj.free();
++ if (first < 0 || n < 0 || first + n < 0) {
++ goto err1;
+ }
+- // check for buggy PDF files with an incorrect (too small) xref
+- // table size
+ if (first + n > size) {
+- newSize = size + 256;
++ for (newSize = size ? 2 * size : 1024;
++ first + n > newSize && newSize > 0;
++ newSize <<= 1) ;
++ if (newSize < 0) {
++ goto err1;
++ }
++ if ((unsigned) newSize >= INT_MAX / sizeof(XRefEntry)) {
++ error(-1, "Invalid 'obj' parameters'");
++ goto err1;
++ }
++
+ entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry));
+ for (i = size; i < newSize; ++i) {
+ entries[i].offset = 0xffffffff;
+- entries[i].used = gFalse;
++ entries[i].type = xrefEntryFree;
+ }
+ size = newSize;
+ }
+ for (i = first; i < first + n; ++i) {
+- for (j = 0; j < 20; ++j) {
+- if ((c = str->getChar()) == EOF) {
+- goto err2;
+- }
+- s[j] = (char)c;
++ if (!parser->getObj(&obj)->isInt()) {
++ goto err1;
+ }
++ entry.offset = (Guint)obj.getInt();
++ obj.free();
++ if (!parser->getObj(&obj)->isInt()) {
++ goto err1;
++ }
++ entry.gen = obj.getInt();
++ obj.free();
++ parser->getObj(&obj);
++ if (obj.isCmd("n")) {
++ entry.type = xrefEntryUncompressed;
++ } else if (obj.isCmd("f")) {
++ entry.type = xrefEntryFree;
++ } else {
++ goto err1;
++ }
++ obj.free();
+ if (entries[i].offset == 0xffffffff) {
+- s[10] = '\0';
+- entries[i].offset = strToUnsigned(s);
+- s[16] = '\0';
+- entries[i].gen = atoi(&s[11]);
+- if (s[17] == 'n') {
+- entries[i].used = gTrue;
+- } else if (s[17] == 'f') {
+- entries[i].used = gFalse;
+- } else {
+- goto err2;
+- }
++ entries[i] = entry;
+ // PDF files of patents from the IBM Intellectual Property
+ // Network have a bug: the xref table claims to start at 1
+ // instead of 0.
+ if (i == 1 && first == 1 &&
+ entries[1].offset == 0 && entries[1].gen == 65535 &&
+- !entries[1].used) {
++ entries[1].type == xrefEntryFree) {
+ i = first = 0;
+ entries[0] = entries[1];
+ entries[1].offset = 0xffffffff;
+@@ -307,20 +442,12 @@ GBool XRef::readXRef(Guint *pos) {
+ }
+ }
+
+- // read prev pointer from trailer dictionary
+- obj.initNull();
+- parser = new Parser(NULL,
+- new Lexer(NULL,
+- str->makeSubStream(str->getPos(), gFalse, 0, &obj)));
+- parser->getObj(&obj);
+- if (!obj.isCmd("trailer")) {
+- goto err1;
+- }
+- obj.free();
+- parser->getObj(&obj);
+- if (!obj.isDict()) {
++ // read the trailer dictionary
++ if (!parser->getObj(&obj)->isDict()) {
+ goto err1;
+ }
++
++ // get the 'Prev' pointer
+ obj.getDict()->lookupNF("Prev", &obj2);
+ if (obj2.isInt()) {
+ *pos = (Guint)obj2.getInt();
+@@ -333,23 +460,208 @@ GBool XRef::readXRef(Guint *pos) {
+ } else {
+ more = gFalse;
+ }
+- obj.free();
+ obj2.free();
+
+- delete parser;
++ // save the first trailer dictionary
++ if (trailerDict.isNone()) {
++ obj.copy(&trailerDict);
++ }
++
++ // check for an 'XRefStm' key
++ if (obj.getDict()->lookup("XRefStm", &obj2)->isInt()) {
++ pos2 = (Guint)obj2.getInt();
++ readXRef(&pos2);
++ if (!ok) {
++ goto err1;
++ }
++ }
++ obj2.free();
++
++ obj.free();
++ return more;
++
++ err1:
++ obj.free();
++ ok = gFalse;
++ return gFalse;
++}
++
++GBool XRef::readXRefStream(Stream *xrefStr, Guint *pos) {
++ Dict *dict;
++ int w[3];
++ GBool more;
++ Object obj, obj2, idx;
++ int newSize, first, n, i;
++
++ dict = xrefStr->getDict();
++
++ if (!dict->lookupNF("Size", &obj)->isInt()) {
++ goto err1;
++ }
++ newSize = obj.getInt();
++ obj.free();
++ if (newSize < 0) {
++ goto err1;
++ }
++ if (newSize > size) {
++ if ((unsigned) newSize >= INT_MAX / sizeof(XRefEntry)) {
++ error(-1, "Invalid 'size' parameter.");
++ 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 (!dict->lookupNF("W", &obj)->isArray() ||
++ obj.arrayGetLength() < 3) {
++ goto err1;
++ }
++ for (i = 0; i < 3; ++i) {
++ if (!obj.arrayGet(i, &obj2)->isInt()) {
++ obj2.free();
++ goto err1;
++ }
++ w[i] = obj2.getInt();
++ obj2.free();
++ if (w[i] < 0 || w[i] > 4) {
++ goto err1;
++ }
++ }
++ obj.free();
++
++ xrefStr->reset();
++ dict->lookupNF("Index", &idx);
++ if (idx.isArray()) {
++ for (i = 0; i+1 < idx.arrayGetLength(); i += 2) {
++ if (!idx.arrayGet(i, &obj)->isInt()) {
++ idx.free();
++ goto err1;
++ }
++ first = obj.getInt();
++ obj.free();
++ if (!idx.arrayGet(i+1, &obj)->isInt()) {
++ idx.free();
++ goto err1;
++ }
++ n = obj.getInt();
++ obj.free();
++ if (first < 0 || n < 0 ||
++ !readXRefStreamSection(xrefStr, w, first, n)) {
++ idx.free();
++ goto err0;
++ }
++ }
++ } else {
++ if (!readXRefStreamSection(xrefStr, w, 0, newSize)) {
++ idx.free();
++ goto err0;
++ }
++ }
++ idx.free();
++
++ dict->lookupNF("Prev", &obj);
++ if (obj.isInt()) {
++ *pos = (Guint)obj.getInt();
++ more = gTrue;
++ } else {
++ more = gFalse;
++ }
++ obj.free();
++ if (trailerDict.isNone()) {
++ trailerDict.initDict(dict);
++ }
++
+ return more;
+
+ err1:
+ obj.free();
+- err2:
++ err0:
+ ok = gFalse;
+ return gFalse;
+ }
+
++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 && newSize > 0;
++ newSize <<= 1) ;
++ if (newSize < 0) {
++ return gFalse;
++ }
++ if ((unsigned) newSize >= INT_MAX / sizeof(XRefEntry)) {
++ 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;
++ entries[i].type = xrefEntryFree;
++ }
++ size = newSize;
++ }
++ for (i = first; i < first + n; ++i) {
++ if (w[0] == 0) {
++ type = 1;
++ } else {
++ for (type = 0, j = 0; j < w[0]; ++j) {
++ if ((c = xrefStr->getChar()) == EOF) {
++ return gFalse;
++ }
++ type = (type << 8) + c;
++ }
++ }
++ for (offset = 0, j = 0; j < w[1]; ++j) {
++ if ((c = xrefStr->getChar()) == EOF) {
++ return gFalse;
++ }
++ offset = (offset << 8) + c;
++ }
++ for (gen = 0, j = 0; j < w[2]; ++j) {
++ if ((c = xrefStr->getChar()) == EOF) {
++ return gFalse;
++ }
++ gen = (gen << 8) + c;
++ }
++ 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;
++ }
++ }
++ }
++
++ return gTrue;
++}
++
+ // Attempt to construct an xref table for a damaged file.
+ GBool XRef::constructXRef() {
+ Parser *parser;
+- Object obj;
++ Object newTrailerDict, obj;
+ char buf[256];
+ Guint pos;
+ int num, gen;
+@@ -359,6 +671,10 @@ GBool XRef::constructXRef() {
+ int i;
+ GBool gotRoot;
+
++ gfree(entries);
++ size = 0;
++ entries = NULL;
++
+ error(0, "PDF file is damaged - attempting to reconstruct xref table...");
+ gotRoot = gFalse;
+ streamEndsLen = streamEndsSize = 0;
+@@ -377,56 +693,68 @@ GBool XRef::constructXRef() {
+ parser = new Parser(NULL,
+ new Lexer(NULL,
+ str->makeSubStream(start + pos + 7, gFalse, 0, &obj)));
+- if (!trailerDict.isNone())
+- trailerDict.free();
+- parser->getObj(&trailerDict);
+- if (trailerDict.isDict()) {
+- trailerDict.dictLookupNF("Root", &obj);
++ parser->getObj(&newTrailerDict);
++ if (newTrailerDict.isDict()) {
++ newTrailerDict.dictLookupNF("Root", &obj);
+ if (obj.isRef()) {
+ rootNum = obj.getRefNum();
+ rootGen = obj.getRefGen();
++ if (!trailerDict.isNone()) {
++ trailerDict.free();
++ }
++ newTrailerDict.copy(&trailerDict);
+ gotRoot = gTrue;
+ }
+ obj.free();
+- } else {
+- pos = 0;
+ }
++ newTrailerDict.free();
+ delete parser;
+
+ // 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].used = gFalse;
++ } 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 ((unsigned) newSize >= INT_MAX / sizeof(XRefEntry)) {
++ 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].used || gen >= entries[num].gen) {
+- entries[num].offset = pos - start;
+- entries[num].gen = gen;
+- entries[num].used = gTrue;
+ }
+ }
+ }
+@@ -436,6 +764,10 @@ GBool XRef::constructXRef() {
+ } else if (!strncmp(p, "endstream", 9)) {
+ if (streamEndsLen == streamEndsSize) {
+ streamEndsSize += 64;
++ if ((unsigned) streamEndsSize >= INT_MAX / sizeof(int)) {
++ error(-1, "Invalid 'endstream' parameter.");
++ return gFalse;
++ }
+ streamEnds = (Guint *)grealloc(streamEnds,
+ streamEndsSize * sizeof(int));
+ }
+@@ -457,6 +789,8 @@ GBool XRef::checkEncrypted(GString *owne
+ GBool encrypted1;
+ GBool ret;
+
++ keyLength = 0;
++ encVersion = encRevision = 0;
+ ret = gFalse;
+
+ permFlags = defPermFlags;
+@@ -551,38 +885,34 @@ GBool XRef::checkEncrypted(GString *owne
+
+ GBool XRef::okToPrint(GBool ignoreOwnerPW) {
+ #ifndef NO_DECRYPTION
+- if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permPrint)) {
+- return gFalse;
+- }
+-#endif
++ return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permPrint);
++#else
+ return gTrue;
++#endif
+ }
+
+ GBool XRef::okToChange(GBool ignoreOwnerPW) {
+ #ifndef NO_DECRYPTION
+- if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permChange)) {
+- return gFalse;
+- }
+-#endif
++ return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permChange);
++#else
+ return gTrue;
++#endif
+ }
+
+ GBool XRef::okToCopy(GBool ignoreOwnerPW) {
+ #ifndef NO_DECRYPTION
+- if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permCopy)) {
+- return gFalse;
+- }
+-#endif
++ return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permCopy);
++#else
+ return gTrue;
++#endif
+ }
+
+ GBool XRef::okToAddNotes(GBool ignoreOwnerPW) {
+ #ifndef NO_DECRYPTION
+- if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permNotes)) {
+- return gFalse;
+- }
+-#endif
++ return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permNotes);
++#else
+ return gTrue;
++#endif
+ }
+
+ Object *XRef::fetch(int num, int gen, Object *obj) {
+@@ -592,12 +922,16 @@ Object *XRef::fetch(int num, int gen, Ob
+
+ // check for bogus ref - this can happen in corrupted PDF files
+ if (num < 0 || num >= size) {
+- obj->initNull();
+- return obj;
++ goto err;
+ }
+
+ e = &entries[num];
+- if (e->gen == gen && e->offset != 0xffffffff) {
++ switch (e->type) {
++
++ case xrefEntryUncompressed:
++ if (e->gen != gen) {
++ goto err;
++ }
+ obj1.initNull();
+ parser = new Parser(this,
+ new Lexer(this,
+@@ -605,26 +939,44 @@ Object *XRef::fetch(int num, int gen, Ob
+ parser->getObj(&obj1);
+ parser->getObj(&obj2);
+ parser->getObj(&obj3);
+- if (obj1.isInt() && obj1.getInt() == num &&
+- obj2.isInt() && obj2.getInt() == gen &&
+- obj3.isCmd("obj")) {
++ if (!obj1.isInt() || obj1.getInt() != num ||
++ !obj2.isInt() || obj2.getInt() != gen ||
++ !obj3.isCmd("obj")) {
++ goto err;
++ }
+ #ifndef NO_DECRYPTION
+- parser->getObj(obj, encrypted ? fileKey : (Guchar *)NULL, keyLength,
+- num, gen);
++ parser->getObj(obj, encrypted ? fileKey : (Guchar *)NULL, keyLength,
++ num, gen);
+ #else
+- parser->getObj(obj);
++ parser->getObj(obj);
+ #endif
+- } else {
+- obj->initNull();
+- }
+ obj1.free();
+ obj2.free();
+ obj3.free();
+ delete parser;
+- } else {
+- obj->initNull();
++ break;
++
++ case xrefEntryCompressed:
++ if (gen != 0) {
++ goto err;
++ }
++ if (!objStr || objStr->getObjStrNum() != (int)e->offset) {
++ if (objStr) {
++ delete objStr;
++ }
++ objStr = new ObjectStream(this, e->offset);
++ }
++ objStr->getObject(e->gen, num, obj);
++ break;
++
++ default:
++ goto err;
+ }
++
+ return obj;
++
++ err:
++ return obj->initNull();
+ }
+
+ Object *XRef::getDocInfo(Object *obj) {
diff --git a/kde-base/kdegraphics/files/post-3.3.1-kdegraphics_2.diff b/kde-base/kdegraphics/files/post-3.3.1-kdegraphics_2.diff
new file mode 100644
index 000000000000..16a564ab9f4e
--- /dev/null
+++ b/kde-base/kdegraphics/files/post-3.3.1-kdegraphics_2.diff
@@ -0,0 +1,115 @@
+--- kpdf/xpdf/Catalog.cc 2004/09/02 21:30:18 1.3.4.1
++++ kpdf/xpdf/Catalog.cc 2004/10/28 09:42:53 1.3.4.4
+@@ -12,6 +12,7 @@
+ #pragma implementation
+ #endif
+
++#include <limits.h>
+ #include <stddef.h>
+ #include "gmem.h"
+ #include "Object.h"
+@@ -64,6 +65,14 @@ Catalog::Catalog(XRef *xrefA) {
+ }
+ pagesSize = numPages0 = (int)obj.getNum();
+ obj.free();
++ if (((unsigned) pagesSize >= INT_MAX / sizeof(Page *)) ||
++ ((unsigned) pagesSize >= INT_MAX / sizeof(Ref)))
++ {
++ 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 *pagesDic
+ }
+ if (start >= pagesSize) {
+ pagesSize += 32;
++ if ((unsigned) pagesSize >= INT_MAX / sizeof(Page*) ||
++ (unsigned) pagesSize >= INT_MAX / sizeof(Ref)) {
++ 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) {
+--- kpdf/xpdf/XRef.cc 2004/10/12 19:41:07 1.3.4.2
++++ kpdf/xpdf/XRef.cc 2004/10/28 09:42:53 1.3.4.5
+@@ -12,6 +12,7 @@
+ #pragma implementation
+ #endif
+
++#include <limits.h>
+ #include <stdlib.h>
+ #include <stddef.h>
+ #include <string.h>
+@@ -110,6 +111,11 @@ ObjectStream::ObjectStream(XRef *xref, i
+ goto err1;
+ }
+
++ if ((unsigned) nObjects >= INT_MAX / sizeof(int)) {
++ error(-1, "Invalid 'nObjects'");
++ goto err1;
++ }
++
+ objs = new Object[nObjects];
+ objNums = (int *)gmalloc(nObjects * sizeof(int));
+ offsets = (int *)gmalloc(nObjects * sizeof(int));
+@@ -388,6 +394,11 @@ GBool XRef::readXRefTable(Parser *parser
+ if (newSize < 0) {
+ goto err1;
+ }
++ if ((unsigned) newSize >= INT_MAX / sizeof(XRefEntry)) {
++ error(-1, "Invalid 'obj' parameters'");
++ goto err1;
++ }
++
+ entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry));
+ for (i = size; i < newSize; ++i) {
+ entries[i].offset = 0xffffffff;
+@@ -493,6 +504,10 @@ GBool XRef::readXRefStream(Stream *xrefS
+ goto err1;
+ }
+ if (newSize > size) {
++ if ((unsigned) newSize >= INT_MAX / sizeof(XRefEntry)) {
++ error(-1, "Invalid 'size' parameter.");
++ return gFalse;
++ }
+ entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry));
+ for (i = size; i < newSize; ++i) {
+ entries[i].offset = 0xffffffff;
+@@ -583,6 +598,10 @@ GBool XRef::readXRefStreamSection(Stream
+ if (newSize < 0) {
+ return gFalse;
+ }
++ if ((unsigned) newSize >= INT_MAX / sizeof(XRefEntry)) {
++ 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;
+@@ -718,6 +737,10 @@ GBool XRef::constructXRef() {
+ error(-1, "Bad object number");
+ return gFalse;
+ }
++ if ((unsigned) newSize >= INT_MAX / sizeof(XRefEntry)) {
++ error(-1, "Invalid 'obj' parameters.");
++ return gFalse;
++ }
+ entries = (XRefEntry *)
+ grealloc(entries, newSize * sizeof(XRefEntry));
+ for (i = size; i < newSize; ++i) {
+@@ -741,6 +764,10 @@ GBool XRef::constructXRef() {
+ } else if (!strncmp(p, "endstream", 9)) {
+ if (streamEndsLen == streamEndsSize) {
+ streamEndsSize += 64;
++ if ((unsigned) streamEndsSize >= INT_MAX / sizeof(int)) {
++ error(-1, "Invalid 'endstream' parameter.");
++ return gFalse;
++ }
+ streamEnds = (Guint *)grealloc(streamEnds,
+ streamEndsSize * sizeof(int));
+ }
diff --git a/kde-base/kdegraphics/kdegraphics-3.2.3-r2.ebuild b/kde-base/kdegraphics/kdegraphics-3.2.3-r2.ebuild
new file mode 100644
index 000000000000..e3061c06e926
--- /dev/null
+++ b/kde-base/kdegraphics/kdegraphics-3.2.3-r2.ebuild
@@ -0,0 +1,45 @@
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/kde-base/kdegraphics/kdegraphics-3.2.3-r2.ebuild,v 1.1 2004/11/03 17:35:58 carlo Exp $
+
+inherit kde-dist eutils
+
+DESCRIPTION="KDE graphics-related apps"
+
+KEYWORDS="x86 ~ppc ~sparc ~alpha ~hppa ~amd64 ~ia64"
+IUSE="gphoto2 tetex scanner opengl"
+
+DEPEND="~kde-base/kdebase-${PV}
+ gphoto2? ( media-gfx/gphoto2 )
+ scanner? ( media-gfx/sane-backends )
+ tetex? ( virtual/tetex )
+ dev-libs/fribidi
+ opengl? ( virtual/glut virtual/opengl )
+ media-libs/imlib
+ virtual/ghostscript
+ media-libs/tiff
+ x86? ( scanner? sys-libs/libieee1284 )"
+RDEPEND="${DEPEND}
+ app-text/xpdf"
+
+src_unpack() {
+ kde_src_unpack
+ epatch ${FILESDIR}/${P}-gcc34-compile.patch
+ epatch ${FILESDIR}/post-3.2.3-kdegraphics_2.diff
+}
+
+src_compile() {
+
+ use gphoto2 \
+ && myconf="$myconf --with-kamera \
+ --with-gphoto2-includes=/usr/include/gphoto2 \
+ --with-gphoto2-libraries=/usr/lib/gphoto2" \
+ || myconf="$myconf --without-kamera"
+
+ use tetex && myconf="$myconf --with-system-kpathsea --with-tex-datadir=/usr/share"
+
+ use scanner || DO_NOT_COMPILE="$DO_NOT_COMPILE kooka libkscan"
+
+ myconf="$myconf --with-imlib --with-imlib-config=/usr/bin"
+ kde_src_compile
+}
diff --git a/kde-base/kdegraphics/kdegraphics-3.3.0-r1.ebuild b/kde-base/kdegraphics/kdegraphics-3.3.0-r1.ebuild
index 6d609d6711d7..fdfc22dee887 100644
--- a/kde-base/kdegraphics/kdegraphics-3.3.0-r1.ebuild
+++ b/kde-base/kdegraphics/kdegraphics-3.3.0-r1.ebuild
@@ -1,6 +1,6 @@
# Copyright 1999-2004 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/kde-base/kdegraphics/kdegraphics-3.3.0-r1.ebuild,v 1.4 2004/10/27 22:10:09 kugelfang Exp $
+# $Header: /var/cvsroot/gentoo-x86/kde-base/kdegraphics/kdegraphics-3.3.0-r1.ebuild,v 1.5 2004/11/03 17:35:58 carlo Exp $
inherit kde-dist eutils
@@ -20,7 +20,8 @@ DEPEND="~kde-base/kdebase-${PV}
x86? ( scanner? sys-libs/libieee1284 )
povray? ( x86? ( media-gfx/povray ) )
jpeg2k? ( x86? ( media-libs/jasper ) )
- !media-gfx/kolourpaint"
+ !media-gfx/kolourpaint
+ !x11-misc/kgamma"
RDEPEND="${DEPEND}
app-text/xpdf
tetex? (
diff --git a/kde-base/kdegraphics/kdegraphics-3.3.0-r2.ebuild b/kde-base/kdegraphics/kdegraphics-3.3.0-r2.ebuild
new file mode 100644
index 000000000000..6aa25e68ede6
--- /dev/null
+++ b/kde-base/kdegraphics/kdegraphics-3.3.0-r2.ebuild
@@ -0,0 +1,55 @@
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/kde-base/kdegraphics/kdegraphics-3.3.0-r2.ebuild,v 1.1 2004/11/03 17:35:58 carlo Exp $
+
+inherit kde-dist eutils
+
+DESCRIPTION="KDE graphics-related apps"
+
+KEYWORDS="x86 ~amd64 ~ppc64 ~sparc ~ppc ~hppa"
+IUSE="gphoto2 imlib jpeg2k opengl povray scanner tetex"
+
+DEPEND="~kde-base/kdebase-${PV}
+ gphoto2? ( media-gfx/gphoto2 )
+ scanner? ( media-gfx/sane-backends )
+ dev-libs/fribidi
+ opengl? ( virtual/glut virtual/opengl )
+ imlib? ( media-libs/imlib )
+ virtual/ghostscript
+ media-libs/tiff
+ x86? ( scanner? sys-libs/libieee1284 )
+ povray? ( x86? ( media-gfx/povray ) )
+ jpeg2k? ( x86? ( media-libs/jasper ) )
+ !media-gfx/kolourpaint"
+RDEPEND="${DEPEND}
+ app-text/xpdf
+ tetex? (
+ || ( >=app-text/tetex-2
+ app-text/ptex
+ app-text/cstetex
+ app-text/dvipdfm )
+ )"
+
+src_unpack() {
+ kde_src_unpack
+ epatch ${FILESDIR}/post-3.3.0-kdegraphics_2.diff
+}
+
+src_compile() {
+
+ use gphoto2 \
+ && myconf="$myconf --with-kamera \
+ --with-gphoto2-includes=/usr/include/gphoto2 \
+ --with-gphoto2-libraries=/usr/lib/gphoto2" \
+ || myconf="$myconf --without-kamera"
+
+ use tetex && myconf="$myconf --with-system-kpathsea --with-tex-datadir=/usr/share"
+
+ use scanner || DO_NOT_COMPILE="$DO_NOT_COMPILE kooka libkscan"
+
+ use imlib \
+ && myconf="$myconf --with-imlib --with-imlib-config=/usr/bin" \
+ || myconf="$myconf --without-imlib"
+
+ kde_src_compile
+}
diff --git a/kde-base/kdegraphics/kdegraphics-3.3.1-r2.ebuild b/kde-base/kdegraphics/kdegraphics-3.3.1-r2.ebuild
new file mode 100644
index 000000000000..b83a4f8edc1d
--- /dev/null
+++ b/kde-base/kdegraphics/kdegraphics-3.3.1-r2.ebuild
@@ -0,0 +1,55 @@
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/kde-base/kdegraphics/kdegraphics-3.3.1-r2.ebuild,v 1.1 2004/11/03 17:35:58 carlo Exp $
+
+inherit kde-dist eutils
+
+DESCRIPTION="KDE graphics-related apps"
+
+KEYWORDS="~x86 ~amd64 ~ppc64 ~sparc ~ppc ~hppa"
+IUSE="gphoto2 imlib jpeg2k opengl povray scanner tetex"
+
+DEPEND="~kde-base/kdebase-${PV}
+ gphoto2? ( media-gfx/gphoto2 )
+ scanner? ( media-gfx/sane-backends )
+ dev-libs/fribidi
+ opengl? ( virtual/glut virtual/opengl )
+ imlib? ( media-libs/imlib )
+ virtual/ghostscript
+ media-libs/tiff
+ x86? ( scanner? sys-libs/libieee1284 )
+ povray? ( x86? ( media-gfx/povray ) )
+ jpeg2k? ( x86? ( media-libs/jasper ) )
+ !media-gfx/kolourpaint"
+RDEPEND="${DEPEND}
+ app-text/xpdf
+ tetex? (
+ || ( >=app-text/tetex-2
+ app-text/ptex
+ app-text/cstetex
+ app-text/dvipdfm )
+ )"
+
+src_unpack() {
+ kde_src_unpack
+ epatch ${FILESDIR}/post-3.3.1-kdegraphics_2.diff
+}
+
+src_compile() {
+
+ use gphoto2 \
+ && myconf="$myconf --with-kamera \
+ --with-gphoto2-includes=/usr/include/gphoto2 \
+ --with-gphoto2-libraries=/usr/lib/gphoto2" \
+ || myconf="$myconf --without-kamera"
+
+ use tetex && myconf="$myconf --with-system-kpathsea --with-tex-datadir=/usr/share"
+
+ use scanner || DO_NOT_COMPILE="$DO_NOT_COMPILE kooka libkscan"
+
+ use imlib \
+ && myconf="$myconf --with-imlib --with-imlib-config=/usr/bin" \
+ || myconf="$myconf --without-imlib"
+
+ kde_src_compile
+}