glib/poppler-form-field.cc | 8 ++-- poppler/Annot.cc | 26 ++++++-------- poppler/Annot.h | 8 ++-- poppler/Catalog.cc | 7 +-- poppler/Catalog.h | 2 - poppler/Form.cc | 2 - poppler/Form.h | 2 - poppler/Link.cc | 51 ++++++++++++---------------- poppler/Link.h | 11 ++---- poppler/Outline.cc | 4 -- poppler/Outline.h | 6 ++- poppler/Page.cc | 8 ++-- poppler/Page.h | 4 +- qt5/src/poppler-annotation.cc | 5 +- qt5/src/poppler-form.cc | 10 ++--- qt5/src/poppler-page.cc | 10 ++--- utils/JSInfo.cc | 76 ++++++++++++++++++++---------------------- utils/JSInfo.h | 4 +- 18 files changed, 117 insertions(+), 127 deletions(-)
New commits: commit 58dfc767964f133f9bf18b3c5eb641c090584967 Author: Oliver Sander <oliver.san...@tu-dresden.de> Date: Tue Nov 26 17:02:56 2019 +0100 Handle LinkAction objects by std::unique_ptrs This clarifies the object ownership, and fixes various memory leaks. diff --git a/glib/poppler-form-field.cc b/glib/poppler-form-field.cc index 0507d4e8..b7d51e56 100644 --- a/glib/poppler-form-field.cc +++ b/glib/poppler-form-field.cc @@ -2,6 +2,7 @@ * * Copyright (C) 2007 Carlos Garcia Campos <carlo...@gnome.org> * Copyright (C) 2006 Julien Rebetez + * Copyright (C) 2020 Oliver Sander <oliver.san...@tu-dresden.de> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +19,8 @@ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ +#include <memory> + #include "poppler.h" #include "poppler-private.h" @@ -215,7 +218,6 @@ poppler_form_field_get_additional_action (PopplerFormField *field, PopplerAdditionalActionType type) { Annot::FormAdditionalActionsType form_action; - LinkAction *link_action; PopplerAction **action; switch (type) @@ -244,11 +246,11 @@ poppler_form_field_get_additional_action (PopplerFormField *field, if (*action) return *action; - link_action = field->widget->getAdditionalAction (form_action); + std::unique_ptr<LinkAction> link_action = field->widget->getAdditionalAction (form_action); if (!link_action) return nullptr; - *action = _poppler_action_new (nullptr, link_action, nullptr); + *action = _poppler_action_new (nullptr, link_action.get(), nullptr); return *action; } diff --git a/poppler/Annot.cc b/poppler/Annot.cc index 27111711..87f57918 100644 --- a/poppler/Annot.cc +++ b/poppler/Annot.cc @@ -208,8 +208,7 @@ static std::unique_ptr<PDFRectangle> parseDiffRectangle(Array *array, PDFRectang return nullptr; } -static LinkAction* getAdditionalAction(Annot::AdditionalActionsType type, Object *additionalActions, PDFDoc *doc) { - LinkAction *linkAction = nullptr; +static std::unique_ptr<LinkAction> getAdditionalAction(Annot::AdditionalActionsType type, Object *additionalActions, PDFDoc *doc) { Object additionalActionsObject = additionalActions->fetch(doc->getXRef()); if (additionalActionsObject.isDict()) { @@ -226,10 +225,10 @@ static LinkAction* getAdditionalAction(Annot::AdditionalActionsType type, Object Object actionObject = additionalActionsObject.dictLookup(key); if (actionObject.isDict()) - linkAction = LinkAction::parseAction(&actionObject, doc->getCatalog()->getBaseURI()); + return LinkAction::parseAction(&actionObject, doc->getCatalog()->getBaseURI()); } - return linkAction; + return nullptr; } static const char *getFormAdditionalActionKey(Annot::FormAdditionalActionsType type) @@ -2534,12 +2533,12 @@ void AnnotLink::initialize(PDFDoc *docA, Dict *dict) { // look for destination obj1 = dict->lookup("Dest"); if (!obj1.isNull()) { - action.reset(LinkAction::parseDest(&obj1)); + action = LinkAction::parseDest(&obj1); // look for action } else { obj1 = dict->lookup("A"); if (obj1.isDict()) { - action.reset(LinkAction::parseAction(&obj1, doc->getCatalog()->getBaseURI())); + action = LinkAction::parseAction(&obj1, doc->getCatalog()->getBaseURI()); } } @@ -3700,7 +3699,7 @@ void AnnotWidget::initialize(PDFDoc *docA, Dict *dict) { obj1 = dict->lookup("A"); if (obj1.isDict()) { - action.reset(LinkAction::parseAction(&obj1, doc->getCatalog()->getBaseURI())); + action = LinkAction::parseAction(&obj1, doc->getCatalog()->getBaseURI()); } additionalActions = dict->lookupNF("AA").copy(); @@ -3720,14 +3719,13 @@ void AnnotWidget::initialize(PDFDoc *docA, Dict *dict) { updatedAppearanceStream = Ref::INVALID(); } -LinkAction* AnnotWidget::getAdditionalAction(AdditionalActionsType additionalActionType) +std::unique_ptr<LinkAction> AnnotWidget::getAdditionalAction(AdditionalActionsType additionalActionType) { return ::getAdditionalAction(additionalActionType, &additionalActions, doc); } -LinkAction* AnnotWidget::getFormAdditionalAction(FormAdditionalActionsType formAdditionalActionType) +std::unique_ptr<LinkAction> AnnotWidget::getFormAdditionalAction(FormAdditionalActionsType formAdditionalActionType) { - LinkAction *linkAction = nullptr; Object additionalActionsObject = additionalActions.fetch(doc->getXRef()); if (additionalActionsObject.isDict()) { @@ -3735,10 +3733,10 @@ LinkAction* AnnotWidget::getFormAdditionalAction(FormAdditionalActionsType formA Object actionObject = additionalActionsObject.dictLookup(key); if (actionObject.isDict()) - linkAction = LinkAction::parseAction(&actionObject, doc->getCatalog()->getBaseURI()); + return LinkAction::parseAction(&actionObject, doc->getCatalog()->getBaseURI()); } - return linkAction; + return nullptr; } bool AnnotWidget::setFormAdditionalAction(FormAdditionalActionsType formAdditionalActionType, const GooString &js) @@ -5129,7 +5127,7 @@ void AnnotScreen::initialize(PDFDoc *docA, Dict* dict) { obj1 = dict->lookup("A"); if (obj1.isDict()) { - action.reset(LinkAction::parseAction(&obj1, doc->getCatalog()->getBaseURI())); + action = LinkAction::parseAction(&obj1, doc->getCatalog()->getBaseURI()); if (action && action->getKind() == actionRendition && page == 0) { error (errSyntaxError, -1, "Invalid Rendition action: associated screen annotation without P"); action = nullptr; @@ -5145,7 +5143,7 @@ void AnnotScreen::initialize(PDFDoc *docA, Dict* dict) { } } -LinkAction* AnnotScreen::getAdditionalAction(AdditionalActionsType additionalActionType) +std::unique_ptr<LinkAction> AnnotScreen::getAdditionalAction(AdditionalActionsType additionalActionType) { if (additionalActionType == actionFocusIn || additionalActionType == actionFocusOut) // not defined for screen annotation return nullptr; diff --git a/poppler/Annot.h b/poppler/Annot.h index 2f0a8290..9ded9d1f 100644 --- a/poppler/Annot.h +++ b/poppler/Annot.h @@ -29,7 +29,7 @@ // Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <i...@kdab.com>. Work sponsored by the LiMux project of the city of Munich // Copyright (C) 2018 Dileep Sankhla <sankhla.dilee...@gmail.com> // Copyright (C) 2018, 2019 Tobias Deiminger <haxti...@posteo.de> -// Copyright (C) 2018 Oliver Sander <oliver.san...@tu-dresden.de> +// Copyright (C) 2018, 2020 Oliver Sander <oliver.san...@tu-dresden.de> // Copyright (C) 2018 Adam Reichold <adam.reich...@t-online.de> // Copyright (C) 2019 Umang Malik <umang...@gmail.com> // Copyright (C) 2019 João Netto <joaonetto...@gmail.com> @@ -935,7 +935,7 @@ class AnnotScreen: public Annot { AnnotAppearanceCharacs *getAppearCharacs() { return appearCharacs.get(); } LinkAction *getAction() { return action.get(); } // The caller should not delete the result - LinkAction *getAdditionalAction(AdditionalActionsType type); // The caller should delete the result + std::unique_ptr<LinkAction> getAdditionalAction(AdditionalActionsType type); private: void initialize(PDFDoc *docA, Dict *dict); @@ -1407,8 +1407,8 @@ public: AnnotWidgetHighlightMode getMode() { return mode; } AnnotAppearanceCharacs *getAppearCharacs() { return appearCharacs.get(); } LinkAction *getAction() { return action.get(); } // The caller should not delete the result - LinkAction *getAdditionalAction(AdditionalActionsType type); // The caller should delete the result - LinkAction *getFormAdditionalAction(FormAdditionalActionsType type); // The caller should delete the result + std::unique_ptr<LinkAction> getAdditionalAction(AdditionalActionsType type); + std::unique_ptr<LinkAction> getFormAdditionalAction(FormAdditionalActionsType type); Dict *getParent() { return parent; } void setNewAppearance(Object &&newAppearance); diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index b3951efe..a4d1edf5 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -1074,8 +1074,7 @@ NameTree *Catalog::getJSNameTree() return jsNameTree; } -LinkAction* Catalog::getAdditionalAction(DocumentAdditionalActionsType type) { - LinkAction *linkAction = nullptr; +std::unique_ptr<LinkAction> Catalog::getAdditionalAction(DocumentAdditionalActionsType type) { Object additionalActionsObject = additionalActions.fetch(doc->getXRef()); if (additionalActionsObject.isDict()) { const char *key = (type == actionCloseDocument ? "WC" : @@ -1086,7 +1085,7 @@ LinkAction* Catalog::getAdditionalAction(DocumentAdditionalActionsType type) { Object actionObject = additionalActionsObject.dictLookup(key); if (actionObject.isDict()) - linkAction = LinkAction::parseAction(&actionObject, doc->getCatalog()->getBaseURI()); + return LinkAction::parseAction(&actionObject, doc->getCatalog()->getBaseURI()); } - return linkAction; + return nullptr; } diff --git a/poppler/Catalog.h b/poppler/Catalog.h index 3cde9fe1..a15dab28 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -247,7 +247,7 @@ public: actionPrintDocumentFinish, ///< Performed after printing the document }; - LinkAction *getAdditionalAction(DocumentAdditionalActionsType type); + std::unique_ptr<LinkAction> getAdditionalAction(DocumentAdditionalActionsType type); private: diff --git a/poppler/Form.cc b/poppler/Form.cc index 7af550e7..de9077dc 100644 --- a/poppler/Form.cc +++ b/poppler/Form.cc @@ -174,7 +174,7 @@ LinkAction *FormWidget::getActivationAction() { return widget ? widget->getAction() : nullptr; } -LinkAction *FormWidget::getAdditionalAction(Annot::FormAdditionalActionsType t) { +std::unique_ptr<LinkAction> FormWidget::getAdditionalAction(Annot::FormAdditionalActionsType t) { return widget ? widget->getFormAdditionalAction(t) : nullptr; } diff --git a/poppler/Form.h b/poppler/Form.h index 5473c584..38f0f51c 100644 --- a/poppler/Form.h +++ b/poppler/Form.h @@ -119,7 +119,7 @@ public: void setReadOnly(bool value); LinkAction *getActivationAction(); // The caller should not delete the result - LinkAction *getAdditionalAction(Annot::FormAdditionalActionsType type); // The caller should delete the result + std::unique_ptr<LinkAction> getAdditionalAction(Annot::FormAdditionalActionsType type); bool setAdditionalAction(Annot::FormAdditionalActionsType t, const GooString &js); // return the unique ID corresponding to pageNum/fieldNum diff --git a/poppler/Link.cc b/poppler/Link.cc index 19581e84..0bf57b3e 100644 --- a/poppler/Link.cc +++ b/poppler/Link.cc @@ -53,26 +53,22 @@ LinkAction::LinkAction() = default; LinkAction::~LinkAction() = default; -LinkAction *LinkAction::parseDest(const Object *obj) { - LinkAction *action; - - action = new LinkGoTo(obj); +std::unique_ptr<LinkAction> LinkAction::parseDest(const Object *obj) { + auto action = std::unique_ptr<LinkAction>(new LinkGoTo(obj)); if (!action->isOk()) { - delete action; - return nullptr; + action.reset(); } return action; } -LinkAction *LinkAction::parseAction(const Object *obj, const GooString *baseURI) +std::unique_ptr<LinkAction> LinkAction::parseAction(const Object *obj, const GooString *baseURI) { std::set<int> seenNextActions; return parseAction(obj, baseURI, &seenNextActions); } -LinkAction *LinkAction::parseAction(const Object *obj, const GooString *baseURI, +std::unique_ptr<LinkAction> LinkAction::parseAction(const Object *obj, const GooString *baseURI, std::set<int> *seenNextActions) { - LinkAction *action; if (!obj->isDict()) { error(errSyntaxWarning, -1, "parseAction: Bad annotation action for URI '{0:s}'", @@ -80,61 +76,62 @@ LinkAction *LinkAction::parseAction(const Object *obj, const GooString *baseURI, return nullptr; } + std::unique_ptr<LinkAction> action; Object obj2 = obj->dictLookup("S"); // GoTo action if (obj2.isName("GoTo")) { Object obj3 = obj->dictLookup("D"); - action = new LinkGoTo(&obj3); + action = std::make_unique<LinkGoTo>(&obj3); // GoToR action } else if (obj2.isName("GoToR")) { Object obj3 = obj->dictLookup("F"); Object obj4 = obj->dictLookup("D"); - action = new LinkGoToR(&obj3, &obj4); + action = std::make_unique<LinkGoToR>(&obj3, &obj4); // Launch action } else if (obj2.isName("Launch")) { - action = new LinkLaunch(obj); + action = std::make_unique<LinkLaunch>(obj); // URI action } else if (obj2.isName("URI")) { Object obj3 = obj->dictLookup("URI"); - action = new LinkURI(&obj3, baseURI); + action = std::make_unique<LinkURI>(&obj3, baseURI); // Named action } else if (obj2.isName("Named")) { Object obj3 = obj->dictLookup("N"); - action = new LinkNamed(&obj3); + action = std::make_unique<LinkNamed>(&obj3); // Movie action } else if (obj2.isName("Movie")) { - action = new LinkMovie(obj); + action = std::make_unique<LinkMovie>(obj); // Rendition action } else if (obj2.isName("Rendition")) { - action = new LinkRendition(obj); + action = std::make_unique<LinkRendition>(obj); // Sound action } else if (obj2.isName("Sound")) { - action = new LinkSound(obj); + action = std::make_unique<LinkSound>(obj); // JavaScript action } else if (obj2.isName("JavaScript")) { Object obj3 = obj->dictLookup("JS"); - action = new LinkJavaScript(&obj3); + action = std::make_unique<LinkJavaScript>(&obj3); // Set-OCG-State action } else if (obj2.isName("SetOCGState")) { - action = new LinkOCGState(obj); + action = std::make_unique<LinkOCGState>(obj); // Hide action } else if (obj2.isName("Hide")) { - action = new LinkHide(obj); + action = std::make_unique<LinkHide>(obj); // unknown action } else if (obj2.isName()) { - action = new LinkUnknown(obj2.getName()); + action = std::make_unique<LinkUnknown>(obj2.getName()); // action is missing or wrong type } else { @@ -144,7 +141,7 @@ LinkAction *LinkAction::parseAction(const Object *obj, const GooString *baseURI, } if (action && !action->isOk()) { - delete action; + action.reset(); return nullptr; } @@ -169,7 +166,7 @@ LinkAction *LinkAction::parseAction(const Object *obj, const GooString *baseURI, } actionList.reserve(1); - actionList.push_back(std::unique_ptr<LinkAction>(parseAction(&nextObj, nullptr, seenNextActions))); + actionList.push_back(parseAction(&nextObj, nullptr, seenNextActions)); } else if (nextObj.isArray()) { const Array *a = nextObj.getArray(); const int n = a->getLength(); @@ -191,7 +188,7 @@ LinkAction *LinkAction::parseAction(const Object *obj, const GooString *baseURI, } } - actionList.push_back(std::unique_ptr<LinkAction>(parseAction(&obj3, nullptr, seenNextActions))); + actionList.push_back(parseAction(&obj3, nullptr, seenNextActions)); } } diff --git a/poppler/Link.h b/poppler/Link.h index 61731e72..b996f560 100644 --- a/poppler/Link.h +++ b/poppler/Link.h @@ -79,16 +79,16 @@ public: virtual LinkActionKind getKind() const = 0; // Parse a destination (old-style action) name, string, or array. - static LinkAction *parseDest(const Object *obj); + static std::unique_ptr<LinkAction> parseDest(const Object *obj); // Parse an action dictionary. - static LinkAction *parseAction(const Object *obj, const GooString *baseURI = nullptr); + static std::unique_ptr<LinkAction> parseAction(const Object *obj, const GooString *baseURI = nullptr); // A List of the next actions to execute in order. const std::vector<std::unique_ptr<LinkAction> >& nextActions() const; private: - static LinkAction *parseAction(const Object *obj, const GooString *baseURI, std::set<int> *seenNextActions); + static std::unique_ptr<LinkAction> parseAction(const Object *obj, const GooString *baseURI, std::set<int> *seenNextActions); std::vector<std::unique_ptr<LinkAction> > nextActionList; }; diff --git a/poppler/Outline.cc b/poppler/Outline.cc index 757b25ed..8a38c1d2 100644 --- a/poppler/Outline.cc +++ b/poppler/Outline.cc @@ -66,7 +66,6 @@ OutlineItem::OutlineItem(const Dict *dict, int refNumA, OutlineItem *parentA, XR parent = parentA; xref = xrefA; title = nullptr; - action = nullptr; kids = nullptr; @@ -106,9 +105,6 @@ OutlineItem::~OutlineItem() { if (title) { gfree(title); } - if (action) { - delete action; - } } std::vector<OutlineItem*> *OutlineItem::readItemList(OutlineItem *parent, const Object *firstItemRef, XRef *xrefA) { diff --git a/poppler/Outline.h b/poppler/Outline.h index 04f2a7b2..1aa66adc 100644 --- a/poppler/Outline.h +++ b/poppler/Outline.h @@ -25,6 +25,7 @@ #ifndef OUTLINE_H #define OUTLINE_H +#include <memory> #include "Object.h" #include "CharTypes.h" @@ -69,7 +70,8 @@ public: const Unicode *getTitle() const { return title; } int getTitleLength() const { return titleLen; } - const LinkAction *getAction() const { return action; } + // OutlineItem keeps the ownership of the action + const LinkAction *getAction() const { return action.get(); } bool isOpen() const { return startsOpen; } bool hasKids() const { return firstRef.isRef(); } const std::vector<OutlineItem*> *getKids() const { return kids; } @@ -81,7 +83,7 @@ private: XRef *xref; Unicode *title; int titleLen; - LinkAction *action; + std::unique_ptr<LinkAction> action; Object firstRef; Object lastRef; Object nextRef; diff --git a/poppler/Page.cc b/poppler/Page.cc index 87621ca2..024fe3da 100644 --- a/poppler/Page.cc +++ b/poppler/Page.cc @@ -30,6 +30,7 @@ // Copyright (C) 2013, 2017 Adrian Johnson <ajohn...@redneon.com> // Copyright (C) 2015 Philipp Reinkemeier <philipp.reinkeme...@offis.de> // Copyright (C) 2018, 2019 Adam Reichold <adam.reich...@t-online.de> +// Copyright (C) 2020 Oliver Sander <oliver.san...@tu-dresden.de> // // 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 @@ -775,8 +776,7 @@ void Page::getDefaultCTM(double *ctm, double hDPI, double vDPI, delete state; } -LinkAction* Page::getAdditionalAction(PageAdditionalActionsType type) { - LinkAction *linkAction = nullptr; +std::unique_ptr<LinkAction> Page::getAdditionalAction(PageAdditionalActionsType type) { Object additionalActionsObject = actions.fetch(doc->getXRef()); if (additionalActionsObject.isDict()) { const char *key = (type == actionOpenPage ? "O" : @@ -784,8 +784,8 @@ LinkAction* Page::getAdditionalAction(PageAdditionalActionsType type) { Object actionObject = additionalActionsObject.dictLookup(key); if (actionObject.isDict()) - linkAction = LinkAction::parseAction(&actionObject, doc->getCatalog()->getBaseURI()); + return LinkAction::parseAction(&actionObject, doc->getCatalog()->getBaseURI()); } - return linkAction; + return nullptr; } diff --git a/poppler/Page.h b/poppler/Page.h index 01f056f9..3e4b341a 100644 --- a/poppler/Page.h +++ b/poppler/Page.h @@ -24,6 +24,7 @@ // Copyright (C) 2013 Thomas Freitag <thomas.frei...@alfa.de> // Copyright (C) 2013, 2017 Adrian Johnson <ajohn...@redneon.com> // Copyright (C) 2018 Adam Reichold <adam.reich...@t-online.de> +// Copyright (C) 2020 Oliver Sander <oliver.san...@tu-dresden.de> // // 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 @@ -33,6 +34,7 @@ #ifndef PAGE_H #define PAGE_H +#include <memory> #include <mutex> #include "poppler-config.h" @@ -222,7 +224,7 @@ public: actionClosePage, ///< Performed when closing the page }; - LinkAction *getAdditionalAction(PageAdditionalActionsType type); + std::unique_ptr<LinkAction> getAdditionalAction(PageAdditionalActionsType type); Gfx *createGfx(OutputDev *out, double hDPI, double vDPI, int rotate, bool useMediaBox, bool crop, diff --git a/qt5/src/poppler-annotation.cc b/qt5/src/poppler-annotation.cc index b09fc681..68b08a58 100644 --- a/qt5/src/poppler-annotation.cc +++ b/qt5/src/poppler-annotation.cc @@ -12,6 +12,7 @@ * Copyright (C) 2018 Carlos Garcia Campos <carlo...@gnome.org> * Adapting code from * Copyright (C) 2004 by Enrico Ros <eros....@email.it> + * Copyright (C) 2020 Oliver Sander <oliver.san...@tu-dresden.de> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -782,7 +783,7 @@ Link* AnnotationPrivate::additionalAction( Annotation::AdditionalActionType type const Annot::AdditionalActionsType actionType = toPopplerAdditionalActionType(type); - ::LinkAction *linkAction = nullptr; + std::unique_ptr<::LinkAction> linkAction = nullptr; if ( pdfAnnot->getType() == Annot::typeScreen ) linkAction = static_cast<AnnotScreen*>( pdfAnnot )->getAdditionalAction( actionType ); else @@ -791,7 +792,7 @@ Link* AnnotationPrivate::additionalAction( Annotation::AdditionalActionType type Link *link = nullptr; if ( linkAction ) - link = PageData::convertLinkActionToLink( linkAction, parentDoc, QRectF() ); + link = PageData::convertLinkActionToLink( linkAction.get(), parentDoc, QRectF() ); return link; } diff --git a/qt5/src/poppler-form.cc b/qt5/src/poppler-form.cc index cab25af6..58458b76 100644 --- a/qt5/src/poppler-form.cc +++ b/qt5/src/poppler-form.cc @@ -8,7 +8,7 @@ * Copyright (C) 2018, Andre Heinecke <aheine...@intevation.de> * Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <i...@kdab.com>. Work sponsored by the LiMux project of the city of Munich * Copyright (C) 2018 Chinmoy Ranjan Pradhan <chinmoyr...@protonmail.com> - * Copyright (C) 2018 Oliver Sander <oliver.san...@tu-dresden.de> + * Copyright (C) 2018, 2020 Oliver Sander <oliver.san...@tu-dresden.de> * Copyright (C) 2019 João Netto <joaonetto...@gmail.com> * Copyright (C) 2020 David García Garzón <v...@canvoki.net> * @@ -244,9 +244,9 @@ Link *FormField::additionalAction(AdditionalActionType type) const } Link* action = nullptr; - if (::LinkAction *act = m_formData->fm->getAdditionalAction(actionType)) + if (std::unique_ptr<::LinkAction> act = m_formData->fm->getAdditionalAction(actionType)) { - action = PageData::convertLinkActionToLink(act, m_formData->doc, QRectF()); + action = PageData::convertLinkActionToLink(act.get(), m_formData->doc, QRectF()); } return action; } @@ -262,9 +262,9 @@ Link *FormField::additionalAction(Annotation::AdditionalActionType type) const const Annot::AdditionalActionsType actionType = toPopplerAdditionalActionType(type); Link* action = nullptr; - if (::LinkAction *act = w->getAdditionalAction(actionType)) + if (std::unique_ptr<::LinkAction> act = w->getAdditionalAction(actionType)) { - action = PageData::convertLinkActionToLink(act, m_formData->doc, QRectF()); + action = PageData::convertLinkActionToLink(act.get(), m_formData->doc, QRectF()); } return action; } diff --git a/qt5/src/poppler-page.cc b/qt5/src/poppler-page.cc index a0862189..30e03509 100644 --- a/qt5/src/poppler-page.cc +++ b/qt5/src/poppler-page.cc @@ -23,6 +23,7 @@ * Copyright (C) 2018 Intevation GmbH <intevat...@intevation.de> * Copyright (C) 2018, Tobias Deiminger <haxti...@posteo.de> * Copyright (C) 2018 Nelson Benítez León <nbenit...@gmail.com> + * Copyright (C) 2020 Oliver Sander <oliver.san...@tu-dresden.de> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -835,12 +836,11 @@ Link *Page::action( PageAction act ) const Dict *dict = o.getDict(); const char *key = act == Page::Opening ? "O" : "C"; Object o2 = dict->lookup((char*)key); - ::LinkAction *lact = ::LinkAction::parseAction(&o2, m_page->parentDoc->doc->getCatalog()->getBaseURI() ); + std::unique_ptr<::LinkAction> lact = ::LinkAction::parseAction(&o2, m_page->parentDoc->doc->getCatalog()->getBaseURI() ); Link *popplerLink = nullptr; if (lact != nullptr) { - popplerLink = m_page->convertLinkActionToLink(lact, QRectF()); - delete lact; + popplerLink = m_page->convertLinkActionToLink(lact.get(), QRectF()); } return popplerLink; } diff --git a/utils/JSInfo.cc b/utils/JSInfo.cc index f816c117..08b47693 100644 --- a/utils/JSInfo.cc +++ b/utils/JSInfo.cc @@ -120,15 +120,15 @@ void JSInfo::scan(int nPages) { } // document actions - scanLinkAction(doc->getCatalog()->getAdditionalAction(Catalog::actionCloseDocument), + scanLinkAction(doc->getCatalog()->getAdditionalAction(Catalog::actionCloseDocument).get(), "Before Close Document"); - scanLinkAction(doc->getCatalog()->getAdditionalAction(Catalog::actionSaveDocumentStart), + scanLinkAction(doc->getCatalog()->getAdditionalAction(Catalog::actionSaveDocumentStart).get(), "Before Save Document"); - scanLinkAction(doc->getCatalog()->getAdditionalAction(Catalog::actionSaveDocumentFinish), + scanLinkAction(doc->getCatalog()->getAdditionalAction(Catalog::actionSaveDocumentFinish).get(), "After Save Document"); - scanLinkAction(doc->getCatalog()->getAdditionalAction(Catalog::actionPrintDocumentStart), + scanLinkAction(doc->getCatalog()->getAdditionalAction(Catalog::actionPrintDocumentStart).get(), "Before Print Document"); - scanLinkAction(doc->getCatalog()->getAdditionalAction(Catalog::actionPrintDocumentFinish), + scanLinkAction(doc->getCatalog()->getAdditionalAction(Catalog::actionPrintDocumentFinish).get(), "After Print Document"); // form field actions @@ -140,13 +140,13 @@ void JSInfo::scan(int nPages) { FormWidget *widget = field->getWidget(j); scanLinkAction(widget->getActivationAction(), "Field Activated"); - scanLinkAction(widget->getAdditionalAction(Annot::actionFieldModified), + scanLinkAction(widget->getAdditionalAction(Annot::actionFieldModified).get(), "Field Modified"); - scanLinkAction(widget->getAdditionalAction(Annot::actionFormatField), + scanLinkAction(widget->getAdditionalAction(Annot::actionFormatField).get(), "Format Field"); - scanLinkAction(widget->getAdditionalAction(Annot::actionValidateField), + scanLinkAction(widget->getAdditionalAction(Annot::actionValidateField).get(), "Validate Field"); - scanLinkAction(widget->getAdditionalAction(Annot::actionCalculateField), + scanLinkAction(widget->getAdditionalAction(Annot::actionCalculateField).get(), "Calculate Field"); } } @@ -168,8 +168,8 @@ void JSInfo::scan(int nPages) { if (!page) continue; // page actions (open, close) - scanLinkAction(page->getAdditionalAction(Page::actionOpenPage), "Page Open"); - scanLinkAction(page->getAdditionalAction(Page::actionClosePage), "Page Close"); + scanLinkAction(page->getAdditionalAction(Page::actionOpenPage).get(), "Page Open"); + scanLinkAction(page->getAdditionalAction(Page::actionClosePage).get(), "Page Close"); // annotation actions (links, screen, widget) annots = page->getAnnots(); @@ -181,50 +181,50 @@ void JSInfo::scan(int nPages) { AnnotScreen *annot = static_cast<AnnotScreen *>(annots->getAnnot(i)); scanLinkAction(annot->getAction(), "Screen Annotation Activated"); - scanLinkAction(annot->getAdditionalAction(Annot::actionCursorEntering), + scanLinkAction(annot->getAdditionalAction(Annot::actionCursorEntering).get(), "Screen Annotation Cursor Enter"); - scanLinkAction(annot->getAdditionalAction(Annot::actionCursorLeaving), + scanLinkAction(annot->getAdditionalAction(Annot::actionCursorLeaving).get(), "Screen Annotation Cursor Leave"); - scanLinkAction(annot->getAdditionalAction(Annot::actionMousePressed), + scanLinkAction(annot->getAdditionalAction(Annot::actionMousePressed).get(), "Screen Annotation Mouse Pressed"); - scanLinkAction(annot->getAdditionalAction(Annot::actionMouseReleased), + scanLinkAction(annot->getAdditionalAction(Annot::actionMouseReleased).get(), "Screen Annotation Mouse Released"); - scanLinkAction(annot->getAdditionalAction(Annot::actionFocusIn), + scanLinkAction(annot->getAdditionalAction(Annot::actionFocusIn).get(), "Screen Annotation Focus In"); - scanLinkAction(annot->getAdditionalAction(Annot::actionFocusOut), + scanLinkAction(annot->getAdditionalAction(Annot::actionFocusOut).get(), "Screen Annotation Focus Out"); - scanLinkAction(annot->getAdditionalAction(Annot::actionPageOpening), + scanLinkAction(annot->getAdditionalAction(Annot::actionPageOpening).get(), "Screen Annotation Page Open"); - scanLinkAction(annot->getAdditionalAction(Annot::actionPageClosing), + scanLinkAction(annot->getAdditionalAction(Annot::actionPageClosing).get(), "Screen Annotation Page Close"); - scanLinkAction(annot->getAdditionalAction(Annot::actionPageVisible), + scanLinkAction(annot->getAdditionalAction(Annot::actionPageVisible).get(), "Screen Annotation Page Visible"); - scanLinkAction(annot->getAdditionalAction(Annot::actionPageInvisible), + scanLinkAction(annot->getAdditionalAction(Annot::actionPageInvisible).get(), "Screen Annotation Page Invisible"); } else if (annots->getAnnot(i)->getType() == Annot::typeWidget) { AnnotWidget *annot = static_cast<AnnotWidget *>(annots->getAnnot(i)); scanLinkAction(annot->getAction(), "Widget Annotation Activated"); - scanLinkAction(annot->getAdditionalAction(Annot::actionCursorEntering), + scanLinkAction(annot->getAdditionalAction(Annot::actionCursorEntering).get(), "Widget Annotation Cursor Enter"); - scanLinkAction(annot->getAdditionalAction(Annot::actionCursorLeaving), + scanLinkAction(annot->getAdditionalAction(Annot::actionCursorLeaving).get(), "Widget Annotation Cursor Leave"); - scanLinkAction(annot->getAdditionalAction(Annot::actionMousePressed), + scanLinkAction(annot->getAdditionalAction(Annot::actionMousePressed).get(), "Widget Annotation Mouse Pressed"); - scanLinkAction(annot->getAdditionalAction(Annot::actionMouseReleased), + scanLinkAction(annot->getAdditionalAction(Annot::actionMouseReleased).get(), "Widget Annotation Mouse Released"); - scanLinkAction(annot->getAdditionalAction(Annot::actionFocusIn), + scanLinkAction(annot->getAdditionalAction(Annot::actionFocusIn).get(), "Widget Annotation Focus In"); - scanLinkAction(annot->getAdditionalAction(Annot::actionFocusOut), + scanLinkAction(annot->getAdditionalAction(Annot::actionFocusOut).get(), "Widget Annotation Focus Out"); - scanLinkAction(annot->getAdditionalAction(Annot::actionPageOpening), + scanLinkAction(annot->getAdditionalAction(Annot::actionPageOpening).get(), "Widget Annotation Page Open"); - scanLinkAction(annot->getAdditionalAction(Annot::actionPageClosing), + scanLinkAction(annot->getAdditionalAction(Annot::actionPageClosing).get(), "Widget Annotation Page Close"); - scanLinkAction(annot->getAdditionalAction(Annot::actionPageVisible), + scanLinkAction(annot->getAdditionalAction(Annot::actionPageVisible).get(), "Widget Annotation Page Visible"); - scanLinkAction(annot->getAdditionalAction(Annot::actionPageInvisible), + scanLinkAction(annot->getAdditionalAction(Annot::actionPageInvisible).get(), "Widget Annotation Page Invisible"); } } commit 35b7e926035c7d6852ed148b4dbe6d15e32f3fed Author: Oliver Sander <oliver.san...@tu-dresden.de> Date: Fri Nov 22 14:32:44 2019 +0100 Revert "pdfinfo: Fix another leak" This reverts commit 4d799cdf9b9039b003de7d3baf05d858bc507a5a. When closing/deallocating a document, poppler should free all memory used by that document internally. Freeing some of that memory within pdfinfo is not a proper solution when valgrind shows leaks. diff --git a/utils/JSInfo.cc b/utils/JSInfo.cc index b0869f09..f816c117 100644 --- a/utils/JSInfo.cc +++ b/utils/JSInfo.cc @@ -5,7 +5,7 @@ // This file is licensed under the GPLv2 or later // // Copyright (C) 2013 Adrian Johnson <ajohn...@redneon.com> -// Copyright (C) 2016, 2017, 2020 Albert Astals Cid <aa...@kde.org> +// Copyright (C) 2017, 2020 Albert Astals Cid <aa...@kde.org> // Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <i...@kdab.com>. Work sponsored by the LiMux project of the city of Munich // Copyright (C) 2020 Oliver Sander <oliver.san...@tu-dresden.de> // @@ -52,7 +52,7 @@ void JSInfo::printJS(const GooString *js) { gfree(u); } -void JSInfo::scanLinkAction(LinkAction *link, const char *action, bool deleteLink) { +void JSInfo::scanLinkAction(LinkAction *link, const char *action) { if (!link) return; @@ -82,8 +82,6 @@ void JSInfo::scanLinkAction(LinkAction *link, const char *action, bool deleteLin } } } - if (deleteLink) - delete link; } void JSInfo::scanJS(int nPages) { @@ -141,7 +139,7 @@ void JSInfo::scan(int nPages) { for (int j = 0; j < field->getNumWidgets(); j++) { FormWidget *widget = field->getWidget(j); scanLinkAction(widget->getActivationAction(), - "Field Activated", false); + "Field Activated"); scanLinkAction(widget->getAdditionalAction(Annot::actionFieldModified), "Field Modified"); scanLinkAction(widget->getAdditionalAction(Annot::actionFormatField), @@ -178,11 +176,11 @@ void JSInfo::scan(int nPages) { for (int i = 0; i < annots->getNumAnnots(); ++i) { if (annots->getAnnot(i)->getType() == Annot::typeLink) { AnnotLink *annot = static_cast<AnnotLink *>(annots->getAnnot(i)); - scanLinkAction(annot->getAction(), "Link Annotation Activated", false); + scanLinkAction(annot->getAction(), "Link Annotation Activated"); } else if (annots->getAnnot(i)->getType() == Annot::typeScreen) { AnnotScreen *annot = static_cast<AnnotScreen *>(annots->getAnnot(i)); scanLinkAction(annot->getAction(), - "Screen Annotation Activated", false); + "Screen Annotation Activated"); scanLinkAction(annot->getAdditionalAction(Annot::actionCursorEntering), "Screen Annotation Cursor Enter"); scanLinkAction(annot->getAdditionalAction(Annot::actionCursorLeaving), @@ -207,7 +205,7 @@ void JSInfo::scan(int nPages) { } else if (annots->getAnnot(i)->getType() == Annot::typeWidget) { AnnotWidget *annot = static_cast<AnnotWidget *>(annots->getAnnot(i)); scanLinkAction(annot->getAction(), - "Widget Annotation Activated", false); + "Widget Annotation Activated"); scanLinkAction(annot->getAdditionalAction(Annot::actionCursorEntering), "Widget Annotation Cursor Enter"); scanLinkAction(annot->getAdditionalAction(Annot::actionCursorLeaving), diff --git a/utils/JSInfo.h b/utils/JSInfo.h index 58dbd68d..646d623d 100644 --- a/utils/JSInfo.h +++ b/utils/JSInfo.h @@ -5,7 +5,7 @@ // This file is licensed under the GPLv2 or later // // Copyright (C) 2013 Adrian Johnson <ajohn...@redneon.com> -// Copyright (C) 2016, 2020 Albert Astals Cid <aa...@kde.org> +// Copyright (C) 2020 Albert Astals Cid <aa...@kde.org> // Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <i...@kdab.com>. Work sponsored by the LiMux project of the city of Munich // // To see a description of the changes please see the Changelog file that @@ -53,7 +53,7 @@ private: const UnicodeMap *uniMap; void scan(int nPages); - void scanLinkAction(LinkAction *link, const char *action, bool deleteLink = true); + void scanLinkAction(LinkAction *link, const char *action); void printJS(const GooString *js); }; commit a11fc679a701879ffd8ba6ccbd4b0a08a03440e6 Author: Oliver Sander <oliver.san...@tu-dresden.de> Date: Fri Nov 22 08:50:35 2019 +0100 Use a vector of unique_ptr for LinkAction::nextActionList This makes it clear that the vector owns the LinkAction objects. diff --git a/poppler/Link.cc b/poppler/Link.cc index 318c6b96..19581e84 100644 --- a/poppler/Link.cc +++ b/poppler/Link.cc @@ -51,11 +51,7 @@ //------------------------------------------------------------------------ LinkAction::LinkAction() = default; -LinkAction::~LinkAction() { - for (auto entry : nextActionList) { - delete entry; - } -} +LinkAction::~LinkAction() = default; LinkAction *LinkAction::parseDest(const Object *obj) { LinkAction *action; @@ -158,7 +154,7 @@ LinkAction *LinkAction::parseAction(const Object *obj, const GooString *baseURI, // parse the next actions const Object nextObj = obj->dictLookup("Next"); - std::vector<LinkAction*> actionList; + std::vector<std::unique_ptr<LinkAction> > actionList; if (nextObj.isDict()) { // Prevent circles in the tree by checking the ref against used refs in @@ -173,7 +169,7 @@ LinkAction *LinkAction::parseAction(const Object *obj, const GooString *baseURI, } actionList.reserve(1); - actionList.push_back(parseAction(&nextObj, nullptr, seenNextActions)); + actionList.push_back(std::unique_ptr<LinkAction>(parseAction(&nextObj, nullptr, seenNextActions))); } else if (nextObj.isArray()) { const Array *a = nextObj.getArray(); const int n = a->getLength(); @@ -195,7 +191,7 @@ LinkAction *LinkAction::parseAction(const Object *obj, const GooString *baseURI, } } - actionList.push_back(parseAction(&obj3, nullptr, seenNextActions)); + actionList.push_back(std::unique_ptr<LinkAction>(parseAction(&obj3, nullptr, seenNextActions))); } } @@ -204,7 +200,7 @@ LinkAction *LinkAction::parseAction(const Object *obj, const GooString *baseURI, return action; } -const std::vector<LinkAction*>& LinkAction::nextActions() const { +const std::vector<std::unique_ptr<LinkAction> >& LinkAction::nextActions() const { return nextActionList; } diff --git a/poppler/Link.h b/poppler/Link.h index 1871890f..61731e72 100644 --- a/poppler/Link.h +++ b/poppler/Link.h @@ -85,13 +85,12 @@ public: static LinkAction *parseAction(const Object *obj, const GooString *baseURI = nullptr); // A List of the next actions to execute in order. - // The list contains pointer to LinkAction objects. - const std::vector<LinkAction*>& nextActions() const; + const std::vector<std::unique_ptr<LinkAction> >& nextActions() const; private: static LinkAction *parseAction(const Object *obj, const GooString *baseURI, std::set<int> *seenNextActions); - std::vector<LinkAction*> nextActionList; + std::vector<std::unique_ptr<LinkAction> > nextActionList; }; //------------------------------------------------------------------------ diff --git a/qt5/src/poppler-page.cc b/qt5/src/poppler-page.cc index e36f6fd3..a0862189 100644 --- a/qt5/src/poppler-page.cc +++ b/qt5/src/poppler-page.cc @@ -361,9 +361,9 @@ Link* PageData::convertLinkActionToLink(::LinkAction * a, DocumentData *parentDo if ( popplerLink ) { QVector<Link *> links; - for ( ::LinkAction *nextAction : a->nextActions() ) + for ( const std::unique_ptr<::LinkAction>& nextAction : a->nextActions() ) { - links << convertLinkActionToLink( nextAction, parentDoc, linkArea ); + links << convertLinkActionToLink( nextAction.get(), parentDoc, linkArea ); } LinkPrivate::get(popplerLink)->nextLinks = links; } _______________________________________________ poppler mailing list poppler@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/poppler