Commit 620dfdbf305d4e703b1c97af9808cf119afcc337
1 parent
d4a4088d
Apply sanity checks during xref stream parsing
Detect corrupt xref streams early to avoid excessive runtime and memory usage.
Showing
2 changed files
with
5 additions
and
1 deletions
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}; |