[poppler] 7 commits - CMakeLists.txt cpp/CMakeLists.txt poppler/GfxState.cc poppler/Link.cc poppler/Link.h qt5/src

Albert Astals Cid aacid at kemper.freedesktop.org
Mon Apr 16 16:10:19 UTC 2018


 CMakeLists.txt                 |    7 ++
 cpp/CMakeLists.txt             |    1 
 poppler/GfxState.cc            |    5 +
 poppler/Link.cc                |  103 ++++++++++++++++++++++++++++++++++++++++-
 poppler/Link.h                 |   54 ++++++++++++++++++++-
 qt5/src/poppler-annotation.cc  |    6 ++
 qt5/src/poppler-link-private.h |   26 ++++++++++
 qt5/src/poppler-link.cc        |   35 +++++++++++++
 qt5/src/poppler-link.h         |   50 +++++++++++++++++++
 qt5/src/poppler-page.cc        |   25 +++++++++
 10 files changed, 303 insertions(+), 9 deletions(-)

New commits:
commit 88c99f1f6f4faf31faabccd35d9d094958020ebc
Author: Albert Astals Cid <aacid at kde.org>
Date:   Mon Apr 16 17:59:35 2018 +0200

    Fix crash on malformed documents
    
    In GfxGouraudTriangleShading::parse
    
    Bug #106061

diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 95699355..5d7cc6ba 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -4916,7 +4916,7 @@ GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(GfxResources *res, i
     }
   }
   delete bitBuf;
