integer overflow vulnerability, #69936
authorCarsten Lohrke <carlo@gentoo.org>
Wed, 3 Nov 2004 17:35:58 +0000 (17:35 +0000)
committerCarsten Lohrke <carlo@gentoo.org>
Wed, 3 Nov 2004 17:35:58 +0000 (17:35 +0000)
12 files changed:
kde-base/kdegraphics/ChangeLog
kde-base/kdegraphics/Manifest
kde-base/kdegraphics/files/digest-kdegraphics-3.2.3-r2 [new file with mode: 0644]
kde-base/kdegraphics/files/digest-kdegraphics-3.3.0-r2 [new file with mode: 0644]
kde-base/kdegraphics/files/digest-kdegraphics-3.3.1-r2 [new file with mode: 0644]
kde-base/kdegraphics/files/post-3.2.3-kdegraphics_2.diff [new file with mode: 0644]
kde-base/kdegraphics/files/post-3.3.0-kdegraphics_2.diff [new file with mode: 0644]
kde-base/kdegraphics/files/post-3.3.1-kdegraphics_2.diff [new file with mode: 0644]
kde-base/kdegraphics/kdegraphics-3.2.3-r2.ebuild [new file with mode: 0644]
kde-base/kdegraphics/kdegraphics-3.3.0-r1.ebuild
kde-base/kdegraphics/kdegraphics-3.3.0-r2.ebuild [new file with mode: 0644]
kde-base/kdegraphics/kdegraphics-3.3.1-r2.ebuild [new file with mode: 0644]

index a0af5662ccf73178c7244e362702ba1719245dfe..ce5d3652dbad3328296aa6690ee47b5d3b707d8b 100644 (file)
@@ -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:
index 34da4f5047aef4b5aca91b6b764dcd609a4d0843..66879c19456aa1a58f38cc990e6cd0c5d7fbec41 100644 (file)
@@ -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 (file)
index 0000000..2e0072d
--- /dev/null
@@ -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 (file)
index 0000000..6aa32ec
--- /dev/null
@@ -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 (file)
index 0000000..484cea3
--- /dev/null
@@ -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 (file)
index 0000000..4f84010
--- /dev/null
@@ -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 (file)
index 0000000..23ddb97
--- /dev/null
@@ -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 (file)
index 0000000..16a564a
--- /dev/null
@@ -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 (file)
index 0000000..e3061c0
--- /dev/null
@@ -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
+}
index 6d609d6711d77428a52a74d3395f16e5ac564702..fdfc22dee887e82ad90c8e3b69e9d588d3d1e3f2 100644 (file)
@@ -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 (file)
index 0000000..6aa25e6
--- /dev/null
@@ -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 (file)
index 0000000..b83a4f8
--- /dev/null
@@ -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
+}