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

Albert Astals Cid aacid at kde.org
Mon Apr 16 18:22:49 UTC 2018


El dilluns, 16 d’abril de 2018, a les 19:05:25 CEST, Adam Reichold va 
escriure:
> Hello,
> 
> concerning df8a4ee51e18a39f85568c4122e5edd8c03d61df, I think there is a
> problem in the "isArray" branch where a moved-from value
> "seenNextActions" is used if the array contains more than one dict. I
> think this is generally undefined behavior (even though it is probably
> fine in this case since a moved-from std::unique_ptr is probably just
> empty, but the only guarantee is that it can be destructed safely).
> 
> But I also think that it is not how the function is supposed to work
> since every call to parseActions should start we the same prefix of
> already-seen actions, hence needs to start with the same value of
> seenNextActions modifying its private copy if actual branching takes
> place, so that the copies probably cannot be elided in that part of the
> function.

You're right, good catch!

> Also if this is about performance, I think this could be a bit lazier by
> initializing the set the first when it will really be used, it could use
> std::unordered_set since we only check membership and a single lookup
> should suffice since it returns whether insertion actually took place.
> 
> But also since an empty instance of std::set does not allocate any
> nodes, wouldn't it be even simpler to just pass that set by value moving
> the set and not the pointer to it where that is possible? (It is
> basically the size of two pointers instead of one, but also looses one
> indirection.)

But your patch does exactly what i want to avoid, you're copying the set in

auto seenNextActionsAux = seenNextActions;

This other patch I'm attaching should fix the problem too with less copying, 
right?

Cheers,
  Albert


> 
> Best regards,
> Adam
> 
> Am 16.04.2018 um 18:10 schrieb Albert Astals Cid:
> >  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;
> > 
> > _______________________________________________
> > poppler mailing list
> > poppler at lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/poppler

-------------- next part --------------
A non-text attachment was scrubbed...
Name: unique_to_shared.patch
Type: text/x-patch
Size: 1817 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/poppler/attachments/20180416/ddf47af8/attachment-0001.bin>


More information about the poppler mailing list