summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Astals Cid <aacid@kde.org>2010-09-21 19:19:27 +0100
committerAlbert Astals Cid <aacid@kde.org>2010-09-21 19:19:27 +0100
commitd2578bd66129466b2dd114b6407c147598e09d2b (patch)
tree3abaf72bc2fba70f1d5ff6b8ddab0a300fb1e8f1
parent2fe825deac055be82b220d0127169cb3d61387a8 (diff)
Avoid loops in Form::fieldLookup
Fixes crash in broken pdf provided by Joel Voss of Leviathan Security Group
-rw-r--r--poppler/Dict.h3
-rw-r--r--poppler/Form.cc27
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
@@ -18,2 +18,3 @@
// Copyright (C) 2007-2008 Julien Rebetez <julienr@svn.gnome.org>
+// Copyright (C) 2010 Albert Astals Cid <aacid@kde.org>
//
@@ -85,2 +86,4 @@ public:
void setXRef(XRef *xrefA) { xref = xrefA; }
+
+ XRef *getXRef() { return xref; }
diff --git a/poppler/Form.cc b/poppler/Form.cc
index 21ca672d..ae9c5091 100644
--- a/poppler/Form.cc
+++ b/poppler/Form.cc
@@ -24,2 +24,3 @@
+#include <set>
#include <stddef.h>
@@ -1183,3 +1184,3 @@ 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;
@@ -1192,4 +1193,19 @@ Object *Form::fieldLookup(Dict *field, char *key, Object *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 {
@@ -1201,2 +1217,7 @@ Object *Form::fieldLookup(Dict *field, char *key, Object *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)