From 769a4915e8392490b77aba3b6ddda3e4a2e89508 Mon Sep 17 00:00:00 2001 From: m-holger Date: Tue, 4 Jul 2023 14:01:03 +0100 Subject: Add new private method QPDF::insertReconstructedXrefEntry --- include/qpdf/QPDF.hh | 1 + libqpdf/QPDF.cc | 18 ++++++++++++++++-- libqpdf/qpdf/JSONHandler.hh | 1 - 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh index e54947d9..6f346422 100644 --- a/include/qpdf/QPDF.hh +++ b/include/qpdf/QPDF.hh @@ -1003,6 +1003,7 @@ class QPDF qpdf_offset_t read_xrefStream(qpdf_offset_t offset); qpdf_offset_t processXRefStream(qpdf_offset_t offset, QPDFObjectHandle& xref_stream); void insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite = false); + void insertReconstructedXrefEntry(int obj, qpdf_offset_t f1, int f2); void setLastObjectDescription(std::string const& description, QPDFObjGen const& og); QPDFObjectHandle readObject( std::shared_ptr, diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index 396dfe8f..8c96eb9c 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -564,7 +564,7 @@ QPDF::reconstruct_xref(QPDFExc& e) if ((t2.isInteger()) && (readToken(m->file, MAX_LEN).isWord("obj"))) { int obj = QUtil::string_to_int(t1.getValue().c_str()); int gen = QUtil::string_to_int(t2.getValue().c_str()); - insertXrefEntry(obj, 1, token_start, gen, true); + insertReconstructedXrefEntry(obj, token_start, gen); } } else if (!m->trailer.isInitialized() && t1.isWord("trailer")) { QPDFObjectHandle t = readObject(m->file, "trailer", QPDFObjGen(), false); @@ -577,6 +577,7 @@ QPDF::reconstruct_xref(QPDFExc& e) m->file->seek(next_line_start, SEEK_SET); line_start = next_line_start; } + m->deleted_objects.clear(); if (!m->trailer.isInitialized()) { // We could check the last encountered object to see if it was an xref stream. If so, we @@ -1126,7 +1127,6 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite) QPDFObjGen og(obj, gen); if (m->xref_table.count(og)) { if (overwrite) { - QTC::TC("qpdf", "QPDF xref overwrite object"); m->xref_table.erase(og); } else { QTC::TC("qpdf", "QPDF xref reused object"); @@ -1160,6 +1160,20 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite) } } +// Replace uncompressed object. This is used in xref recovery mode, which reads the file from +// beginning to end. +void +QPDF::insertReconstructedXrefEntry(int obj, qpdf_offset_t f1, int f2) +{ + QPDFObjGen og(obj, f2); + if (!m->deleted_objects.count(obj)) { + // deleted_objects stores the uncompressed objects removed from the xref table at the start + // of recovery. + QTC::TC("qpdf", "QPDF xref overwrite object"); + m->xref_table[QPDFObjGen(obj, f2)] = QPDFXRefEntry(f1); + } +} + void QPDF::showXRefTable() { diff --git a/libqpdf/qpdf/JSONHandler.hh b/libqpdf/qpdf/JSONHandler.hh index 653924f6..9b2a0b33 100644 --- a/libqpdf/qpdf/JSONHandler.hh +++ b/libqpdf/qpdf/JSONHandler.hh @@ -53,7 +53,6 @@ class JSONHandler static void usage(std::string const& msg); - class Members; std::unique_ptr m; -- cgit v1.2.3-70-g09d2