Blob Blame History Raw
diff -urN ../qpdf-4.0.1.orig/ChangeLog ./ChangeLog
--- ../qpdf-4.0.1.orig/ChangeLog	2013-01-17 14:51:04.000000000 +0000
+++ ./ChangeLog	2013-03-04 21:15:53.952108469 +0000
@@ -1,3 +1,13 @@
+2013-02-23  Jay Berkenbilt  <ejb@ql.org>
+
+	* Bug fix: properly handle overridden compressed objects.  When
+	caching objects from an object stream, only cache objects that,
+	based on the xref table, would actually be resolved into this
+	stream.  Prior to this fix, if an object stream A contained an
+	object B that was overridden by an appended section of the file,
+	qpdf would cache the old value of B if any non-overridden member
+	of A was accessed before B.  This commit fixes that bug.
+
 2013-01-17  Jay Berkenbilt  <ejb@ql.org>
 
 	* 4.0.1: release
diff -urN ../qpdf-4.0.1.orig/libqpdf/QPDF.cc ./libqpdf/QPDF.cc
--- ../qpdf-4.0.1.orig/libqpdf/QPDF.cc	2013-01-17 14:51:04.000000000 +0000
+++ ./libqpdf/QPDF.cc	2013-03-04 21:15:53.952108469 +0000
@@ -1538,20 +1538,31 @@
 	offsets[num] = offset + first;
     }
 
+    // To avoid having to read the object stream multiple times, store
+    // all objects that would be found here in the cache.  Remember
+    // that some objects stored here might have been overridden by new
+    // objects appended to the file, so it is necessary to recheck the
+    // xref table and only cache what would actually be resolved here.
     for (std::map<int, int>::iterator iter = offsets.begin();
 	 iter != offsets.end(); ++iter)
     {
 	int obj = (*iter).first;
-	int offset = (*iter).second;
-	input->seek(offset, SEEK_SET);
-	QPDFObjectHandle oh = readObject(input, "", obj, 0, true);
-
-	// Store in cache
 	ObjGen og(obj, 0);
-
-	this->obj_cache[og] =
-	    ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh),
-		     end_before_space, end_after_space);
+        QPDFXRefEntry const& entry = this->xref_table[og];
+        if ((entry.getType() == 2) &&
+            (entry.getObjStreamNumber() == obj_stream_number))
+        {
+            int offset = (*iter).second;
+            input->seek(offset, SEEK_SET);
+            QPDFObjectHandle oh = readObject(input, "", obj, 0, true);
+            this->obj_cache[og] =
+                ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh),
+                         end_before_space, end_after_space);
+        }
+        else
+        {
+            //QTC::TC("qpdf", "QPDF not caching overridden objstm object");
+        }
     }
 }