fixed patch
authorCarsten Lohrke <carlo@gentoo.org>
Thu, 4 Nov 2004 14:07:46 +0000 (14:07 +0000)
committerCarsten Lohrke <carlo@gentoo.org>
Thu, 4 Nov 2004 14:07:46 +0000 (14:07 +0000)
kde-base/kdegraphics/ChangeLog
kde-base/kdegraphics/Manifest
kde-base/kdegraphics/files/post-3.3.0-kdegraphics_2.diff

index 54db3fa16f23c93e1f0271704e171d7a9e49636a..7735597f8aa29257dde94e8570fbd828a74d720c 100644 (file)
@@ -1,6 +1,10 @@
 # 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.122 2004/11/04 13:45:22 weeve Exp $
+# $Header: /var/cvsroot/gentoo-x86/kde-base/kdegraphics/ChangeLog,v 1.123 2004/11/04 14:07:46 carlo Exp $
+
+  04 Nov 2004; Carsten Lohrke <carlo@gentoo.org>
+  files/post-3.3.0-kdegraphics_2.diff:
+  fixed patch
 
   04 Nov 2004; Jason Wever <weeve@gentoo.org> kdegraphics-3.3.1-r2.ebuild:
   Stable on sparc wrt security bug #69936.
index f5696974458a342e2b6102823b404880968fb3b6..ce9d94cf039c51116248037006c8e221bd13e48c 100644 (file)
@@ -1,34 +1,34 @@
-MD5 276380838d371e4d28627acbc5d92c21 ChangeLog 16974
-MD5 feb2b4270d15a98a32173a5ae04a19fb kdegraphics-3.1.5.ebuild 1048
-MD5 d34737e0c554fe641ce3a353c8b7fe8d kdegraphics-3.2.0.ebuild 1330
-MD5 6b3fabad5f11df10503b136be549dc16 kdegraphics-3.3.1.ebuild 1434
-MD5 14889ab75f97d76e58b0c1154e7683a9 metadata.xml 161
 MD5 0c557af25ca14e9133483d1ff8414c74 kdegraphics-3.2.2.ebuild 1224
+MD5 e720f7455cef7015497f5ad795a6108b kdegraphics-3.2.3-r2.ebuild 1280
 MD5 5a60aa7288a3e688931b84fce55c4b6a kdegraphics-3.3.0.ebuild 1430
-MD5 8e48bc60a542000e2ca8ca2173a21113 kdegraphics-3.2.3.ebuild 1226
+MD5 fbd70cd93878a0622071cf149368b28e kdegraphics-3.3.0-r2.ebuild 1486
+MD5 0dcbff375e401ca8c354637670a32c43 kdegraphics-3.3.1-r1.ebuild 1485
 MD5 749ee0be0aab8c1f4ee11978a8d16ae2 kdegraphics-3.2.3-r1.ebuild 1278
 MD5 f8ea687ae1a7ff4a4771f5cf4050a125 kdegraphics-3.3.0-r1.ebuild 1499
-MD5 0dcbff375e401ca8c354637670a32c43 kdegraphics-3.3.1-r1.ebuild 1485
-MD5 e720f7455cef7015497f5ad795a6108b kdegraphics-3.2.3-r2.ebuild 1280
-MD5 fbd70cd93878a0622071cf149368b28e kdegraphics-3.3.0-r2.ebuild 1486
+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 624fb5601e9a7f7643cce71f96ee5d2c ChangeLog 17077
 MD5 0075d981be237e5f3f8e887e94140f9a kdegraphics-3.3.1-r2.ebuild 1493
-MD5 e43eeb201ab38aa05917d4de1573ff59 files/digest-kdegraphics-3.2.3 71
+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 fecf5cb3209323e56be3368df325411a files/digest-kdegraphics-3.3.1 71
-MD5 e43eeb201ab38aa05917d4de1573ff59 files/digest-kdegraphics-3.2.3-r1 71
 MD5 80f49f2fcc0bb31559666e47fc28b047 files/digest-kdegraphics-3.2.2 71
