Commit 769a4915e8392490b77aba3b6ddda3e4a2e89508
1 parent
b8f20fe3
Add new private method QPDF::insertReconstructedXrefEntry
Showing
3 changed files
with
17 additions
and
3 deletions
include/qpdf/QPDF.hh
| ... | ... | @@ -1003,6 +1003,7 @@ class QPDF |
| 1003 | 1003 | qpdf_offset_t read_xrefStream(qpdf_offset_t offset); |
| 1004 | 1004 | qpdf_offset_t processXRefStream(qpdf_offset_t offset, QPDFObjectHandle& xref_stream); |
| 1005 | 1005 | void insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite = false); |
| 1006 | + void insertReconstructedXrefEntry(int obj, qpdf_offset_t f1, int f2); | |
| 1006 | 1007 | void setLastObjectDescription(std::string const& description, QPDFObjGen const& og); |
| 1007 | 1008 | QPDFObjectHandle readObject( |
| 1008 | 1009 | std::shared_ptr<InputSource>, | ... | ... |
libqpdf/QPDF.cc
| ... | ... | @@ -564,7 +564,7 @@ QPDF::reconstruct_xref(QPDFExc& e) |
| 564 | 564 | if ((t2.isInteger()) && (readToken(m->file, MAX_LEN).isWord("obj"))) { |
| 565 | 565 | int obj = QUtil::string_to_int(t1.getValue().c_str()); |
| 566 | 566 | int gen = QUtil::string_to_int(t2.getValue().c_str()); |
| 567 | - insertXrefEntry(obj, 1, token_start, gen, true); | |
| 567 | + insertReconstructedXrefEntry(obj, token_start, gen); | |
| 568 | 568 | } |
| 569 | 569 | } else if (!m->trailer.isInitialized() && t1.isWord("trailer")) { |
| 570 | 570 | QPDFObjectHandle t = readObject(m->file, "trailer", QPDFObjGen(), false); |
| ... | ... | @@ -577,6 +577,7 @@ QPDF::reconstruct_xref(QPDFExc& e) |
| 577 | 577 | m->file->seek(next_line_start, SEEK_SET); |
| 578 | 578 | line_start = next_line_start; |
| 579 | 579 | } |
| 580 | + m->deleted_objects.clear(); | |
| 580 | 581 | |
| 581 | 582 | if (!m->trailer.isInitialized()) { |
| 582 | 583 | // 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) |
| 1126 | 1127 | QPDFObjGen og(obj, gen); |
| 1127 | 1128 | if (m->xref_table.count(og)) { |
| 1128 | 1129 | if (overwrite) { |
| 1129 | - QTC::TC("qpdf", "QPDF xref overwrite object"); | |
| 1130 | 1130 | m->xref_table.erase(og); |
| 1131 | 1131 | } else { |
| 1132 | 1132 | 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) |
| 1160 | 1160 | } |
| 1161 | 1161 | } |
| 1162 | 1162 | |
| 1163 | +// Replace uncompressed object. This is used in xref recovery mode, which reads the file from | |
| 1164 | +// beginning to end. | |
| 1165 | +void | |
| 1166 | +QPDF::insertReconstructedXrefEntry(int obj, qpdf_offset_t f1, int f2) | |
| 1167 | +{ | |
| 1168 | + QPDFObjGen og(obj, f2); | |
| 1169 | + if (!m->deleted_objects.count(obj)) { | |
| 1170 | + // deleted_objects stores the uncompressed objects removed from the xref table at the start | |
| 1171 | + // of recovery. | |
| 1172 | + QTC::TC("qpdf", "QPDF xref overwrite object"); | |
| 1173 | + m->xref_table[QPDFObjGen(obj, f2)] = QPDFXRefEntry(f1); | |
| 1174 | + } | |
| 1175 | +} | |
| 1176 | + | |
| 1163 | 1177 | void |
| 1164 | 1178 | QPDF::showXRefTable() |
| 1165 | 1179 | { | ... | ... |