Skip to content

Commit

Permalink
external/poppler: Avoid UBSan warning about undefined downcast
Browse files Browse the repository at this point in the history
...of this-ptr of in-construction FormFieldSignature while still in the base
FormField ctor, as happens (in the xpdfimport process) during
CppunitTest_xmlsecurity_signing:

> Form.cc:448:12: runtime error: downcast of address 0x60f000000040 which does not point to an object of type 'FormFieldSignature'
> 0x60f000000040: note: object is of type 'FormField'
>  03 00 00 6d  50 84 f2 00 00 00 00 00  03 00 00 00 04 00 00 00  00 00 00 00 01 be be be  07 00 00 00
>               ^~~~~~~~~~~~~~~~~~~~~~~
>               vptr for 'FormField'
>     #0 0x73d7f4 in FormWidgetSignature::FormWidgetSignature(PDFDoc*, Object*, unsigned int, Ref, FormField*) workdir/UnpackedTarball/poppler/poppler/Form.cc:448:12
>     #1 0x741713 in FormField::_createWidget(Object*, Ref) workdir/UnpackedTarball/poppler/poppler/Form.cc:677:34
>     #2 0x73e747 in FormField::FormField(PDFDoc*, Object*, Ref const&, FormField*, std::set<int, std::less<int>, std::allocator<int> >*, FormFieldType) workdir/UnpackedTarball/poppler/poppler/Form.cc:547:7
>     #3 0x74ec2b in FormFieldSignature::FormFieldSignature(PDFDoc*, Object*, Ref const&, FormField*, std::set<int, std::less<int>, std::allocator<int> >*) workdir/UnpackedTarball/poppler/poppler/Form.cc:1383:5
>     #4 0x740d7f in Form::createFieldFromDict(Object*, PDFDoc*, Ref const&, FormField*, std::set<int, std::less<int>, std::allocator<int> >*) workdir/UnpackedTarball/poppler/poppler/Form.cc:1700:19
>     #5 0x750727 in Form::Form(PDFDoc*, Object*) workdir/UnpackedTarball/poppler/poppler/Form.cc:1623:33
>     #6 0x71d440 in Catalog::getForm() workdir/UnpackedTarball/poppler/poppler/Catalog.cc:1042:18
>     #7 0x708572 in Annots::createAnnot(Dict*, Object*) workdir/UnpackedTarball/poppler/poppler/Annot.cc:7218:41
>     #8 0x70772b in Annots::Annots(PDFDoc*, int, Object*) workdir/UnpackedTarball/poppler/poppler/Annot.cc:7128:17
>     #9 0x87f3e9 in Page::getAnnots(XRef*) workdir/UnpackedTarball/poppler/poppler/Page.cc:405:18
>     #10 0x8814b0 in Page::displaySlice(OutputDev*, double, double, int, bool, bool, int, int, int, int, bool, bool (*)(void*), void*, bool (*)(Annot*, void*), void*, bool) workdir/UnpackedTarball/poppler/poppler/Page.cc:611:15
>     #11 0x880ff6 in Page::display(OutputDev*, double, double, int, bool, bool, bool, bool (*)(void*), void*, bool (*)(Annot*, void*), void*, bool) workdir/UnpackedTarball/poppler/poppler/Page.cc:521:3
>     #12 0x88d906 in PDFDoc::displayPage(OutputDev*, int, double, double, int, bool, bool, bool, bool (*)(void*), void*, bool (*)(Annot*, void*), void*, bool) workdir/UnpackedTarball/poppler/poppler/PDFDoc.cc:491:20
>     LibreOffice#13 0x5d59fb in main sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx:142:14
>     LibreOffice#14 0x7f11600ea730 in __libc_start_main (/lib64/libc.so.6+0x20730)
>     LibreOffice#15 0x459388 in _start (instdir/program/xpdfimport+0x459388)

Change-Id: Ia808919c8d2363d616feb4664f314a77b40dfbb8
  • Loading branch information
stbergmann committed Oct 14, 2016
1 parent d550f5e commit 55013a7
Showing 1 changed file with 218 additions and 0 deletions.
218 changes: 218 additions & 0 deletions external/poppler/ubsan.patch.0
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,224 @@
memcpy(s1, s, length);
}
if (s != sStatic)
--- poppler/Form.cc
+++ poppler/Form.cc
@@ -463,12 +463,11 @@
// FormField
//========================================================================

