Commit 47f4ebcdac39256b084cdbb91ff04392fca4bb8d

Authored by Jay Berkenbilt
1 parent 3e5aaa29

Ignore unused field in xref entry, avoiding range error (fixes #482)

ChangeLog
  1 +2020-11-04 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * Ignore the value of the offset/generation field in an xref entry
  4 + for a deleted object. Also attempt file recovery on lower-level
  5 + exceptions thrown while reading the xref table. Fixes #482.
  6 +
1 7 2020-10-31 Jay Berkenbilt <ejb@ql.org>
2 8  
3 9 * 10.0.3: release
... ...
libqpdf/QPDF.cc
... ... @@ -425,7 +425,20 @@ QPDF::parse(char const* password)
425 425 throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0,
426 426 "can't find startxref");
427 427 }
428   - read_xref(xref_offset);
  428 + try
  429 + {
  430 + read_xref(xref_offset);
  431 + }
  432 + catch (QPDFExc&)
  433 + {
  434 + throw;
  435 + }
  436 + catch (std::exception& e)
  437 + {
  438 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0,
  439 + std::string("error reading xref: ") + e.what());
  440 +
  441 + }
429 442 }
430 443 catch (QPDFExc& e)
431 444 {
... ... @@ -1250,6 +1263,14 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
1250 1263 // This is needed by checkLinearization()
1251 1264 this->m->first_xref_item_offset = xref_offset;
1252 1265 }
  1266 + if (fields[0] == 0)
  1267 + {
  1268 + // Ignore fields[2], which we don't care about in this
  1269 + // case. This works around the issue of some PDF files
  1270 + // that put invalid values, like -1, here for deleted
  1271 + // objects.
  1272 + fields[2] = 0;
  1273 + }
1253 1274 insertXrefEntry(obj, toI(fields[0]),
1254 1275 fields[1], toI(fields[2]));
1255 1276 }
... ...
qpdf/qtest/qpdf.test
... ... @@ -1496,7 +1496,7 @@ $td-&gt;runtest(&quot;detect loops in pages structure&quot;,
1496 1496 show_ntests();
1497 1497 # ----------
1498 1498 $td->notify("--- Xref ---");
1499   -$n_tests += 5;
  1499 +$n_tests += 6;
1500 1500  
1501 1501 # Handle file with invalid xref table and object 0 as a regular object
1502 1502 # (bug 3159950).
... ... @@ -1538,6 +1538,12 @@ $td-&gt;runtest(&quot;show number of pages&quot;,
1538 1538 {$td->STRING => "20\n", $td->EXIT_STATUS => 0},
1539 1539 $td->NORMALIZE_NEWLINES);
1540 1540  
  1541 +# Issue 482 -- don't range check fields[2] for xref entry type 0.
  1542 +$td->runtest("out of range in deleted object",
  1543 + {$td->COMMAND => "qpdf --check xref-range.pdf"},
  1544 + {$td->FILE => "xref-range.out", $td->EXIT_STATUS => 0},
  1545 + $td->NORMALIZE_NEWLINES);
  1546 +
1541 1547 show_ntests();
1542 1548 # ----------
1543 1549 $td->notify("--- Overwrite self ---");
... ...
qpdf/qtest/qpdf/issue-150.out
1 1 WARNING: issue-150.pdf: can't find PDF header
2   -overflow/underflow converting 9900000000000000000 to 64-bit integer
  2 +WARNING: issue-150.pdf: file is damaged
  3 +WARNING: issue-150.pdf: error reading xref: overflow/underflow converting 9900000000000000000 to 64-bit integer
  4 +WARNING: issue-150.pdf: Attempting to reconstruct cross-reference table
  5 +issue-150.pdf: unable to find trailer dictionary while recovering damaged file
... ...
qpdf/qtest/qpdf/xref-range.out 0 → 100644
  1 +checking xref-range.pdf
  2 +PDF Version: 1.5
  3 +File is not encrypted
  4 +File is not linearized
  5 +No syntax or stream encoding errors found; the file may still contain
  6 +errors that qpdf cannot detect
... ...
qpdf/qtest/qpdf/xref-range.pdf 0 → 100644
No preview for this file type