From 701b518d5c56a1449825a3a37a716c58e05e1c3e Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Wed, 26 Jul 2017 05:03:38 -0400 Subject: Detect recursion loops resolving objects (fixes #51) During parsing of an object, sometimes parts of the object have to be resolved. An example is stream lengths. If such an object directly or indirectly points to the object being parsed, it can cause an infinite loop. Guard against all cases of re-entrant resolution of objects. --- libqpdf/QPDF.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'libqpdf/QPDF.cc') diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index 846f188f..ecc13491 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -1471,6 +1471,21 @@ QPDF::resolve(int objid, int generation) // to insert things into the object cache that don't actually // exist in the file. QPDFObjGen og(objid, generation); + if (this->resolving.count(og)) + { + // This can happen if an object references itself directly or + // indirectly in some key that has to be resolved during + // object parsing, such as stream length. + QTC::TC("qpdf", "QPDF recursion loop in resolve"); + warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), + "", this->file->getLastOffset(), + "loop detected resolving object " + + QUtil::int_to_string(objid) + " " + + QUtil::int_to_string(generation))); + return new QPDF_Null; + } + ResolveRecorder rr(this, og); + if (! this->obj_cache.count(og)) { if (! this->xref_table.count(og)) -- cgit v1.2.3-54-g00ecf