mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 10:58:58 +00:00
Fix bug in QPDFWriter::preserveObjectStreams
Code failed to allow for QPDF::getCompressibleObjSet deleting objects from the object cache in case of multiple entries for the same object id. Add fuzz test case 68668.
This commit is contained in:
parent
6ae439f180
commit
02e89bbe47
@ -116,6 +116,7 @@ set(CORPUS_OTHER
|
||||
65777.fuzz
|
||||
68374.fuzz
|
||||
68377.fuzz
|
||||
68668.fuzz
|
||||
)
|
||||
|
||||
set(CORPUS_DIR ${CMAKE_CURRENT_BINARY_DIR}/qpdf_corpus)
|
||||
|
BIN
fuzz/qpdf_extra/68668.fuzz
Normal file
BIN
fuzz/qpdf_extra/68668.fuzz
Normal file
Binary file not shown.
@ -21,7 +21,7 @@ my @fuzzers = (
|
||||
['pngpredictor' => 1],
|
||||
['runlength' => 6],
|
||||
['tiffpredictor' => 2],
|
||||
['qpdf' => 58], # increment when adding new files
|
||||
['qpdf' => 59], # increment when adding new files
|
||||
);
|
||||
|
||||
my $n_tests = 0;
|
||||
|
@ -1944,28 +1944,30 @@ QPDFWriter::preserveObjectStreams()
|
||||
// that are not allowed to be in object streams. In addition to removing objects that were
|
||||
// erroneously included in object streams in the source PDF, it also prevents unreferenced
|
||||
// objects from being included.
|
||||
auto iter = xref.cbegin();
|
||||
auto end = xref.cend();
|
||||
|
||||
// Start by scanning for first compressed object in case we don't have any object streams to
|
||||
// process.
|
||||
for (; iter != end; ++iter) {
|
||||
m->obj.streams_empty = true;
|
||||
if (m->preserve_unreferenced_objects) {
|
||||
for (auto iter = xref.cbegin(); iter != end; ++iter) {
|
||||
if (iter->second.getType() == 2) {
|
||||
// Pdf contains object streams.
|
||||
QTC::TC(
|
||||
"qpdf",
|
||||
"QPDFWriter preserve object streams",
|
||||
m->preserve_unreferenced_objects ? 0 : 1);
|
||||
|
||||
if (m->preserve_unreferenced_objects) {
|
||||
for (; iter != end; ++iter) {
|
||||
if (iter->second.getType() == 2) {
|
||||
QTC::TC("qpdf", "QPDFWriter preserve object streams preserve unreferenced");
|
||||
m->obj.streams_empty = false;
|
||||
m->obj[iter->first].object_stream = iter->second.getObjStreamNumber();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Start by scanning for first compressed object in case we don't have any object streams to
|
||||
// process.
|
||||
for (auto iter = xref.cbegin(); iter != end; ++iter) {
|
||||
if (iter->second.getType() == 2) {
|
||||
// Pdf contains object streams.
|
||||
QTC::TC("qpdf", "QPDFWriter preserve object streams");
|
||||
m->obj.streams_empty = false;
|
||||
auto eligible = QPDF::Writer::getCompressibleObjSet(m->pdf);
|
||||
for (; iter != end; ++iter) {
|
||||
// The object pointed to by iter may be a previous generation, in which case it is
|
||||
// removed by getCompressibleObjSet. We need to restart the loop (while the object
|
||||
// table may contain multiple generations of an object).
|
||||
for (iter = xref.cbegin(); iter != end; ++iter) {
|
||||
if (iter->second.getType() == 2) {
|
||||
auto id = static_cast<size_t>(iter->first.getObj());
|
||||
if (id < eligible.size() && eligible[id]) {
|
||||
@ -1975,12 +1977,10 @@ QPDFWriter::preserveObjectStreams()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
// No compressed objects found.
|
||||
m->obj.streams_empty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -600,7 +600,8 @@ QPDFAcroFormDocumentHelper AP parse error 0
|
||||
QPDFJob copy fields not this file 0
|
||||
QPDFJob copy fields non-first from orig 0
|
||||
QPDF resolve duplicated page in insert 0
|
||||
QPDFWriter preserve object streams 1
|
||||
QPDFWriter preserve object streams 0
|
||||
QPDFWriter preserve object streams preserve unreferenced 0
|
||||
QPDFWriter exclude from object stream 0
|
||||
QPDF_pages findPage not found 0
|
||||
QPDFObjectHandle check ownership 0
|
||||
|
Loading…
Reference in New Issue
Block a user