Commit 620dfdbf305d4e703b1c97af9808cf119afcc337

Authored by m-holger
1 parent d4a4088d

Apply sanity checks during xref stream parsing

Detect corrupt xref streams early to avoid excessive runtime and memory usage.
libqpdf/QPDF_objects.cc
@@ -768,11 +768,13 @@ QPDF::read_xrefStream(qpdf_offset_t xref_offset, bool in_stream_recovery) @@ -768,11 +768,13 @@ QPDF::read_xrefStream(qpdf_offset_t xref_offset, bool in_stream_recovery)
768 QPDFObjGen x_og; 768 QPDFObjGen x_og;
769 QPDFObjectHandle xref_obj; 769 QPDFObjectHandle xref_obj;
770 try { 770 try {
  771 + m->in_read_xref_stream = true;
771 xref_obj = 772 xref_obj =
772 readObjectAtOffset(false, xref_offset, "xref stream", QPDFObjGen(0, 0), x_og, true); 773 readObjectAtOffset(false, xref_offset, "xref stream", QPDFObjGen(0, 0), x_og, true);
773 } catch (QPDFExc&) { 774 } catch (QPDFExc&) {
774 // ignore -- report error below 775 // ignore -- report error below
775 } 776 }
  777 + m->in_read_xref_stream = false;
776 if (xref_obj.isStreamOfType("/XRef")) { 778 if (xref_obj.isStreamOfType("/XRef")) {
777 QTC::TC("qpdf", "QPDF found xref stream"); 779 QTC::TC("qpdf", "QPDF found xref stream");
778 return processXRefStream(xref_offset, xref_obj, in_stream_recovery); 780 return processXRefStream(xref_offset, xref_obj, in_stream_recovery);
@@ -1199,7 +1201,8 @@ QPDF::readObject(std::string const& description, QPDFObjGen og) @@ -1199,7 +1201,8 @@ QPDF::readObject(std::string const& description, QPDFObjGen og)
1199 m->tokenizer, 1201 m->tokenizer,
1200 decrypter_ptr, 1202 decrypter_ptr,
1201 *this, 1203 *this,
1202 - m->in_xref_reconstruction); 1204 + m->in_xref_reconstruction || m->in_read_xref_stream);
  1205 + ;
1203 if (empty) { 1206 if (empty) {
1204 // Nothing in the PDF spec appears to allow empty objects, but they have been encountered in 1207 // Nothing in the PDF spec appears to allow empty objects, but they have been encountered in
1205 // actual PDF files and Adobe Reader appears to ignore them. 1208 // actual PDF files and Adobe Reader appears to ignore them.
libqpdf/qpdf/QPDF_private.hh
@@ -491,6 +491,7 @@ class QPDF::Members @@ -491,6 +491,7 @@ class QPDF::Members
491 CopiedStreamDataProvider* copied_stream_data_provider{nullptr}; 491 CopiedStreamDataProvider* copied_stream_data_provider{nullptr};
492 bool reconstructed_xref{false}; 492 bool reconstructed_xref{false};
493 bool in_xref_reconstruction{false}; 493 bool in_xref_reconstruction{false};
  494 + bool in_read_xref_stream{false};
494 bool fixed_dangling_refs{false}; 495 bool fixed_dangling_refs{false};
495 bool immediate_copy_from{false}; 496 bool immediate_copy_from{false};
496 bool in_parse{false}; 497 bool in_parse{false};