diff -up qpdf-6.0.0/include/qpdf/QPDF.hh.CVE-2017-9209 qpdf-6.0.0/include/qpdf/QPDF.hh --- qpdf-6.0.0/include/qpdf/QPDF.hh.CVE-2017-9209 2017-08-03 10:00:17.489291722 +0200 +++ qpdf-6.0.0/include/qpdf/QPDF.hh 2017-08-03 10:00:17.494291685 +0200 @@ -1095,6 +1095,7 @@ class QPDF // copied_stream_data_provider is owned by copied_streams CopiedStreamDataProvider* copied_stream_data_provider; std::set attachment_streams; + bool reconstructed_xref; // Linearization data qpdf_offset_t first_xref_item_offset; // actual value from file diff -up qpdf-6.0.0/libqpdf/QPDF.cc.CVE-2017-9209 qpdf-6.0.0/libqpdf/QPDF.cc --- qpdf-6.0.0/libqpdf/QPDF.cc.CVE-2017-9209 2017-08-03 10:00:17.491291707 +0200 +++ qpdf-6.0.0/libqpdf/QPDF.cc 2017-08-03 10:01:43.243661883 +0200 @@ -93,6 +93,7 @@ QPDF::QPDF() : cached_key_generation(0), pushed_inherited_attributes_to_pages(false), copied_stream_data_provider(0), + reconstructed_xref(false), first_xref_item_offset(0), uncompressed_after_compressed(false) { @@ -331,6 +332,14 @@ QPDF::setTrailer(QPDFObjectHandle obj) void QPDF::reconstruct_xref(QPDFExc& e) { + if (this->reconstructed_xref) + { + // Avoid xref reconstruction infinite loops + throw e; + } + + this->reconstructed_xref = true; + PCRE obj_re("^\\s*(\\d+)\\s+(\\d+)\\s+obj\\b"); PCRE endobj_re("^\\s*endobj\\b"); PCRE trailer_re("^\\s*trailer\\b");