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 /include | |
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 'include')
-rw-r--r-- | include/qpdf/QPDF.hh | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh index f7a31edf..4742275f 100644 --- a/include/qpdf/QPDF.hh +++ b/include/qpdf/QPDF.hh @@ -603,6 +603,25 @@ class QPDF int gen; }; + class ResolveRecorder + { + public: + ResolveRecorder(QPDF* qpdf, QPDFObjGen const& og) : + qpdf(qpdf), + og(og) + { + qpdf->resolving.insert(og); + } + virtual ~ResolveRecorder() + { + this->qpdf->resolving.erase(og); + } + private: + QPDF* qpdf; + QPDFObjGen og; + }; + friend class ResolveRecorder; + void parse(char const* password); void warn(QPDFExc const& e); void setTrailer(QPDFObjectHandle obj); @@ -1065,6 +1084,7 @@ class QPDF std::map<QPDFObjGen, QPDFXRefEntry> xref_table; std::set<int> deleted_objects; std::map<QPDFObjGen, ObjCache> obj_cache; + std::set<QPDFObjGen> resolving; QPDFObjectHandle trailer; std::vector<QPDFObjectHandle> all_pages; std::map<QPDFObjGen, int> pageobj_to_pages_pos; |