mirror of
https://github.com/qpdf/qpdf.git
synced 2025-01-03 15:17:29 +00:00
Fix logic for fixDanglingReferences
This commit is contained in:
parent
1d9209ee74
commit
ff42ea4e6c
@ -1292,48 +1292,48 @@ QPDF::showXRefTable()
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure all objects in the pdf file, including those in indirect references,
|
||||
// appear in the object cache.
|
||||
void
|
||||
QPDF::fixDanglingReferences(bool force)
|
||||
{
|
||||
// Ensure all objects in the pdf file, including those in indirect
|
||||
// references, appear in the object cache.
|
||||
if (this->m->fixed_dangling_refs && !force) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this->m->fixed_dangling_refs) {
|
||||
// First pass is only run if the the xref table has not been
|
||||
// reconstructed. It will be terminated as soon as reconstruction is
|
||||
// triggered.
|
||||
if (!this->m->reconstructed_xref) {
|
||||
// Make sure everything in the xref table appears in the object
|
||||
// cache.
|
||||
for (auto const& iter: this->m->xref_table) {
|
||||
auto og = iter.first;
|
||||
if (!isCached(og)) {
|
||||
m->obj_cache[og] =
|
||||
ObjCache(QPDF_Unresolved::create(this, og), -1, -1);
|
||||
if (this->m->reconstructed_xref) {
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve all known objects. The parser inserts any indirect
|
||||
// reference into the object cache, including dangling references.
|
||||
bool orig_reconstructed_xref = this->m->reconstructed_xref;
|
||||
bool triggered_xref_reconstruction = false;
|
||||
for (auto const& iter: this->m->obj_cache) {
|
||||
resolve(iter.first);
|
||||
if (!orig_reconstructed_xref && this->m->reconstructed_xref) {
|
||||
triggered_xref_reconstruction = true;
|
||||
// We triggered xref reconstruction. We'll have to start
|
||||
// over.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Second pass is skipped if the first pass did not trigger
|
||||
// reconstruction of the xref table.
|
||||
if (this->m->reconstructed_xref) {
|
||||
for (auto const& iter: this->m->xref_table) {
|
||||
auto og = iter.first;
|
||||
if (!isCached(og)) {
|
||||
m->obj_cache[og] =
|
||||
ObjCache(QPDF_Unresolved::create(this, og), -1, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Final pass adds all indirect references to the object cache.
|
||||
for (auto const& iter: this->m->obj_cache) {
|
||||
resolve(iter.first);
|
||||
}
|
||||
if (triggered_xref_reconstruction) {
|
||||
// Resolving objects triggered xref reconstruction. This may
|
||||
// cause new objects to appear in the xref. Start over again.
|
||||
// This recursive call can never go more than two deep since
|
||||
// we never clear this->m->reconstructed_xref.
|
||||
QTC::TC("qpdf", "QPDF fix dangling triggered xref reconstruction");
|
||||
fixDanglingReferences(force);
|
||||
} else {
|
||||
this->m->fixed_dangling_refs = true;
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
|
@ -678,3 +678,4 @@ QPDF_json bad pushedinheritedpageresources 0
|
||||
QPDFPageObjectHelper copied fallback 0
|
||||
QPDFPageObjectHelper used fallback without copying 0
|
||||
QPDF skipping cache for known unchecked object 0
|
||||
QPDF fix dangling triggered xref reconstruction 0
|
||||
|
@ -19,21 +19,13 @@ my $n_tests = 2 * scalar(@dangling);
|
||||
|
||||
foreach my $f (@dangling)
|
||||
{
|
||||
# TEMPORARY
|
||||
my $xflags = 0;
|
||||
if ($f eq 'dangling-bad-xref')
|
||||
{
|
||||
$xflags = $td->EXPECT_FAILURE;
|
||||
}
|
||||
# END TEMPORARY
|
||||
$td->runtest("dangling refs: $f",
|
||||
{$td->COMMAND => "test_driver 53 $f.pdf"},
|
||||
{$td->FILE => "$f-dangling.out", $td->EXIT_STATUS => 0},
|
||||
$td->NORMALIZE_NEWLINES | $xflags);
|
||||
$td->NORMALIZE_NEWLINES);
|
||||
$td->runtest("check output",
|
||||
{$td->FILE => "a.pdf"},
|
||||
{$td->FILE => "$f-dangling-out.pdf"},
|
||||
$xflags);
|
||||
{$td->FILE => "$f-dangling-out.pdf"});
|
||||
}
|
||||
cleanup();
|
||||
$td->report($n_tests);
|
||||
|
Loading…
Reference in New Issue
Block a user