[prev in list] [next in list] [prev in thread] [next in thread]
List: freedesktop-poppler
Subject: [poppler] poppler/Form.cc poppler/Form.h
From: aacid () kemper ! freedesktop ! org (Albert Astals Cid)
Date: 2010-11-20 19:15:01
Message-ID: 20101120191501.187E110057 () kemper ! freedesktop ! org
[Download RAW message or body]
poppler/Form.cc | 88 +++++++++++++++++++++++++++++++-------------------------
poppler/Form.h | 14 +++++---
2 files changed, 58 insertions(+), 44 deletions(-)
New commits:
commit 555fa897b275ca7195f22a727b049c8c4f2d74cd
Author: Albert Astals Cid <aacid@kde.org>
Date: Sat Nov 20 19:14:38 2010 +0000
Detect loops in FormField creation
diff --git a/poppler/Form.cc b/poppler/Form.cc
index 78e46ef..74e8d90 100644
--- a/poppler/Form.cc
+++ b/poppler/Form.cc
@@ -759,7 +759,7 @@ FormWidgetSignature::FormWidgetSignature(XRef *xrefA, Object \
*aobj, unsigned num // FormField
//========================================================================
-FormField::FormField(XRef* xrefA, Object *aobj, const Ref& aref, FormFieldType ty)
+FormField::FormField(XRef* xrefA, Object *aobj, const Ref& aref, std::set<int> \
*usedParents, FormFieldType ty) {
xref = xrefA;
aobj->copy(&obj);
@@ -789,32 +789,43 @@ FormField::FormField(XRef* xrefA, Object *aobj, const Ref& \
aref, FormFieldType t }
Object childRef;
array->getNF(i, &childRef);
- //field child
- if (dict->lookup ("FT", &obj3)->isName()) {
- // If I'm not a generic container field and my children
- // are widgets, create widgets for them
- Object obj4;
-
- if (obj2.dictLookup("Subtype",&obj4)->isName()) {
- _createWidget(&obj2, childRef.getRef());
- }
- obj4.free();
- } else if(obj2.dictLookup("FT", &obj3)->isName() || obj2.dictLookup("Kids", \
&obj3)->isArray()) {
- if(terminal) error(-1, "Field can't have both Widget AND Field as kids\n");
+ if (childRef.isRef()) {
+ const Ref ref = childRef.getRef();
+ if (usedParents->find(ref.num) == usedParents->end()) {
+ //field child
+ if (dict->lookup ("FT", &obj3)->isName()) {
+ // If I'm not a generic container field and my children
+ // are widgets, create widgets for them
+ Object obj4;
+
+ if (obj2.dictLookup("Subtype",&obj4)->isName()) {
+ _createWidget(&obj2, childRef.getRef());
+ }
+ obj4.free();
+ } else if(obj2.dictLookup("FT", &obj3)->isName() || \
obj2.dictLookup("Kids", &obj3)->isArray()) { + std::set<int> \
usedParentsAux = *usedParents; + usedParentsAux.insert(ref.num);
+ if(terminal) error(-1, "Field can't have both Widget AND Field as \
kids\n");
- numChildren++;
- children = (FormField**)greallocn(children, numChildren, \
sizeof(FormField*)); + numChildren++;
+ children = (FormField**)greallocn(children, numChildren, \
sizeof(FormField*));
- obj3.free();
- children[numChildren-1] = Form::createFieldFromDict (&obj2, xrefA, \
childRef.getRef());
- }
- // 1 - we will handle 'collapsed' fields (field + annot in the same dict)
- // as if the annot was in the Kids array of the field
- else if (obj2.dictLookup("Subtype",&obj3)->isName()) {
- _createWidget(&obj2, childRef.getRef());
+ obj3.free();
+ children[numChildren-1] = Form::createFieldFromDict (&obj2, xrefA, \
childRef.getRef(), &usedParentsAux); + }
+ // 1 - we will handle 'collapsed' fields (field + annot in the same dict)
+ // as if the annot was in the Kids array of the field
+ else if (obj2.dictLookup("Subtype",&obj3)->isName()) {
+ _createWidget(&obj2, childRef.getRef());
+ }
+ obj3.free();
+ } else {
+ error(-1, "Found loop in FormField creation");
+ }
+ } else {
+ error(-1, "FormField child is not a Ref as expected");
}
obj2.free();
- obj3.free();
}
}
obj1.free();
@@ -926,8 +937,8 @@ FormWidget* FormField::findWidgetByRef (Ref aref)
//------------------------------------------------------------------------
// FormFieldButton
//------------------------------------------------------------------------
-FormFieldButton::FormFieldButton(XRef *xrefA, Object *aobj, const Ref& ref)
- : FormField(xrefA, aobj, ref, formButton)
+FormFieldButton::FormFieldButton(XRef *xrefA, Object *aobj, const Ref& ref, \
std::set<int> *usedParents) + : FormField(xrefA, aobj, ref, usedParents, formButton)
{
Dict* dict = obj.getDict();
active_child = -1;
@@ -1020,8 +1031,8 @@ FormFieldButton::~FormFieldButton()
//------------------------------------------------------------------------
// FormFieldText
//------------------------------------------------------------------------
-FormFieldText::FormFieldText(XRef *xrefA, Object *aobj, const Ref& ref)
- : FormField(xrefA, aobj, ref, formText)
+FormFieldText::FormFieldText(XRef *xrefA, Object *aobj, const Ref& ref, \
std::set<int> *usedParents) + : FormField(xrefA, aobj, ref, usedParents, formText)
{
Dict* dict = obj.getDict();
Object obj1;
@@ -1077,8 +1088,8 @@ FormFieldText::~FormFieldText()
//------------------------------------------------------------------------
// FormFieldChoice
//------------------------------------------------------------------------
-FormFieldChoice::FormFieldChoice(XRef *xrefA, Object *aobj, const Ref& ref)
- : FormField(xrefA, aobj, ref, formChoice)
+FormFieldChoice::FormFieldChoice(XRef *xrefA, Object *aobj, const Ref& ref, \
std::set<int> *usedParents) + : FormField(xrefA, aobj, ref, usedParents, formChoice)
{
numChoices = 0;
choices = NULL;
@@ -1171,8 +1182,8 @@ void FormFieldChoice::_createChoicesTab ()
//------------------------------------------------------------------------
// FormFieldSignature
//------------------------------------------------------------------------
-FormFieldSignature::FormFieldSignature(XRef *xrefA, Object *dict, const Ref& ref)
- : FormField(xrefA, dict, ref, formSignature)
+FormFieldSignature::FormFieldSignature(XRef *xrefA, Object *dict, const Ref& ref, \
std::set<int> *usedParents) + : FormField(xrefA, dict, ref, usedParents, \
formSignature) {
}
@@ -1228,7 +1239,8 @@ Form::Form(XRef *xrefA, Object* acroFormA)
rootFields = (FormField**)greallocn(rootFields,size,sizeof(FormField*));
}
- rootFields[numFields++] = createFieldFromDict (&obj2, xrefA, oref.getRef());
+ std::set<int> usedParents;
+ rootFields[numFields++] = createFieldFromDict (&obj2, xrefA, oref.getRef(), \
&usedParents);
obj2.free();
oref.free();
@@ -1285,21 +1297,21 @@ Object *Form::fieldLookup(Dict *field, char *key, Object \
*obj) { return ::fieldLookup(field, key, obj, &usedParents);
}
-FormField *Form::createFieldFromDict (Object* obj, XRef *xrefA, const Ref& pref)
+FormField *Form::createFieldFromDict (Object* obj, XRef *xrefA, const Ref& pref, \
std::set<int> *usedParents) {
Object obj2;
FormField *field;
if (Form::fieldLookup(obj->getDict (), "FT", &obj2)->isName("Btn")) {
- field = new FormFieldButton(xrefA, obj, pref);
+ field = new FormFieldButton(xrefA, obj, pref, usedParents);
} else if (obj2.isName("Tx")) {
- field = new FormFieldText(xrefA, obj, pref);
+ field = new FormFieldText(xrefA, obj, pref, usedParents);
} else if (obj2.isName("Ch")) {
- field = new FormFieldChoice(xrefA, obj, pref);
+ field = new FormFieldChoice(xrefA, obj, pref, usedParents);
} else if (obj2.isName("Sig")) {
- field = new FormFieldSignature(xrefA, obj, pref);
+ field = new FormFieldSignature(xrefA, obj, pref, usedParents);
} else { //we don't have an FT entry => non-terminal field
- field = new FormField(xrefA, obj, pref);
+ field = new FormField(xrefA, obj, pref, usedParents);
}
obj2.free();
diff --git a/poppler/Form.h b/poppler/Form.h
index eb76fbb..106c556 100644
--- a/poppler/Form.h
+++ b/poppler/Form.h
@@ -20,6 +20,8 @@
#include "Object.h"
+#include <set>
+
class GooString;
class Array;
class Dict;
@@ -256,7 +258,7 @@ protected:
class FormField {
public:
- FormField(XRef* xrefa, Object *aobj, const Ref& aref, FormFieldType t=formUndef);
+ FormField(XRef* xrefa, Object *aobj, const Ref& aref, std::set<int> *usedParents, \
FormFieldType t=formUndef);
virtual ~FormField();
@@ -301,7 +303,7 @@ private:
class FormFieldButton: public FormField {
public:
- FormFieldButton(XRef *xrefA, Object *dict, const Ref& ref);
+ FormFieldButton(XRef *xrefA, Object *dict, const Ref& ref, std::set<int> \
*usedParents);
FormButtonType getButtonType () { return btype; }
@@ -326,7 +328,7 @@ protected:
class FormFieldText: public FormField {
public:
- FormFieldText(XRef *xrefA, Object *dict, const Ref& ref);
+ FormFieldText(XRef *xrefA, Object *dict, const Ref& ref, std::set<int> \
*usedParents);
GooString* getContent () { return content; }
GooString* getContentCopy ();
@@ -360,7 +362,7 @@ protected:
class FormFieldChoice: public FormField {
public:
- FormFieldChoice(XRef *xrefA, Object *aobj, const Ref& ref);
+ FormFieldChoice(XRef *xrefA, Object *aobj, const Ref& ref, std::set<int> \
*usedParents);
virtual ~FormFieldChoice();
@@ -423,7 +425,7 @@ protected:
class FormFieldSignature: public FormField {
public:
- FormFieldSignature(XRef *xrefA, Object *dict, const Ref& ref);
+ FormFieldSignature(XRef *xrefA, Object *dict, const Ref& ref, std::set<int> \
*usedParents);
virtual ~FormFieldSignature();
};
@@ -445,7 +447,7 @@ public:
/* Creates a new Field of the type specified in obj's dict.
used in Form::Form and FormField::FormField */
- static FormField *createFieldFromDict (Object* obj, XRef *xref, const Ref& aref);
+ static FormField *createFieldFromDict (Object* obj, XRef *xref, const Ref& aref, \
std::set<int> *usedParents);
Object *getObj () const { return acroForm; }
GBool getNeedAppearances () const { return needAppearances; }
_______________________________________________
poppler mailing list
poppler@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/poppler
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic