aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/QPDF.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libqpdf/QPDF.cc')
-rw-r--r--libqpdf/QPDF.cc32
1 files changed, 32 insertions, 0 deletions
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc
index af3db080..67f5e2e0 100644
--- a/libqpdf/QPDF.cc
+++ b/libqpdf/QPDF.cc
@@ -580,6 +580,38 @@ QPDF::reconstruct_xref(QPDFExc& e)
m->deleted_objects.clear();
if (!m->trailer.isInitialized()) {
+ qpdf_offset_t max_offset{0};
+ // If there are any xref streams, take the last one to appear.
+ for (auto const& iter: m->xref_table) {
+ auto entry = iter.second;
+ if (entry.getType() != 1) {
+ continue;
+ }
+ auto oh = getObjectByObjGen(iter.first);
+ try {
+ if (!oh.isStreamOfType("/XRef")) {
+ continue;
+ }
+ } catch (std::exception&) {
+ continue;
+ }
+ auto offset = entry.getOffset();
+ if (offset > max_offset) {
+ max_offset = offset;
+ setTrailer(oh.getDict());
+ }
+ }
+ if (max_offset > 0) {
+ try {
+ read_xref(max_offset);
+ } catch (std::exception&) {
+ throw damagedPDF("", 0, "error decoding candidate xref stream while recovering damaged file");
+ }
+ QTC::TC("qpdf", "QPDF recover xref stream");
+ }
+ }
+
+ if (!m->trailer.isInitialized()) {
// We could check the last encountered object to see if it was an xref stream. If so, we
// could try to get the trailer from there. This may make it possible to recover files with
// bad startxref pointers even when they have object streams.