$OpenBSD: patch-kpdf_xpdf_xpdf_XRef_cc,v 1.3 2009/10/25 12:45:53 kili Exp $
--- kpdf/xpdf/xpdf/XRef.cc.orig	Mon May 14 09:39:30 2007
+++ kpdf/xpdf/xpdf/XRef.cc	Sun Oct 25 13:04:29 2009
@@ -52,6 +52,8 @@ class ObjectStream { (public)
   // generation 0.
   ObjectStream(XRef *xref, int objStrNumA);
 
+  GBool isOk() { return ok; }
+
   ~ObjectStream();
 
   // Return the object number of this object stream.
@@ -67,6 +69,7 @@ class ObjectStream { (public)
   int nObjects;			// number of objects in the stream
   Object *objs;			// the objects (length = nObjects)
   int *objNums;			// the object numbers (length = nObjects)
+  GBool ok;
 };
 
 ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
@@ -80,6 +83,7 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA)
   nObjects = 0;
   objs = NULL;
   objNums = NULL;
+  ok = gFalse;
 
   if (!xref->fetch(objStrNum, 0, &objStr)->isStream()) {
     goto err1;
@@ -105,6 +109,13 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA)
     goto err1;
   }
 
+  // this is an arbitrary limit to avoid integer overflow problems
+  // in the 'new Object[nObjects]' call (Acrobat apparently limits
+  // object streams to 100-200 objects)
+  if (nObjects > 1000000) {
+    error(-1, "Too many objects in an object stream");
+    goto err1;
+  }
   objs = new Object[nObjects];
   objNums = (int *)gmallocn(nObjects, sizeof(int));
   offsets = (int *)gmallocn(nObjects, sizeof(int));
@@ -161,10 +172,10 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA)
   }
 
   gfree(offsets);
+  ok = gTrue;
 
  err1:
   objStr.free();
-  return;
 }
 
 ObjectStream::~ObjectStream() {
@@ -771,19 +782,19 @@ void XRef::setEncryption(int permFlagsA, GBool ownerPa
 }
 
 GBool XRef::okToPrint(GBool ignoreOwnerPW) {
-  return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permPrint);
+  return (1);
 }
 
 GBool XRef::okToChange(GBool ignoreOwnerPW) {
-  return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permChange);
+  return (1);
 }
 
 GBool XRef::okToCopy(GBool ignoreOwnerPW) {
-  return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permCopy);
+  return (1);
 }
 
 GBool XRef::okToAddNotes(GBool ignoreOwnerPW) {
-  return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permNotes);
+  return (1);
 }
 
 Object *XRef::fetch(int num, int gen, Object *obj) {
@@ -837,6 +848,11 @@ Object *XRef::fetch(int num, int gen, Object *obj) {
 	delete objStr;
       }
       objStr = new ObjectStream(this, e->offset);
+      if (!objStr->isOk()) {
+	delete objStr;
+	objStr = NULL;
+	goto err;
+      }
     }
     objStr->getObject(e->gen, num, obj);
     break;
