aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/QPDF.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2017-07-26 11:03:38 +0200
committerJay Berkenbilt <ejb@ql.org>2017-07-26 12:24:07 +0200
commit701b518d5c56a1449825a3a37a716c58e05e1c3e (patch)
treebb4891231a8150bf3a2ccb56bca298df433210a0 /libqpdf/QPDF.cc
parentafe0242b263a9e1a8d51dd81e42ab6de2e5127eb (diff)
downloadqpdf-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/QPDF.cc')
-rw-r--r--libqpdf/QPDF.cc15
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))