diff options
author | Albert Astals Cid <aacid@kde.org> | 2010-09-21 19:19:27 +0100 |
---|---|---|
committer | Albert Astals Cid <aacid@kde.org> | 2010-09-21 19:19:27 +0100 |
commit | d2578bd66129466b2dd114b6407c147598e09d2b (patch) | |
tree | 3abaf72bc2fba70f1d5ff6b8ddab0a300fb1e8f1 | |
parent | 2fe825deac055be82b220d0127169cb3d61387a8 (diff) |
Avoid loops in Form::fieldLookup
Fixes crash in broken pdf provided by Joel Voss of Leviathan Security Group
-rw-r--r-- | poppler/Dict.h | 3 | ||||
-rw-r--r-- | poppler/Form.cc | 27 |
2 files changed, 27 insertions, 3 deletions
diff --git a/poppler/Dict.h b/poppler/Dict.h index bb747d57..a76bc890 100644 --- a/poppler/Dict.h +++ b/poppler/Dict.h @@ -16,6 +16,7 @@ // Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com> // Copyright (C) 2006 Krzysztof Kowalczyk <kkowalczyk@gmail.com> // Copyright (C) 2007-2008 Julien Rebetez <julienr@svn.gnome.org> +// Copyright (C) 2010 Albert Astals Cid <aacid@kde.org> // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -83,6 +84,8 @@ public: // trailer dictionary, which is read before the xref table is // parsed. void setXRef(XRef *xrefA) { xref = xrefA; } + + XRef *getXRef() { return xref; } private: diff --git a/poppler/Form.cc b/poppler/Form.cc index 21ca672d..ae9c5091 100644 --- a/poppler/Form.cc +++ b/poppler/Form.cc @@ -22,6 +22,7 @@ #pragma implementation #endif +#include <set> #include <stddef.h> #include <string.h> #include "goo/gmem.h" @@ -1181,7 +1182,7 @@ Form::~Form() { } // Look up an inheritable field dictionary entry. -Object *Form::fieldLookup(Dict *field, char *key, Object *obj) { +static Object *fieldLookup(Dict *field, char *key, Object *obj, std::set<int> *usedParents) { Dict *dict; Object parent; @@ -1190,8 +1191,23 @@ Object *Form::fieldLookup(Dict *field, char *key, Object *obj) { return obj; } obj->free(); - if (dict->lookup("Parent", &parent)->isDict()) { - fieldLookup(parent.getDict(), key, obj); + dict->lookupNF("Parent", &parent); + if (parent.isRef()) { + const Ref ref = parent.getRef(); + if (usedParents->find(ref.num) == usedParents->end()) { + usedParents->insert(ref.num); + + Object obj2; + parent.fetch(dict->getXRef(), &obj2); + if (obj2.isDict()) { + fieldLookup(obj2.getDict(), key, obj, usedParents); + } else { + obj->initNull(); + } + obj2.free(); + } + } else if (parent.isDict()) { + fieldLookup(parent.getDict(), key, obj, usedParents); } else { obj->initNull(); } @@ -1199,6 +1215,11 @@ Object *Form::fieldLookup(Dict *field, char *key, Object *obj) { return obj; } +Object *Form::fieldLookup(Dict *field, char *key, Object *obj) { + std::set<int> usedParents; + return ::fieldLookup(field, key, obj, &usedParents); +} + FormField *Form::createFieldFromDict (Object* obj, XRef *xrefA, const Ref& pref) { Object obj2; |