-FormField::FormField(PDFDoc *docA, Object *aobj, const Ref& aref, FormField *parentA, std::set<int> *usedParents, FormFieldType ty)
+FormField::FormField(PDFDoc *docA, Object *aobj, const Ref& aref, FormField *parentA, FormFieldType ty)
{
doc = docA;
xref = doc->getXRef();
aobj->copy(&obj);
- Dict* dict = obj.getDict();
ref.num = ref.gen = 0;
type = ty;
parent = parentA;
@@ -483,7 +482,11 @@
hasQuadding = gFalse;

ref = aref;
+}

+void FormField::init(std::set<int> *usedParents)
+{
+ Dict* dict = obj.getDict();
Object obj1;
//childs
if (dict->lookup("Kids", &obj1)->isArray()) {
@@ -803,9 +806,15 @@
//------------------------------------------------------------------------
// FormFieldButton
//------------------------------------------------------------------------
-FormFieldButton::FormFieldButton(PDFDoc *docA, Object *aobj, const Ref& ref, FormField *parent, std::set<int> *usedParents)
- : FormField(docA, aobj, ref, parent, usedParents, formButton)
+FormFieldButton::FormFieldButton(PDFDoc *docA, Object *aobj, const Ref& ref, FormField *parent)
+ : FormField(docA, aobj, ref, parent, formButton)
{
+}
+
+void FormFieldButton::init(std::set<int> *usedParents)
+{
+ FormField::init(usedParents);
+
Dict* dict = obj.getDict();
active_child = -1;
noAllOff = false;
@@ -983,9 +992,15 @@
//------------------------------------------------------------------------
// FormFieldText
//------------------------------------------------------------------------
-FormFieldText::FormFieldText(PDFDoc *docA, Object *aobj, const Ref& ref, FormField *parent, std::set<int> *usedParents)
- : FormField(docA, aobj, ref, parent, usedParents, formText)
+FormFieldText::FormFieldText(PDFDoc *docA, Object *aobj, const Ref& ref, FormField *parent)
+ : FormField(docA, aobj, ref, parent, formText)
{
+}
+
+void FormFieldText::init(std::set<int> *usedParents)
+{
+ FormField::init(usedParents);
+
Dict* dict = obj.getDict();
Object obj1;
content = NULL;
@@ -1076,9 +1091,15 @@
//------------------------------------------------------------------------
// FormFieldChoice
//------------------------------------------------------------------------
-FormFieldChoice::FormFieldChoice(PDFDoc *docA, Object *aobj, const Ref& ref, FormField *parent, std::set<int> *usedParents)
- : FormField(docA, aobj, ref, parent, usedParents, formChoice)
+FormFieldChoice::FormFieldChoice(PDFDoc *docA, Object *aobj, const Ref& ref, FormField *parent)
+ : FormField(docA, aobj, ref, parent, formChoice)
{
+}
+
+void FormFieldChoice::init(std::set<int> *usedParents)
+{
+ FormField::init(usedParents);
+
numChoices = 0;
choices = NULL;
editedChoice = NULL;
@@ -1379,9 +1400,15 @@
//------------------------------------------------------------------------
// FormFieldSignature
//------------------------------------------------------------------------
-FormFieldSignature::FormFieldSignature(PDFDoc *docA, Object *dict, const Ref& ref, FormField *parent, std::set<int> *usedParents)
- : FormField(docA, dict, ref, parent, usedParents, formSignature)
+FormFieldSignature::FormFieldSignature(PDFDoc *docA, Object *dict, const Ref& ref, FormField *parent)
+ : FormField(docA, dict, ref, parent, formSignature)
{
+}
+
+void FormFieldSignature::init(std::set<int> *usedParents)
+{
+ FormField::init(usedParents);
+
signature = NULL;

signature_info = new SignatureInfo();
@@ -1691,15 +1718,15 @@
FormField *field;

if (Form::fieldLookup(obj->getDict (), "FT", &obj2)->isName("Btn")) {
- field = new FormFieldButton(docA, obj, pref, parent, usedParents);
+ field = FormFieldButton::create(docA, obj, pref, parent, usedParents);
} else if (obj2.isName("Tx")) {
- field = new FormFieldText(docA, obj, pref, parent, usedParents);
+ field = FormFieldText::create(docA, obj, pref, parent, usedParents);
} else if (obj2.isName("Ch")) {
- field = new FormFieldChoice(docA, obj, pref, parent, usedParents);
+ field = FormFieldChoice::create(docA, obj, pref, parent, usedParents);
} else if (obj2.isName("Sig")) {
- field = new FormFieldSignature(docA, obj, pref, parent, usedParents);
+ field = FormFieldSignature::create(docA, obj, pref, parent, usedParents);
} else { //we don't have an FT entry => non-terminal field
- field = new FormField(docA, obj, pref, parent, usedParents);
+ field = FormField::create(docA, obj, pref, parent, usedParents);
}
obj2.free();

--- poppler/Form.h
+++ poppler/Form.h
@@ -264,8 +264,16 @@
//------------------------------------------------------------------------

class FormField {
-public:
- FormField(PDFDoc *docA, Object *aobj, const Ref& aref, FormField *parent, std::set<int> *usedParents, FormFieldType t=formUndef);
+protected:
+ FormField(PDFDoc *docA, Object *aobj, const Ref& aref, FormField *parent, FormFieldType t);
+ void init(std::set<int> *usedParents);
+public:
+ static FormField *create(PDFDoc *docA, Object *aobj, const Ref& aref, FormField *parent, std::set<int> *usedParents, FormFieldType t=formUndef)
+ {
+ FormField *f = new FormField(docA, aobj, aref, parent, t);
+ f->init(usedParents);
+ return f;
+ }

virtual ~FormField();

@@ -338,8 +346,16 @@
//------------------------------------------------------------------------

class FormFieldButton: public FormField {
-public:
- FormFieldButton(PDFDoc *docA, Object *dict, const Ref& ref, FormField *parent, std::set<int> *usedParents);
+private:
+ FormFieldButton(PDFDoc *docA, Object *dict, const Ref& ref, FormField *parent);
+ void init(std::set<int> *usedParents);
+public:
+ static FormFieldButton *create(PDFDoc *docA, Object *dict, const Ref& ref, FormField *parent, std::set<int> *usedParents)
+ {
+ FormFieldButton *f = new FormFieldButton(docA, dict, ref, parent);
+ f->init(usedParents);
+ return f;
+ }

FormButtonType getButtonType () { return btype; }

@@ -384,8 +400,16 @@
//------------------------------------------------------------------------

class FormFieldText: public FormField {
-public:
- FormFieldText(PDFDoc *docA, Object *dict, const Ref& ref, FormField *parent, std::set<int> *usedParents);
+private:
+ FormFieldText(PDFDoc *docA, Object *dict, const Ref& ref, FormField *parent);
+ void init(std::set<int> *usedParents);
+public:
+ static FormFieldText *create(PDFDoc *docA, Object *dict, const Ref& ref, FormField *parent, std::set<int> *usedParents)
+ {
+ FormFieldText *f = new FormFieldText(docA, dict, ref, parent);
+ f->init(usedParents);
+ return f;
+ }

GooString* getContent () { return content; }
GooString* getContentCopy ();
@@ -422,8 +446,16 @@
//------------------------------------------------------------------------

class FormFieldChoice: public FormField {
-public:
- FormFieldChoice(PDFDoc *docA, Object *aobj, const Ref& ref, FormField *parent, std::set<int> *usedParents);
+private:
+ FormFieldChoice(PDFDoc *docA, Object *aobj, const Ref& ref, FormField *parent);
+ void init(std::set<int> *usedParents);
+public:
+ static FormFieldChoice *create(PDFDoc *docA, Object *aobj, const Ref& ref, FormField *parent, std::set<int> *usedParents)
+ {
+ FormFieldChoice *f = new FormFieldChoice(docA, aobj, ref, parent);
+ f->init(usedParents);
+ return f;
+ }

virtual ~FormFieldChoice();

@@ -491,8 +523,16 @@
//------------------------------------------------------------------------

class FormFieldSignature: public FormField {
-public:
- FormFieldSignature(PDFDoc *docA, Object *dict, const Ref& ref, FormField *parent, std::set<int> *usedParents);
+private:
+ FormFieldSignature(PDFDoc *docA, Object *dict, const Ref& ref, FormField *parent);
+ void init(std::set<int> *usedParents);
+public:
+ static FormFieldSignature *create(PDFDoc *docA, Object *dict, const Ref& ref, FormField *parent, std::set<int> *usedParents)
+ {
+ FormFieldSignature *f = new FormFieldSignature(docA, dict, ref, parent);
+ f->init(usedParents);
+ return f;
+ }

SignatureInfo *validateSignature(bool doVerifyCert, bool forceRevalidation);

--- poppler/Stream.cc
+++ poppler/Stream.cc
@@ -2966,12 +2966,12 @@
Expand Down

0 comments on commit 55013a7

Please sign in to comment.