-MD5 eb03ab721af71700a0b445f1c50b55f8 files/kdegraphics-3.2.2-gcc34-compile.patch 7723
-MD5 d97c962408abd235435f6857fc405ebf files/kdegraphics-3.2.3-gcc34-compile.patch 7162
-MD5 33d7a652f3ae6f9e66d79fb818b684f6 files/digest-kdegraphics-3.3.0-r1 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-r1 71
-MD5 4f854adb507f4d04e997702e44ffc2ea files/post-3.2.3-kdegraphics.diff 3853
-MD5 651fba579516ea947fbefee373f40a6c files/post-3.3.1-kdegraphics.diff 1533
+MD5 fecf5cb3209323e56be3368df325411a files/digest-kdegraphics-3.3.1 71
 MD5 8d995a343d5083ba8ac84f1d4136d359 files/xpdf-3.3.0-kdegraphics.diff 1630
-MD5 e43eeb201ab38aa05917d4de1573ff59 files/digest-kdegraphics-3.2.3-r2 71
-MD5 33d7a652f3ae6f9e66d79fb818b684f6 files/digest-kdegraphics-3.3.0-r2 71
-MD5 fecf5cb3209323e56be3368df325411a files/digest-kdegraphics-3.3.1-r2 71
+MD5 4f854adb507f4d04e997702e44ffc2ea files/post-3.2.3-kdegraphics.diff 3853
+MD5 d97c962408abd235435f6857fc405ebf files/kdegraphics-3.2.3-gcc34-compile.patch 7162
+MD5 06573d3829a3009c879f870746607056 files/post-3.3.0-kdegraphics_2.diff 3586
 MD5 870d90051bb236753070fb553890f95d files/post-3.2.3-kdegraphics_2.diff 3205
-MD5 a93abae30c47739bd9247d230d1769d2 files/post-3.3.0-kdegraphics_2.diff 26941
+MD5 651fba579516ea947fbefee373f40a6c files/post-3.3.1-kdegraphics.diff 1533
 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
index 23ddb97bdba6157aff025513406d50f5d4955432..65ff458325866b7202cd9c980506e5e99358a674 100644 (file)
@@ -1,5 +1,5 @@
---- 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
+--- kpdf/xpdf/Catalog.cc       2003/08/20 21:25:12     1.3
++++ kpdf/xpdf/Catalog.cc       2004/10/28 09:42:53     1.3.4.4
 @@ -12,6 +12,7 @@
  #pragma implementation
  #endif
@@ -55,8 +55,9 @@
      }
      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
+
+--- kpdf/xpdf/XRef.cc.orig     2004-11-04 13:08:50.000000000 +0100
++++ kpdf/xpdf/XRef.cc  2004-11-04 13:14:50.000000000 +0100
 @@ -12,6 +12,7 @@
  #pragma implementation
  #endif
  #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;
-     }
+@@ -76,6 +77,12 @@
  
--  // trailer is ok - read the xref table
-+  // read the xref table
+   // trailer is ok - 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())) {
++    if ((unsigned) size >= INT_MAX / sizeof(XRefEntry)) {
++      error(-1, "Invalid 'size' inside xref table.");
++      ok = gFalse;
 +      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
+     entries = (XRefEntry *)gmalloc(size * sizeof(XRefEntry));
+     for (i = 0; i < size; ++i) {
+       entries[i].offset = 0xffffffff;
+@@ -267,6 +274,10 @@
+     // 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;
-+      }
+       newSize = size + 256;
 +      if ((unsigned) newSize >= INT_MAX / sizeof(XRefEntry)) {
-+        error(-1, "Invalid 'obj' parameters'");
-+        goto err1;
++        error(-1, "Invalid 'newSize'");
++        goto err2;
 +      }
-+ 
        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() {
+@@ -415,6 +426,10 @@
+           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 @@
      } else if (!strncmp(p, "endstream", 9)) {
        if (streamEndsLen == streamEndsSize) {
        streamEndsSize += 64;
 +          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) {