mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 02:49:00 +00:00
Bug fix: properly handle overridden compressed objects
When caching objects in an object stream, only cache objects that still resolve to that stream. See Changelog mod from this commit for details.
This commit is contained in:
parent
7e7c93951f
commit
6c7bf114dc
10
ChangeLog
10
ChangeLog
@ -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-31 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
* Do not remove libtool's .la file during the make install step.
|
||||
|
@ -1538,20 +1538,31 @@ QPDF::resolveObjectsInStream(int obj_stream_number)
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,3 +261,4 @@ qpdf-c called qpdf_set_r5_encryption_parameters 0
|
||||
qpdf-c called qpdf_set_r6_encryption_parameters 0
|
||||
QPDFObjectHandle EOF in inline image 0
|
||||
QPDFObjectHandle inline image token 0
|
||||
QPDF not caching overridden objstm object 0
|
||||
|
@ -199,7 +199,7 @@ $td->runtest("remove page we don't have",
|
||||
show_ntests();
|
||||
# ----------
|
||||
$td->notify("--- Miscellaneous Tests ---");
|
||||
$n_tests += 60;
|
||||
$n_tests += 61;
|
||||
|
||||
$td->runtest("qpdf version",
|
||||
{$td->COMMAND => "qpdf --version"},
|
||||
@ -484,6 +484,18 @@ $td->runtest("content stream errors",
|
||||
$td->EXIT_STATUS => 2},
|
||||
$td->NORMALIZE_NEWLINES);
|
||||
|
||||
# The file override-compressed-object.pdf contains an object stream
|
||||
# with four strings in it. The file is then appended. The appended
|
||||
# section overrides one of the four strings with a string in another
|
||||
# object stream and another one in an uncompressed object. The other
|
||||
# two strings are left alone. The test case exercises that all four
|
||||
# objects have the correct value.
|
||||
$td->runtest("overridden compressed objects",
|
||||
{$td->COMMAND => "test_driver 38 override-compressed-object.pdf"},
|
||||
{$td->FILE => "override-compressed-object.out",
|
||||
$td->EXIT_STATUS => 0},
|
||||
$td->NORMALIZE_NEWLINES);
|
||||
|
||||
show_ntests();
|
||||
# ----------
|
||||
$td->notify("--- Numeric range parsing tests ---");
|
||||
|
5
qpdf/qtest/qpdf/override-compressed-object.out
Normal file
5
qpdf/qtest/qpdf/override-compressed-object.out
Normal file
@ -0,0 +1,5 @@
|
||||
(orig-1)
|
||||
(override-2)
|
||||
(override-3)
|
||||
(orig-4)
|
||||
test 38 done
|
BIN
qpdf/qtest/qpdf/override-compressed-object.pdf
Normal file
BIN
qpdf/qtest/qpdf/override-compressed-object.pdf
Normal file
Binary file not shown.
@ -1302,6 +1302,15 @@ void runtest(int n, char const* filename1, char const* arg2)
|
||||
QPDFObjectHandle::parseContentStream(contents, &cb);
|
||||
}
|
||||
}
|
||||
else if (n == 38)
|
||||
{
|
||||
// Designed for override-compressed-object.pdf
|
||||
QPDFObjectHandle qtest = pdf.getRoot().getKey("/QTest");
|
||||
for (int i = 0; i < qtest.getArrayNItems(); ++i)
|
||||
{
|
||||
std::cout << qtest.getArrayItem(i).unparseResolved() << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error(std::string("invalid test ") +
|
||||
|
Loading…
Reference in New Issue
Block a user