Commit bf4b25b27ee61dcd57854e0fee1eae01a597cd10
1 parent
a9a3e5fd
Fix startxref recovery
Backup and restore the xref table during attempted startxref recovery to avoid corrupt states. Added a guard condition to handle invalid xref entries types, preventing processing of unsupported cases. These changes improve robustness during PDF parsing and recovery.
Showing
1 changed file
with
7 additions
and
0 deletions
libqpdf/QPDF_objects.cc
| ... | ... | @@ -256,10 +256,12 @@ QPDF::reconstruct_xref(QPDFExc& e, bool found_startxref) |
| 256 | 256 | |
| 257 | 257 | if (!found_startxref && !startxrefs.empty() && !found_objects.empty() && |
| 258 | 258 | startxrefs.back() > std::get<2>(found_objects.back())) { |
| 259 | + auto xref_backup{m->xref_table}; | |
| 259 | 260 | try { |
| 260 | 261 | m->file->seek(startxrefs.back(), SEEK_SET); |
| 261 | 262 | if (auto offset = QUtil::string_to_ll(readToken(*m->file).getValue().data())) { |
| 262 | 263 | read_xref(offset); |
| 264 | + | |
| 263 | 265 | if (getRoot().getKey("/Pages").isDictionary()) { |
| 264 | 266 | QTC::TC("qpdf", "QPDF startxref more than 1024 before end"); |
| 265 | 267 | warn(damagedPDF( |
| ... | ... | @@ -273,6 +275,7 @@ QPDF::reconstruct_xref(QPDFExc& e, bool found_startxref) |
| 273 | 275 | } catch (...) { |
| 274 | 276 | // ok, bad luck. Do recovery. |
| 275 | 277 | } |
| 278 | + m->xref_table = std::move(xref_backup); | |
| 276 | 279 | } |
| 277 | 280 | |
| 278 | 281 | auto rend = found_objects.rend(); |
| ... | ... | @@ -1011,6 +1014,10 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2) |
| 1011 | 1014 | // later xref table has registered this object. Disregard this one. |
| 1012 | 1015 | int new_gen = f0 == 2 ? 0 : f2; |
| 1013 | 1016 | |
| 1017 | + if (!(f0 == 1 || f0 == 2)) { | |
| 1018 | + return; | |
| 1019 | + } | |
| 1020 | + | |
| 1014 | 1021 | if (!(obj > 0 && obj <= m->xref_table_max_id && 0 <= f2 && new_gen < 65535)) { |
| 1015 | 1022 | // We are ignoring invalid objgens. Most will arrive here from xref reconstruction. There |
| 1016 | 1023 | // is probably no point having another warning but we could count invalid items in order to | ... | ... |