-  if (typeA == 5 && nVerticesA > 0) {
+  if (typeA == 5 && nVerticesA > 0 && vertsPerRow > 0) {
     nRows = nVerticesA / vertsPerRow;
     nTrianglesA = (nRows - 1) * 2 * (vertsPerRow - 1);
     trianglesA = (int (*)[3])gmallocn_checkoverflow(nTrianglesA * 3, sizeof(int));
commit df8a4ee51e18a39f85568c4122e5edd8c03d61df
Author: Albert Astals Cid <aacid at kde.org>
Date:   Mon Apr 16 17:46:10 2018 +0200

    Make it so we copy seenNextActions a bit less

diff --git a/poppler/Link.cc b/poppler/Link.cc
index 2f853125..42bdaf1b 100644
--- a/poppler/Link.cc
+++ b/poppler/Link.cc
@@ -71,7 +71,7 @@ LinkAction *LinkAction::parseDest(const Object *obj) {
 }
 
 LinkAction *LinkAction::parseAction(const Object *obj, const GooString *baseURI,
-                                    const std::set<int> *seenNextActions) {
+                                    std::unique_ptr<std::set<int>> seenNextActions) {
   LinkAction *action;
 
   if (!obj->isDict()) {
@@ -160,18 +160,19 @@ LinkAction *LinkAction::parseAction(const Object *obj, const GooString *baseURI,
     // Prevent circles in the tree by checking the ref against used refs in
     // our current tree branch.
     const Object nextRefObj = obj->dictLookupNF("Next");
-    std::set<int> seenNextActionsAux = seenNextActions ? *seenNextActions : std::set<int> ();
+    if (!seenNextActions)
+        seenNextActions.reset(new std::set<int>);
     if (nextRefObj.isRef()) {
         const Ref ref = nextRefObj.getRef();
-        if (seenNextActionsAux.find(ref.num) != seenNextActionsAux.end()) {
+        if (seenNextActions->find(ref.num) != seenNextActions->end()) {
             error(errSyntaxWarning, -1, "parseAction: Circular next actions detected.");
             return action;
         }
-        seenNextActionsAux.insert(ref.num);
+        seenNextActions->insert(ref.num);
     }
 
     actionList = new GooList(1);
-    actionList->append(parseAction(&nextObj, nullptr, &seenNextActionsAux));
+    actionList->append(parseAction(&nextObj, nullptr, std::move(seenNextActions)));
   } else if (nextObj.isArray()) {
     const Array *a = nextObj.getArray();
     const int n = a->getLength();
@@ -184,18 +185,19 @@ LinkAction *LinkAction::parseAction(const Object *obj, const GooString *baseURI,
       }
 
       // Similar circle check as above.
-      std::set<int> seenNextActionsAux = seenNextActions ? *seenNextActions : std::set<int> ();
+      if (!seenNextActions)
+        seenNextActions.reset(new std::set<int>);
       const Object obj3Ref = a->getNF(i);
       if (obj3Ref.isRef()) {
           const Ref ref = obj3Ref.getRef();
-          if (seenNextActionsAux.find(ref.num) != seenNextActionsAux.end()) {
+          if (seenNextActions->find(ref.num) != seenNextActions->end()) {
               error(errSyntaxWarning, -1, "parseAction: Circular next actions detected in array.");
               return action;
           }
-          seenNextActionsAux.insert(ref.num);
+          seenNextActions->insert(ref.num);
       }
 
-      actionList->append(parseAction(&obj3, nullptr, &seenNextActionsAux));
+      actionList->append(parseAction(&obj3, nullptr, std::move(seenNextActions)));
     }
   }
 
diff --git a/poppler/Link.h b/poppler/Link.h
index 806e30f6..77d224d9 100644
--- a/poppler/Link.h
+++ b/poppler/Link.h
@@ -34,6 +34,7 @@
 #endif
 
 #include "Object.h"
+#include <memory>
 #include <set>
 
 class GooString;
@@ -85,7 +86,7 @@ public:
 
   // Parse an action dictionary.
   static LinkAction *parseAction(const Object *obj, const GooString *baseURI = nullptr,
-                                 const std::set<int> *seenNextActions = nullptr);
+                                 std::unique_ptr<std::set<int>> seenNextActions = nullptr);
 
   // A List of the next actions to execute in order.
   // The list contains pointer to LinkAction objects.
commit bd9fb431941916174e1c3b2201bf5f422bcf61bd
Author: Aleix Pol <aleixpol at kde.org>
Date:   Mon Apr 16 16:38:09 2018 +0200

    Make it possible to build poppler on Android without fontconfig
    
    Didn't manage to make fontconfig build, still nice to have poppler
    available.

diff --git a/CMakeLists.txt b/CMakeLists.txt
index efa6c3f4..e2ebc44d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -89,10 +89,13 @@ endif()
 
 if(WIN32)
   set(_default_fontconfiguration "win32")
+elseif(ANDROID)
+  # on android we don't have fontconfig and we don't want window-specific code
+  set(_default_fontconfiguration "generic")
 else()
   set(_default_fontconfiguration "fontconfig")
 endif()
-set(FONT_CONFIGURATION "${_default_fontconfiguration}" CACHE STRING "The font configuration backend (win32|fontconfig).")
+set(FONT_CONFIGURATION "${_default_fontconfiguration}" CACHE STRING "The font configuration backend (win32|generic|fontconfig).")
 string(TOLOWER "${FONT_CONFIGURATION}" font_configuration)
 set(WITH_FONTCONFIGURATION_WIN32 OFF)
 set(WITH_FONTCONFIGURATION_FONTCONFIG OFF)
@@ -100,6 +103,8 @@ if(font_configuration STREQUAL "win32")
   set(WITH_FONTCONFIGURATION_WIN32 ON)
 elseif(font_configuration STREQUAL "fontconfig")
   set(WITH_FONTCONFIGURATION_FONTCONFIG ON)
+elseif(font_configuration STREQUAL "generic")
+  message(STATUS "no fontconfig or win32 specific code")
 else()
   message(FATAL_ERROR "Invalid font configuration setting: ${FONT_CONFIGURATION}")
 endif()
commit 34a44e5b95230b1ed03bb030e9963d0187b01951
Author: Aleix Pol <aleixpol at kde.org>
Date:   Mon Apr 16 16:35:47 2018 +0200

    Do not assume that iconv is in /usr/include
    
    We find it explicitly because it may be elsewhere.

diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index ea252088..a08ee263 100644
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -1,6 +1,7 @@
 include_directories(
   ${CMAKE_CURRENT_SOURCE_DIR}
   ${CMAKE_CURRENT_BINARY_DIR}
+  ${ICONV_INCLUDE_DIR}
 )
 
 configure_file(poppler-version.h.in ${CMAKE_CURRENT_BINARY_DIR}/poppler-version.h @ONLY)
commit bdd8db389c7b09cd9042267f36214f809e4c5f60
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Apr 16 17:13:05 2018 +0200

    Add support for Next actions following an action
    
    Next actions are action dictionaries or an array
    of action dictonaries. "Next" is an entry in the
    general action dictionary.
    
    These actions are supposed to be performed after each other.
    So that a single button press can for example
    both trigger a Hide action and a JavaScript action.

diff --git a/poppler/Link.cc b/poppler/Link.cc
index a748d69e..2f853125 100644
--- a/poppler/Link.cc
+++ b/poppler/Link.cc
@@ -52,6 +52,12 @@
 //------------------------------------------------------------------------
 // LinkAction
 //------------------------------------------------------------------------
+LinkAction::LinkAction() : nextActionList(nullptr) {
+}
+
+LinkAction::~LinkAction() {
+  delete nextActionList;
+}
 
 LinkAction *LinkAction::parseDest(const Object *obj) {
   LinkAction *action;
@@ -64,7 +70,8 @@ LinkAction *LinkAction::parseDest(const Object *obj) {
   return action;
 }
 
-LinkAction *LinkAction::parseAction(const Object *obj, const GooString *baseURI) {
+LinkAction *LinkAction::parseAction(const Object *obj, const GooString *baseURI,
+                                    const std::set<int> *seenNextActions) {
   LinkAction *action;
 
   if (!obj->isDict()) {
@@ -140,9 +147,72 @@ LinkAction *LinkAction::parseAction(const Object *obj, const GooString *baseURI)
     delete action;
     return nullptr;
   }
+
+  if (!action) {
+    return nullptr;
+  }
+
+  // parse the next actions
+  const Object nextObj = obj->dictLookup("Next");
+  GooList *actionList = nullptr;
+  if (nextObj.isDict()) {
+
+    // Prevent circles in the tree by checking the ref against used refs in
+    // our current tree branch.
+    const Object nextRefObj = obj->dictLookupNF("Next");
+    std::set<int> seenNextActionsAux = seenNextActions ? *seenNextActions : std::set<int> ();
+    if (nextRefObj.isRef()) {
+        const Ref ref = nextRefObj.getRef();
+        if (seenNextActionsAux.find(ref.num) != seenNextActionsAux.end()) {
+            error(errSyntaxWarning, -1, "parseAction: Circular next actions detected.");
+            return action;
+        }
+        seenNextActionsAux.insert(ref.num);
+    }
+
+    actionList = new GooList(1);
+    actionList->append(parseAction(&nextObj, nullptr, &seenNextActionsAux));
+  } else if (nextObj.isArray()) {
+    const Array *a = nextObj.getArray();
+    const int n = a->getLength();
+    actionList = new GooList(n);
+    for (int i = 0; i < n; ++i) {
+      const Object obj3 = a->get(i);
+      if (!obj3.isDict()) {
+        error(errSyntaxWarning, -1, "parseAction: Next array does not contain only dicts");
+        continue;
+      }
+
+      // Similar circle check as above.
+      std::set<int> seenNextActionsAux = seenNextActions ? *seenNextActions : std::set<int> ();
+      const Object obj3Ref = a->getNF(i);
+      if (obj3Ref.isRef()) {
+          const Ref ref = obj3Ref.getRef();
+          if (seenNextActionsAux.find(ref.num) != seenNextActionsAux.end()) {
+              error(errSyntaxWarning, -1, "parseAction: Circular next actions detected in array.");
+              return action;
+          }
+          seenNextActionsAux.insert(ref.num);
+      }
+
+      actionList->append(parseAction(&obj3, nullptr, &seenNextActionsAux));
+    }
+  }
+
+  action->setNextActions(actionList);
+
   return action;
 }
 
+const GooList *LinkAction::nextActions() const {
+  return nextActionList;
+}
+
+void LinkAction::setNextActions(GooList *actions) {
+  delete nextActionList;
+  nextActionList = actions;
+}
+
 //------------------------------------------------------------------------
 // LinkDest
 //------------------------------------------------------------------------
diff --git a/poppler/Link.h b/poppler/Link.h
index 229a8431..806e30f6 100644
--- a/poppler/Link.h
+++ b/poppler/Link.h
@@ -34,6 +34,7 @@
 #endif
 
 #include "Object.h"
+#include <set>
 
 class GooString;
 class GooList;
@@ -66,12 +67,12 @@ enum LinkActionKind {
 class LinkAction {
 public:
 
-  LinkAction() = default;
+  LinkAction();
   LinkAction(const LinkAction &) = delete;
   LinkAction& operator=(const LinkAction &other) = delete;
 
   // Destructor.
-  virtual ~LinkAction() {}
+  virtual ~LinkAction();
 
   // Was the LinkAction created successfully?
   virtual GBool isOk() const = 0;
@@ -83,7 +84,18 @@ public:
   static LinkAction *parseDest(const Object *obj);
 
   // Parse an action dictionary.
-  static LinkAction *parseAction(const Object *obj, const GooString *baseURI = NULL);
+  static LinkAction *parseAction(const Object *obj, const GooString *baseURI = nullptr,
+                                 const std::set<int> *seenNextActions = nullptr);
+
+  // A List of the next actions to execute in order.
+  // The list contains pointer to LinkAction objects.
+  const GooList *nextActions() const;
+
+  // Sets the next action list. Takes ownership of the actions.
+  void setNextActions(GooList *actions);
+
+private:
+  GooList *nextActionList;
 };
 
 //------------------------------------------------------------------------
diff --git a/qt5/src/poppler-link-private.h b/qt5/src/poppler-link-private.h
index e54c8f86..766f1899 100644
--- a/qt5/src/poppler-link-private.h
+++ b/qt5/src/poppler-link-private.h
@@ -24,6 +24,8 @@ class LinkOCGState;
 
 namespace Poppler {
 
+class Link;
+
 class LinkPrivate
 {
 public:
@@ -34,12 +36,19 @@ public:
 
     virtual ~LinkPrivate()
     {
+        qDeleteAll(nextLinks);
+    }
+
+    static LinkPrivate *get( Link *link )
+    {
+        return link->d_ptr;
     }
 
     LinkPrivate(const LinkPrivate &) = delete;
     LinkPrivate& operator=(const LinkPrivate &) = delete;
 
     QRectF linkArea;
+    QVector <Link *> nextLinks;
 };
 
 
diff --git a/qt5/src/poppler-link.cc b/qt5/src/poppler-link.cc
index 1279e0b2..1086afce 100644
--- a/qt5/src/poppler-link.cc
+++ b/qt5/src/poppler-link.cc
@@ -427,7 +427,12 @@ class LinkMoviePrivate : public LinkPrivate
 		Q_D( const Link );
 		return d->linkArea;
 	}
-	
+
+	QVector< Link * > Link::nextLinks() const
+	{
+		return d_ptr->nextLinks;
+	}
+
 	// LinkGoto
 	LinkGoto::LinkGoto( const QRectF &linkArea, QString extFileName, const LinkDestination & destination )
 		: Link( *new LinkGotoPrivate( linkArea, destination ) )
diff --git a/qt5/src/poppler-link.h b/qt5/src/poppler-link.h
index 5a59b6f3..0ce4c0d1 100644
--- a/qt5/src/poppler-link.h
+++ b/qt5/src/poppler-link.h
@@ -29,6 +29,7 @@
 #include <QtCore/QString>
 #include <QtCore/QRectF>
 #include <QtCore/QSharedDataPointer>
+#include <QtCore/QVector>
 #include "poppler-export.h"
 
 struct Ref;
@@ -177,6 +178,7 @@ class POPPLER_QT5_EXPORT LinkDestination
 class POPPLER_QT5_EXPORT Link
 {
 	friend class OptContentModel;
+	friend class LinkPrivate;
 
 	public:
 		/// \cond PRIVATE
@@ -220,7 +222,14 @@ class POPPLER_QT5_EXPORT Link
 		 * a general action. The area is given in 0..1 range
 		 */
 		QRectF linkArea() const;
-		
+
+		/**
+		 * Get the next links to be activiated / executed after this link.
+		 *
+		 * \since 0.64
+		 */
+		QVector<Link *> nextLinks() const;
+
 	protected:
 		/// \cond PRIVATE
 		Link( LinkPrivate &dd );
diff --git a/qt5/src/poppler-page.cc b/qt5/src/poppler-page.cc
index 3ed98846..b48ee959 100644
--- a/qt5/src/poppler-page.cc
+++ b/qt5/src/poppler-page.cc
@@ -358,6 +358,20 @@ Link* PageData::convertLinkActionToLink(::LinkAction * a, DocumentData *parentDo
     break;
   }
 
+  if ( popplerLink )
+  {
+    const GooList *nextActions = a->nextActions();
+    if ( nextActions )
+    {
+      QVector<Link *> links;
+      for ( int i = 0; i < nextActions->getLength(); ++i )
+      {
+        links << convertLinkActionToLink( static_cast< ::LinkAction * >( nextActions->get( i ) ), parentDoc, linkArea );
+      }
+      LinkPrivate::get(popplerLink)->nextLinks = links;
+    }
+  }
+
   return popplerLink;
 }
 
commit ab72205dd14efe9c5c8d12e6b1ae538208bce168
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Apr 16 16:31:38 2018 +0200

    Add support for hide action
    
    The hide action can be used to show / hide fields.

diff --git a/poppler/Link.cc b/poppler/Link.cc
index 9be6a8c1..a748d69e 100644
--- a/poppler/Link.cc
+++ b/poppler/Link.cc
@@ -21,6 +21,7 @@
 // Copyright (C) 2009 Ilya Gorenbein <igorenbein at finjan.com>
 // Copyright (C) 2012 Tobias Koening <tobias.koenig at kdab.com>
 // 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 Intevation GmbH <intevation at intevation.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
@@ -120,6 +121,10 @@ LinkAction *LinkAction::parseAction(const Object *obj, const GooString *baseURI)
   } else if (obj2.isName("SetOCGState")) {
     action = new LinkOCGState(obj);
 
+  // Hide action
+  } else if (obj2.isName("Hide")) {
+    action = new LinkHide(obj);
+
   // unknown action
   } else if (obj2.isName()) {
     action = new LinkUnknown(obj2.getName());
@@ -811,6 +816,30 @@ LinkOCGState::StateList::~StateList() {
 }
 
 //------------------------------------------------------------------------
+// LinkHide
+//------------------------------------------------------------------------
+
+LinkHide::LinkHide(const Object *hideObj) {
+  targetName = nullptr;
+  show = false; // Default
+
+  if (hideObj->isDict()) {
+      const Object targetObj = hideObj->dictLookup("T");
+      if (targetObj.isString()) {
+	targetName = targetObj.getString()->copy();
+      }
+      const Object shouldHide = hideObj->dictLookup("H");
+      if (shouldHide.isBool()) {
+	show = !shouldHide.getBool();
+      }
+  }
+}
+
+LinkHide::~LinkHide() {
+  delete targetName;
+}
+
+//------------------------------------------------------------------------
 // LinkUnknown
 //------------------------------------------------------------------------
 
diff --git a/poppler/Link.h b/poppler/Link.h
index 90496c42..229a8431 100644
--- a/poppler/Link.h
+++ b/poppler/Link.h
@@ -19,6 +19,7 @@
 // Copyright (C) 2012 Tobias Koening <tobias.koenig at kdab.com>
 // Copyright (C) 2018 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) 2018 Intevation GmbH <intevation at intevation.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
@@ -58,6 +59,7 @@ enum LinkActionKind {
   actionSound,			// sound action
   actionJavaScript,		// JavaScript action
   actionOCGState,               // Set-OCG-State action
+  actionHide,			// Hide action
   actionUnknown			// anything else
 };
 
@@ -452,6 +454,39 @@ private:
 };
 
 //------------------------------------------------------------------------
+// LinkHide
+//------------------------------------------------------------------------
+
+class LinkHide: public LinkAction {
+public:
+  LinkHide(const Object *hideObj);
+
+  ~LinkHide();
+
+  GBool isOk() const override { return targetName != nullptr; }
+  LinkActionKind getKind() const override { return actionHide; }
+
+  // According to spec the target can be either:
+  // a) A text string containing the fully qualified name of the target
+  //    field.
+  // b) An indirect reference to an annotation dictionary.
+  // c) An array of "such dictionaries or text strings".
+  //
+  // While b / c appear to be very uncommon and can't easily be
+  // created with Adobe Acrobat DC. So only support hide
+  // actions with named targets (yet).
+  GBool hasTargetName() const { return targetName != nullptr; }
+  const GooString *getTargetName() const { return targetName; }
+
+  // Should this action show or hide.
+  GBool isShowAction() const { return show; }
+
+private:
+  GooString *targetName;
+  GBool show;
+};
+
+//------------------------------------------------------------------------
 // LinkUnknown
 //------------------------------------------------------------------------
 
diff --git a/qt5/src/poppler-annotation.cc b/qt5/src/poppler-annotation.cc
index 6a2ec893..2394ffc5 100644
--- a/qt5/src/poppler-annotation.cc
+++ b/qt5/src/poppler-annotation.cc
@@ -6,6 +6,7 @@
  * Copyright (C) 2012, 2015, Tobias Koenig <tobias.koenig at kdab.com>
  * Copyright (C) 2018 Adam Reichold <adam.reichold at t-online.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 Intevation GmbH <intevation at intevation.de>
  * Adapting code from
  *   Copyright (C) 2004 by Enrico Ros <eros.kde at email.it>
  *
@@ -3946,6 +3947,11 @@ void LinkAnnotation::store( QDomNode & node, QDomDocument & document ) const
                 hyperlinkElement.setAttribute( QStringLiteral("type"), QStringLiteral("OCGState") );
                 break;
             }
+            case Poppler::Link::Hide:
+            {
+                hyperlinkElement.setAttribute( QStringLiteral("type"), QStringLiteral("Hide") );
+                break;
+            }
             case Poppler::Link::None:
                 break;
         }
diff --git a/qt5/src/poppler-link-private.h b/qt5/src/poppler-link-private.h
index 6bc5cb9f..e54c8f86 100644
--- a/qt5/src/poppler-link-private.h
+++ b/qt5/src/poppler-link-private.h
@@ -1,5 +1,6 @@
 /* poppler-link-private.h: qt interface to poppler
  * Copyright (C) 2016, 2018, Albert Astals Cid <aacid at kde.org>
+ * Copyright (C) 2018 Intevation GmbH <intevation at intevation.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
@@ -55,6 +56,22 @@ public:
     ::LinkOCGState *popplerLinkOCGState;
 };
 
+
+
+class LinkHidePrivate : public LinkPrivate
+{
+public:
+    LinkHidePrivate( const QRectF &area, const QString &tName, bool show )
+        : LinkPrivate( area )
+        , targetName( tName )
+        , isShow( show )
+    {
+    }
+
+    QString targetName;
+    bool isShow;
+};
+
 }
 
 #endif
diff --git a/qt5/src/poppler-link.cc b/qt5/src/poppler-link.cc
index ffa3e74d..1279e0b2 100644
--- a/qt5/src/poppler-link.cc
+++ b/qt5/src/poppler-link.cc
@@ -4,6 +4,7 @@
  * Copyright (C) 2010 Hib Eris <hib at hiberis.nl>
  * Copyright (C) 2012, Tobias Koenig <tokoe at kdab.com>
  * Copyright (C) 2012, Guillermo A. Amaral B. <gamaral at kde.org>
+ * Copyright (C) 2018 Intevation GmbH <intevation at intevation.de>
  * Adapting code from
  *   Copyright (C) 2004 by Enrico Ros <eros.kde at email.it>
  *
@@ -704,4 +705,31 @@ class LinkMoviePrivate : public LinkPrivate
 	{
 		return OCGState;
 	}
+
+	// LinkHide
+	LinkHide::LinkHide( LinkHidePrivate *lhidep )
+		: Link( *lhidep )
+	{
+	}
+
+	LinkHide::~LinkHide()
+	{
+	}
+
+	Link::LinkType LinkHide::linkType() const
+	{
+		return Hide;
+	}
+
+	QVector < QString > LinkHide::targets() const
+	{
+		Q_D( const LinkHide );
+		return QVector< QString >() << d->targetName;
+	}
+
+	bool LinkHide::isShowAction() const
+	{
+		Q_D( const LinkHide );
+		return d->isShow;
+	}
 }
diff --git a/qt5/src/poppler-link.h b/qt5/src/poppler-link.h
index 0753ce99..5a59b6f3 100644
--- a/qt5/src/poppler-link.h
+++ b/qt5/src/poppler-link.h
@@ -4,6 +4,7 @@
  * Copyright (C) 2010, 2012, Guillermo Amaral <gamaral at kdab.com>
  * Copyright (C) 2012, Tobias Koenig <tokoe at kdab.com>
  * Copyright (C) 2013, Anthony Granger <grangeranthony at gmail.com>
+ * Copyright (C) 2018 Intevation GmbH <intevation at intevation.de>
  * Adapting code from
  *   Copyright (C) 2004 by Enrico Ros <eros.kde at email.it>
  *
@@ -49,6 +50,7 @@ class LinkDestinationData;
 class LinkDestinationPrivate;
 class LinkRenditionPrivate;
 class LinkOCGStatePrivate;
+class LinkHidePrivate;
 class MediaRendition;
 class SoundObject;
 
@@ -197,7 +199,8 @@ class POPPLER_QT5_EXPORT Link
 		    Movie,    ///< An action to be executed on a movie
 		    Rendition,    ///< A rendition link \since 0.20
 		    JavaScript,   ///< A JavaScript code to be interpreted \since 0.10
-		    OCGState      ///< An Optional Content Group state change \since 0.50
+		    OCGState,      ///< An Optional Content Group state change \since 0.50
+		    Hide,     ///< An action to hide a field \since 0.64
 		};
 
 		/**
@@ -627,6 +630,40 @@ class POPPLER_QT5_EXPORT LinkOCGState : public Link
 		Q_DISABLE_COPY( LinkOCGState )
 };
 
+/**
+ * Hide: an action to show / hide a field.
+ *
+ * \since 0.64
+ */
+class POPPLER_QT5_EXPORT LinkHide: public Link
+{
+	public:
+		/**
+		 * Create a new Hide link. This is only used by Poppler::Page.
+		 */
+		LinkHide( LinkHidePrivate *lhidep );
+		/**
+		 * Destructor.
+		 */
+		~LinkHide();
+
+		LinkType linkType() const override;
+
+		/**
+		 * The fully qualified target names of the action.
+		 */
+		QVector< QString > targets() const;
+
+		/**
+		 * Should this action change the visibility of the target to true.
+		 */
+		bool isShowAction() const;
+
+	private:
+		Q_DECLARE_PRIVATE( LinkHide )
+		Q_DISABLE_COPY( LinkHide )
+};
+
 }
 
 #endif
diff --git a/qt5/src/poppler-page.cc b/qt5/src/poppler-page.cc
index 48dbe8ff..3ed98846 100644
--- a/qt5/src/poppler-page.cc
+++ b/qt5/src/poppler-page.cc
@@ -20,6 +20,7 @@
  * Copyright (C) 2017, 2018, Oliver Sander <oliver.sander at tu-dresden.de>
  * Copyright (C) 2017 Adrian Johnson <ajohnson at redneon.com>
  * Copyright (C) 2017, 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 Intevation GmbH <intevation at intevation.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
@@ -342,6 +343,16 @@ Link* PageData::convertLinkActionToLink(::LinkAction * a, DocumentData *parentDo
       LinkOCGStatePrivate *locgp = new LinkOCGStatePrivate( linkArea, plocg );
       popplerLink = new LinkOCGState( locgp );
     }
+    break;
+
+    case actionHide:
+    {
+      ::LinkHide *lh = (::LinkHide *)a;
+
+      LinkHidePrivate *lhp = new LinkHidePrivate( linkArea, lh->hasTargetName() ? UnicodeParsedString( lh->getTargetName() ) : QString(), lh->isShowAction() );
+      popplerLink = new LinkHide( lhp );
+    }
+    break;
 
     case actionUnknown:
     break;
commit 022ccd4e1c61f4e89c7ffad83d9a5a896f65dc40
Author: Albert Astals Cid <aacid at kde.org>
Date:   Mon Apr 16 16:22:55 2018 +0200

    GfxGouraudTriangleShading::parse: Fix memory leak on malformed files
    
    Bug #106059

diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 3d564138..95699355 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -4922,6 +4922,9 @@ GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(GfxResources *res, i
     trianglesA = (int (*)[3])gmallocn_checkoverflow(nTrianglesA * 3, sizeof(int));
     if (unlikely(!trianglesA)) {
       gfree(verticesA);
+      for (i = 0; i < nFuncsA; ++i) {
+	delete funcsA[i];
+      }
       return nullptr;
     }
     k = 0;


More information about the poppler mailing list