diff options
author | Jay Berkenbilt <ejb@ql.org> | 2017-07-26 11:03:38 +0200 |
---|---|---|
committer | Jay Berkenbilt <ejb@ql.org> | 2017-07-26 12:24:07 +0200 |
commit | 701b518d5c56a1449825a3a37a716c58e05e1c3e (patch) | |
tree | bb4891231a8150bf3a2ccb56bca298df433210a0 /libqpdf | |
parent | afe0242b263a9e1a8d51dd81e42ab6de2e5127eb (diff) | |
download | qpdf-701b518d5c56a1449825a3a37a716c58e05e1c3e.tar.zst |
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.
Diffstat (limited to 'libqpdf')
-rw-r--r-- | libqpdf/QPDF.cc | 15 |
1 files changed, 15 insertions, 0 deletions
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)) |