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 + + * 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 * 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::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"); + } } }