aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/qpdf/QPDF.hh5
-rw-r--r--libqpdf/QPDF.cc64
-rw-r--r--libqpdf/QPDFWriter.cc2
3 files changed, 30 insertions, 41 deletions
diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh
index 7cec14d2..5b2db6a8 100644
--- a/include/qpdf/QPDF.hh
+++ b/include/qpdf/QPDF.hh
@@ -1173,6 +1173,7 @@ class QPDF
void inParse(bool);
void setTrailer(QPDFObjectHandle obj);
void read_xref(qpdf_offset_t offset);
+ bool resolveXRefTable();
void reconstruct_xref(QPDFExc& e);
bool
parse_xrefFirst(std::string const& line, int& obj, int& num, int& bytes);
@@ -1202,10 +1203,10 @@ class QPDF
bool attempt_recovery,
qpdf_offset_t offset,
std::string const& description,
- QPDFObjGen const& exp_og,
+ QPDFObjGen exp_og,
QPDFObjGen& og,
bool skip_cache_if_in_xref);
- void resolve(QPDFObjGen const& og);
+ void resolve(QPDFObjGen og);
void resolveObjectsInStream(int obj_stream_number);
void stopOnError(std::string const& message);
QPDFObjectHandle reserveObjectIfNotExists(QPDFObjGen const& og);
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc
index 89487ee1..86846675 100644
--- a/libqpdf/QPDF.cc
+++ b/libqpdf/QPDF.cc
@@ -1292,48 +1292,36 @@ QPDF::showXRefTable()
}
}
+// Resolve all objects in the xref table. If this triggers a xref table
+// reconstruction abort and return false. Otherwise return true.
+bool
+QPDF::resolveXRefTable()
+{
+ bool may_change = !this->m->reconstructed_xref;
+ for (auto& iter: this->m->xref_table) {
+ if (isUnresolved(iter.first)) {
+ resolve(iter.first);
+ if (may_change && this->m->reconstructed_xref) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+// 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) {
+ if (this->m->fixed_dangling_refs) {
return;
}
-
- // 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);
- }
- }
-
- // 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;
- }
- }
- 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.
+ if (!resolveXRefTable()) {
QTC::TC("qpdf", "QPDF fix dangling triggered xref reconstruction");
- fixDanglingReferences(force);
- } else {
- this->m->fixed_dangling_refs = true;
+ resolveXRefTable();
}
+ this->m->fixed_dangling_refs = true;
}
size_t
@@ -1356,7 +1344,7 @@ QPDF::getAllObjects()
{
// After fixDanglingReferences is called, all objects are in the
// object cache.
- fixDanglingReferences(true);
+ fixDanglingReferences();
std::vector<QPDFObjectHandle> result;
for (auto const& iter: this->m->obj_cache) {
result.push_back(newIndirect(iter.first, iter.second.object));
@@ -1616,7 +1604,7 @@ QPDF::readObjectAtOffset(
bool try_recovery,
qpdf_offset_t offset,
std::string const& description,
- QPDFObjGen const& exp_og,
+ QPDFObjGen exp_og,
QPDFObjGen& og,
bool skip_cache_if_in_xref)
{
@@ -1799,7 +1787,7 @@ QPDF::readObjectAtOffset(
}
void
-QPDF::resolve(QPDFObjGen const& og)
+QPDF::resolve(QPDFObjGen og)
{
if (!isUnresolved(og)) {
return;
diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc
index b29f75b9..b07aef53 100644
--- a/libqpdf/QPDFWriter.cc
+++ b/libqpdf/QPDFWriter.cc
@@ -2266,7 +2266,7 @@ QPDFWriter::prepareFileForWrite()
// Make document extension level information direct as required by
// the spec.
- this->m->pdf.fixDanglingReferences(true);
+ this->m->pdf.fixDanglingReferences();
QPDFObjectHandle root = this->m->pdf.getRoot();
for (auto const& key: root.getKeys()) {
QPDFObjectHandle oh = root.getKey(key);