[poppler] 3 commits - glib/poppler-form-field.cc poppler/Annot.cc poppler/Annot.h poppler/Catalog.cc poppler/Catalog.h poppler/Form.cc poppler/Form.h poppler/Link.cc poppler/Link.h poppler/Outline.cc poppler/Outline.h poppler/Page.cc poppler/Page.h qt5/src utils/JSInfo.cc utils/JSInfo.h

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Feb 26 21:41:53 UTC 2020


 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.sander at 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 <carlosgc at gnome.org>
  * Copyright (C) 2006 Julien Rebetez
+ * Copyright (C) 2020 Oliver Sander <oliver.sander at 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, <info at kdab.com>. Work sponsored by the LiMux project of the city of Munich
 // Copyright (C) 2018 Dileep Sankhla <sankhla.dileep96 at gmail.com>
 // Copyright (C) 2018, 2019 Tobias Deiminger <haxtibal at posteo.de>
-// Copyright (C) 2018 Oliver Sander <oliver.sander at tu-dresden.de>
+// Copyright (C) 2018, 2020 Oliver Sander <oliver.sander at tu-dresden.de>
 // Copyright (C) 2018 Adam Reichold <adam.reichold at t-online.de>
 // Copyright (C) 2019 Umang Malik <umang99m at gmail.com>
 // Copyright (C) 2019 João Netto <joaonetto901 at 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 <ajohnson at redneon.com>
 // Copyright (C) 2015 Philipp Reinkemeier <philipp.reinkemeier at offis.de>
 // Copyright (C) 2018, 2019 Adam Reichold <adam.reichold at t-online.de>
+// Copyright (C) 2020 Oliver Sander <oliver.sander at 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.Freitag at alfa.de>
 // Copyright (C) 2013, 2017 Adrian Johnson <ajohnson at redneon.com>
 // Copyright (C) 2018 Adam Reichold <adam.reichold at t-online.de>
+// Copyright (C) 2020 Oliver Sander <oliver.sander at 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 <carlosgc at gnome.org>
  * Adapting code from
  *   Copyright (C) 2004 by Enrico Ros <eros.kde at email.it>
+ * Copyright (C) 2020 Oliver Sander <oliver.sander at 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 <aheinecke at intevation.de>
  * Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info at kdab.com>. Work sponsored by the LiMux project of the city of Munich
  * Copyright (C) 2018 Chinmoy Ranjan Pradhan <chinmoyrp65 at protonmail.com>
- * Copyright (C) 2018 Oliver Sander <oliver.sander at tu-dresden.de>
+ * Copyright (C) 2018, 2020 Oliver Sander <oliver.sander at tu-dresden.de>
  * Copyright (C) 2019 João Netto <joaonetto901 at gmail.com>
  * Copyright (C) 2020 David García Garzón <voki at 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 <intevation at intevation.de>
  * Copyright (C) 2018, Tobias Deiminger <haxtibal at posteo.de>
  * Copyright (C) 2018 Nelson Benítez León <nbenitezl at gmail.com>
+ * Copyright (C) 2020 Oliver Sander <oliver.sander at 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.sander at 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 <ajohnson at redneon.com>
-// Copyright (C) 2016, 2017, 2020 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2017, 2020 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info at kdab.com>. Work sponsored by the LiMux project of the city of Munich
 // Copyright (C) 2020 Oliver Sander <oliver.sander at 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 <ajohnson at redneon.com>
-// Copyright (C) 2016, 2020 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2020 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info at 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.sander at 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;
   }


More information about the poppler mailing list