[poppler] Branch 'better_object' - 25 commits - CMakeLists.txt configure.ac cpp/Doxyfile fofi/FoFiType1.cc goo/GooHash.cc NEWS poppler/FlateStream.h poppler/Function.cc poppler/GfxFont.cc poppler/GfxState.cc poppler/JBIG2Stream.cc poppler/JPXStream.h poppler/PDFDoc.cc poppler/PDFDoc.h poppler/Stream.cc poppler/Stream.h poppler/StructTreeRoot.cc qt4/src qt5/src utils/HtmlFonts.cc utils/HtmlOutputDev.cc utils/ImageOutputDev.cc

Albert Astals Cid aacid at kemper.freedesktop.org
Mon Jul 31 14:40:10 UTC 2017


 CMakeLists.txt            |    4 +-
 NEWS                      |    8 +++++
 configure.ac              |    2 -
 cpp/Doxyfile              |    2 -
 fofi/FoFiType1.cc         |   40 ++++++++++++++++++++++---
 goo/GooHash.cc            |   18 +++++++++++
 poppler/FlateStream.h     |   16 +++++-----
 poppler/Function.cc       |    8 +++--
 poppler/GfxFont.cc        |    2 -
 poppler/GfxState.cc       |   13 +++++++-
 poppler/JBIG2Stream.cc    |   12 ++++++-
 poppler/JPXStream.h       |   16 +++++-----
 poppler/PDFDoc.cc         |   71 ++++++++++++++++++++++++++++++++++------------
 poppler/PDFDoc.h          |   19 +++++-------
 poppler/Stream.cc         |    9 +++++
 poppler/Stream.h          |   16 +++++-----
 poppler/StructTreeRoot.cc |    8 ++---
 qt4/src/Doxyfile          |    2 -
 qt5/src/Doxyfile          |    2 -
 utils/HtmlFonts.cc        |    6 +++
 utils/HtmlOutputDev.cc    |    6 ++-
 utils/ImageOutputDev.cc   |    6 ++-
 22 files changed, 208 insertions(+), 78 deletions(-)

New commits:
commit 66e718e753a527289ce86cd206fcffd23fc28d81
Merge: 9cecd78f 213ae24b
Author: Albert Astals Cid <aacid at kde.org>
Date:   Mon Jul 31 16:39:53 2017 +0200

    Merge remote-tracking branch 'origin/master' into better_object

diff --cc poppler/PDFDoc.cc
index 206b7e42,ec5c7002..35b3bc01
--- a/poppler/PDFDoc.cc
+++ b/poppler/PDFDoc.cc
@@@ -1074,18 -1127,37 +1074,36 @@@ void PDFDoc::saveCompleteRewrite (OutSt
  }
  
  void PDFDoc::writeDictionnary (Dict* dict, OutStream* outStr, XRef *xRef, Guint numOffset, Guchar *fileKey,
-                                CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen)
+                                CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen, std::set<Dict*> *alreadyWrittenDicts)
  {
+   bool deleteSet = false;
+   if (!alreadyWrittenDicts) {
+     alreadyWrittenDicts = new std::set<Dict*>;
+     deleteSet = true;
+   }
+ 
+   if (alreadyWrittenDicts->find(dict) != alreadyWrittenDicts->end()) {
+     error(errSyntaxWarning, -1, "PDFDoc::writeDictionnary: Found recursive dicts");
+     if (deleteSet) delete alreadyWrittenDicts;
+     return;
+   } else {
+     alreadyWrittenDicts->insert(dict);
+   }
+ 
 -  Object obj1;
    outStr->printf("<<");
    for (int i=0; i<dict->getLength(); i++) {
      GooString keyName(dict->getKey(i));
      GooString *keyNameToPrint = keyName.sanitizedName(gFalse /* non ps mode */);
      outStr->printf("/%s ", keyNameToPrint->getCString());
      delete keyNameToPrint;
 -    writeObject(dict->getValNF(i, &obj1), outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen, alreadyWrittenDicts);
 -    obj1.free();
 +    Object obj1 = dict->getValNF(i);
-     writeObject(&obj1, outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen);
++    writeObject(&obj1, outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen, alreadyWrittenDicts);
    }
    outStr->printf(">> ");
+ 
+   if (deleteSet) {
+     delete alreadyWrittenDicts;
+   }
  }
  
  void PDFDoc::writeStream (Stream* str, OutStream* outStr)
@@@ -1189,9 -1264,11 +1207,9 @@@ Goffset PDFDoc::writeObjectHeader (Ref 
  }
  
  void PDFDoc::writeObject (Object* obj, OutStream* outStr, XRef *xRef, Guint numOffset, Guchar *fileKey,
-                           CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen)
+                           CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen, std::set<Dict*> *alreadyWrittenDicts)
  {
    Array *array;
 -  Object obj1;
 -  Goffset tmp;
  
    switch (obj->getType()) {
      case objBool:
@@@ -1291,9 -1374,10 +1309,9 @@@
            }
            stream->getDict()->remove("DecodeParms");
  
-           writeDictionnary (stream->getDict(),outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen);
+           writeDictionnary (stream->getDict(),outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen, alreadyWrittenDicts);
            writeStream (stream,outStr);
            delete encStream;
 -          obj1.free();
          } else {
            //raw stream copy
            FilterStream *fs = dynamic_cast<FilterStream*>(stream);
@@@ -1426,7 -1527,7 +1444,7 @@@ void PDFDoc::writeXRefTableTrailer(Obje
  {
    uxref->writeTableToFile( outStr, writeAllEntries );
    outStr->printf( "trailer\r\n");
-   writeDictionnary(trailerDict.getDict(), outStr, xRef, 0, NULL, cryptRC4, 0, 0, 0);
 -  writeDictionnary(trailerDict, outStr, xRef, 0, NULL, cryptRC4, 0, 0, 0, nullptr);
++  writeDictionnary(trailerDict.getDict(), outStr, xRef, 0, NULL, cryptRC4, 0, 0, 0, nullptr);
    outStr->printf( "\r\nstartxref\r\n");
    outStr->printf( "%lli\r\n", uxrefOffset);
    outStr->printf( "%%%%EOF\r\n");
@@@ -1482,20 -1601,27 +1515,24 @@@ void PDFDoc::markDictionnary (Dict* dic
    for (int i=0; i<dict->getLength(); i++) {
      const char *key = dict->getKey(i);
      if (strcmp(key, "Annots") != 0) {
 -      markObject(dict->getValNF(i, &obj1), xRef, countRef, numOffset, oldRefNum, newRefNum, alreadyMarkedDicts);
 +      Object obj1 = dict->getValNF(i);
-       markObject(&obj1, xRef, countRef, numOffset, oldRefNum, newRefNum);
++      markObject(&obj1, xRef, countRef, numOffset, oldRefNum, newRefNum, alreadyMarkedDicts);
      } else {
 -      Object annotsObj;
 -      dict->getValNF(i, &annotsObj);
 +      Object annotsObj = dict->getValNF(i);
        if (!annotsObj.isNull()) {
-         markAnnotations(&annotsObj, xRef, countRef, 0, oldRefNum, newRefNum);
+         markAnnotations(&annotsObj, xRef, countRef, 0, oldRefNum, newRefNum, alreadyMarkedDicts);
 -        annotsObj.free();
        }
      }
 -    obj1.free();
    }
+ 
+   if (deleteSet) {
+     delete alreadyMarkedDicts;
+   }
  }
  
- void PDFDoc::markObject (Object* obj, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum)
+ void PDFDoc::markObject (Object* obj, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum, std::set<Dict*> *alreadyMarkedDicts)
  {
    Array *array;
 -  Object obj1;
  
    switch (obj->getType()) {
      case objArray:
@@@ -1558,30 -1687,51 +1595,30 @@@ void PDFDoc::replacePageDict(int pageNo
    pageDict->remove("BleedBox");
    pageDict->remove("TrimBox");
    pageDict->remove("Rotate");
 -  Object mediaBoxObj;
 -  mediaBoxObj.initArray(getXRef());
 -  Object murx;
 -  murx.initReal(mediaBox->x1);
 -  Object mury;
 -  mury.initReal(mediaBox->y1);
 -  Object mllx;
 -  mllx.initReal(mediaBox->x2);
 -  Object mlly;
 -  mlly.initReal(mediaBox->y2);
 -  mediaBoxObj.arrayAdd(&murx);
 -  mediaBoxObj.arrayAdd(&mury);
 -  mediaBoxObj.arrayAdd(&mllx);
 -  mediaBoxObj.arrayAdd(&mlly);
 -  pageDict->add(copyString("MediaBox"), &mediaBoxObj);
 +  Array *mediaBoxArray = new Array(getXRef());
 +  mediaBoxArray->add(Object(mediaBox->x1));
 +  mediaBoxArray->add(Object(mediaBox->y1));
 +  mediaBoxArray->add(Object(mediaBox->x2));
 +  mediaBoxArray->add(Object(mediaBox->y2));
 +  Object mediaBoxObject(mediaBoxArray);
 +  Object trimBoxObject = mediaBoxObject.copy();
 +  pageDict->add(copyString("MediaBox"), std::move(mediaBoxObject));
    if (cropBox != NULL) {
 -    Object cropBoxObj;
 -    cropBoxObj.initArray(getXRef());
 -    Object curx;
 -    curx.initReal(cropBox->x1);
 -    Object cury;
 -    cury.initReal(cropBox->y1);
 -    Object cllx;
 -    cllx.initReal(cropBox->x2);
 -    Object clly;
 -    clly.initReal(cropBox->y2);
 -    cropBoxObj.arrayAdd(&curx);
 -    cropBoxObj.arrayAdd(&cury);
 -    cropBoxObj.arrayAdd(&cllx);
 -    cropBoxObj.arrayAdd(&clly);
 -    pageDict->add(copyString("CropBox"), &cropBoxObj);
 -    cropBoxObj.getArray()->incRef();
 -    pageDict->add(copyString("TrimBox"), &cropBoxObj);
 -  } else {
 -    mediaBoxObj.getArray()->incRef();
 -    pageDict->add(copyString("TrimBox"), &mediaBoxObj);
 -  }
 -  Object rotateObj;
 -  rotateObj.initInt(rotate);
 -  pageDict->add(copyString("Rotate"), &rotateObj);
 +    Array *cropBoxArray = new Array(getXRef());
 +    cropBoxArray->add(Object(cropBox->x1));
 +    cropBoxArray->add(Object(cropBox->y1));
 +    cropBoxArray->add(Object(cropBox->x2));
 +    cropBoxArray->add(Object(cropBox->y2));
 +    Object cropBoxObject(cropBoxArray);
 +    trimBoxObject = cropBoxObject.copy();
 +    pageDict->add(copyString("CropBox"), std::move(cropBoxObject));
 +  }
 +  pageDict->add(copyString("TrimBox"), std::move(trimBoxObject));
 +  pageDict->add(copyString("Rotate"), Object(rotate));
    getXRef()->setModifiedObject(&page, *refPage);
 -  page.free();
  }
  
- void PDFDoc::markPageObjects(Dict *pageDict, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum) 
+ void PDFDoc::markPageObjects(Dict *pageDict, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum, std::set<Dict*> *alreadyMarkedDicts)
  {
    pageDict->remove("OpenAction");
    pageDict->remove("Outlines");
@@@ -1596,14 -1746,16 +1633,14 @@@
  	      strcmp(key, "Annots") != 0 &&
  	      strcmp(key, "P") != 0 &&
          strcmp(key, "Root") != 0) {
-       markObject(&value, xRef, countRef, numOffset, oldRefNum, newRefNum);
+       markObject(&value, xRef, countRef, numOffset, oldRefNum, newRefNum, alreadyMarkedDicts);
      }
 -    value.free();
    }
  }
  
- GBool PDFDoc::markAnnotations(Object *annotsObj, XRef *xRef, XRef *countRef, Guint numOffset, int oldPageNum, int newPageNum) {
+ GBool PDFDoc::markAnnotations(Object *annotsObj, XRef *xRef, XRef *countRef, Guint numOffset, int oldPageNum, int newPageNum, std::set<Dict*> *alreadyMarkedDicts) {
 -  Object annots;
    GBool modified = gFalse;
 -  annotsObj->fetch(getXRef(), &annots);
 +  Object annots = annotsObj->fetch(getXRef());
    if (annots.isArray()) {
        Array *array = annots.getArray();
        for (int i=array->getLength() - 1; i >= 0; i--) {
@@@ -1636,10 -1808,13 +1673,10 @@@
                  continue;
                }
              }
 -            obj2.free();
            }
-           markPageObjects(dict, xRef, countRef, numOffset, oldPageNum, newPageNum);
 -          type.free();
+           markPageObjects(dict, xRef, countRef, numOffset, oldPageNum, newPageNum, alreadyMarkedDicts);
          }
 -        obj1.free();
 -        array->getNF(i, &obj1);
 +        obj1 = array->getNF(i);
          if (obj1.isRef()) {
            if (obj1.getRef().num + (int) numOffset >= xRef->getNumObjects() || xRef->getEntry(obj1.getRef().num + numOffset)->type == xrefEntryFree) {
              if (getXRef()->getEntry(obj1.getRef().num)->type == xrefEntryFree) {
diff --cc poppler/PDFDoc.h
index 6a83c7c5,c5621ec2..83a2e97e
--- a/poppler/PDFDoc.h
+++ b/poppler/PDFDoc.h
@@@ -298,14 -298,15 +298,14 @@@ public
    // write all objects used by pageDict to outStr
    Guint writePageObjects(OutStream *outStr, XRef *xRef, Guint numOffset, GBool combine = gFalse);
    static void writeObject (Object *obj, OutStream* outStr, XRef *xref, Guint numOffset, Guchar *fileKey,
-                            CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen);
+                            CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen, std::set<Dict*> *alreadyWrittenDicts = nullptr);
    static void writeHeader(OutStream *outStr, int major, int minor);
  
 -  // Ownership goes to the caller
 -  static Dict *createTrailerDict (int uxrefSize, GBool incrUpdate, Goffset startxRef,
 +  static Object createTrailerDict (int uxrefSize, GBool incrUpdate, Goffset startxRef,
                                    Ref *root, XRef *xRef, const char *fileName, Goffset fileSize);
 -  static void writeXRefTableTrailer (Dict *trailerDict, XRef *uxref, GBool writeAllEntries,
 +  static void writeXRefTableTrailer (Object &&trailerDict, XRef *uxref, GBool writeAllEntries,
                                       Goffset uxrefOffset, OutStream* outStr, XRef *xRef);
 -  static void writeXRefStreamTrailer (Dict *trailerDict, XRef *uxref, Ref *uxrefStreamRef,
 +  static void writeXRefStreamTrailer (Object &&trailerDict, XRef *uxref, Ref *uxrefStreamRef,
                                        Goffset uxrefOffset, OutStream* outStr, XRef *xRef);
  
  private:
diff --cc poppler/Stream.h
index 9c53ea39,f3cf38b1..2317080e
--- a/poppler/Stream.h
+++ b/poppler/Stream.h
@@@ -866,17 -868,17 +866,17 @@@ struct DCTHuffTable 
  class DCTStream: public FilterStream {
  public:
  
 -  DCTStream(Stream *strA, int colorXformA, Object *dict, int recursion);
 +  DCTStream(Stream *strA, int colorXformA, Dict *dict, int recursion);
    virtual ~DCTStream();
-   virtual StreamKind getKind() { return strDCT; }
-   virtual void reset();
-   virtual void close();
-   virtual int getChar();
-   virtual int lookChar();
-   virtual GooString *getPSFilter(int psLevel, const char *indent);
-   virtual GBool isBinary(GBool last = gTrue);
+   StreamKind getKind() override { return strDCT; }
+   void reset() override;
+   void close() override;
+   int getChar() override;
+   int lookChar() override;
+   GooString *getPSFilter(int psLevel, const char *indent) override;
+   GBool isBinary(GBool last = gTrue) override;
  
-   virtual void unfilteredReset();
+   void unfilteredReset() override;
  
  private:
  
diff --cc poppler/StructTreeRoot.cc
index 937df608,29beeecc..5af530e9
--- a/poppler/StructTreeRoot.cc
+++ b/poppler/StructTreeRoot.cc
@@@ -59,37 -60,39 +59,37 @@@ void StructTreeRoot::parse(Dict *root
          parentTree.resize(nums.arrayGetLength() / 2);
          // Index numbers in even positions, references in odd ones
          for (int i = 0; i < nums.arrayGetLength(); i += 2) {
 -          Object index, value;
 +          Object index = nums.arrayGet(i);
  
 -          if (!nums.arrayGet(i, &index)->isInt()) {
 +          if (!index.isInt()) {
              error(errSyntaxError, -1, "Nums item at position {0:d} is wrong type ({1:s})", i, index.getTypeName());
 -            index.free();
              continue;
            }
-           if (index.getInt() < 0) {
-             error(errSyntaxError, -1, "Nums item at position {0:d} is invalid value ({1:d})", i, index.getInt());
+           const unsigned idx = index.getInt();
+           if (idx < 0 || idx >= parentTree.size()) {
+             error(errSyntaxError, -1, "Nums item at position {0:d} is invalid value ({1:d}): [0..{2:d}]", i, idx, parentTree.size() - 1);
 -            index.free();
              continue;
            }
  
-           const unsigned idx = index.getInt();
- 	  Object value = nums.arrayGetNF(i + 1);
 -          if (nums.arrayGetNF(i + 1, &value)->isRef()) {
++          Object value = nums.arrayGetNF(i + 1);
 +          if (value.isRef()) {
              parentTree[idx].resize(1);
              parentTree[idx][0].ref = value.getRef();
 -          } else if (nums.arrayGet(i + 1, &value)->isArray()) {
 -            parentTree[idx].resize(value.arrayGetLength());
 -            for (int j = 0; j < value.arrayGetLength(); j++) {
 -              Object itemvalue;
 -              if (value.arrayGetNF(j, &itemvalue)->isRef())
 -                parentTree[idx][j].ref = itemvalue.getRef();
 -              else
 -                error(errSyntaxError, -1, "Nums array item at position {0:d}/{1:d} is invalid type ({2:s})", i, j, itemvalue.getTypeName());
 -              itemvalue.free();
 -            }
            } else {
 -            error(errSyntaxError, -1, "Nums item at position {0:d} is wrong type ({1:s})", i + 1, value.getTypeName());
 -          }
 -
 -          value.free();
 -          index.free();
 +	    value = nums.arrayGet(i + 1);
 +	    if (value.isArray()) {
 +	      parentTree[idx].resize(value.arrayGetLength());
 +	      for (int j = 0; j < value.arrayGetLength(); j++) {
 +		Object itemvalue = value.arrayGetNF(j);
 +		if (itemvalue.isRef())
 +		  parentTree[idx][j].ref = itemvalue.getRef();
 +		else
 +		  error(errSyntaxError, -1, "Nums array item at position {0:d}/{1:d} is invalid type ({2:s})", i, j, itemvalue.getTypeName());
 +	      }
 +	    } else {
 +	      error(errSyntaxError, -1, "Nums item at position {0:d} is wrong type ({1:s})", i + 1, value.getTypeName());
 +	    }
 +	  }
          }
        } else {
          error(errSyntaxError, -1, "Nums array length is not a even ({0:d})", nums.arrayGetLength());
commit 213ae24b4df97f557e771060e37197d0e57f6f7f
Author: Jannick <thirdedition at gmx.net>
Date:   Sun Jul 16 19:51:49 2017 +0200

    added override tag to function declarations

diff --git a/poppler/FlateStream.h b/poppler/FlateStream.h
index 9e3835f0..6a88a234 100644
--- a/poppler/FlateStream.h
+++ b/poppler/FlateStream.h
@@ -46,14 +46,14 @@ public:
 
   FlateStream(Stream *strA, int predictor, int columns, int colors, int bits);
   virtual ~FlateStream();
-  virtual StreamKind getKind() { return strFlate; }
-  virtual void reset();
-  virtual int getChar();
-  virtual int lookChar();
-  virtual int getRawChar();
-  virtual void getRawChars(int nChars, int *buffer);
-  virtual GooString *getPSFilter(int psLevel, const char *indent);
-  virtual GBool isBinary(GBool last = gTrue);
+  virtual StreamKind getKind() override { return strFlate; }
+  virtual void reset() override;
+  virtual int getChar() override;
+  virtual int lookChar() override;
+  virtual int getRawChar() override;
+  virtual void getRawChars(int nChars, int *buffer) override;
+  virtual GooString *getPSFilter(int psLevel, const char *indent) override;
+  virtual GBool isBinary(GBool last = gTrue) override;
 
 private:
   inline int doGetRawChar() {
diff --git a/poppler/JPXStream.h b/poppler/JPXStream.h
index 30855431..8926ffe5 100644
--- a/poppler/JPXStream.h
+++ b/poppler/JPXStream.h
@@ -262,15 +262,15 @@ public:
 
   JPXStream(Stream *strA);
   virtual ~JPXStream();
-  virtual StreamKind getKind() { return strJPX; }
-  virtual void reset();
-  virtual void close();
-  virtual int getChar();
-  virtual int lookChar();
-  virtual GooString *getPSFilter(int psLevel, const char *indent);
-  virtual GBool isBinary(GBool last = gTrue);
+  virtual StreamKind getKind() override { return strJPX; }
+  virtual void reset() override;
+  virtual void close() override;
+  virtual int getChar() override;
+  virtual int lookChar() override;
+  virtual GooString *getPSFilter(int psLevel, const char *indent) override;
+  virtual GBool isBinary(GBool last = gTrue) override;
   virtual void getImageParams(int *bitsPerComponent,
-			      StreamColorSpaceMode *csMode);
+			      StreamColorSpaceMode *csMode) override;
 
 private:
 
diff --git a/poppler/Stream.h b/poppler/Stream.h
index 91b524fe..f3cf38b1 100644
--- a/poppler/Stream.h
+++ b/poppler/Stream.h
@@ -870,15 +870,15 @@ public:
 
   DCTStream(Stream *strA, int colorXformA, Object *dict, int recursion);
   virtual ~DCTStream();
-  virtual StreamKind getKind() { return strDCT; }
-  virtual void reset();
-  virtual void close();
-  virtual int getChar();
-  virtual int lookChar();
-  virtual GooString *getPSFilter(int psLevel, const char *indent);
-  virtual GBool isBinary(GBool last = gTrue);
+  StreamKind getKind() override { return strDCT; }
+  void reset() override;
+  void close() override;
+  int getChar() override;
+  int lookChar() override;
+  GooString *getPSFilter(int psLevel, const char *indent) override;
+  GBool isBinary(GBool last = gTrue) override;
 
-  virtual void unfilteredReset();
+  void unfilteredReset() override;
 
 private:
 
commit ab371fe60568947e355d89e28d489f7f9a1a7404
Author: Jason Crain <jason at inspiresomeone.us>
Date:   Sun Jul 16 12:07:54 2017 -0500

    pdftohtml: skip control characters
    
    W3C disallows them and they cause a warning in PHP.
    
    https://bugs.freedesktop.org/show_bug.cgi?id=101770

diff --git a/utils/HtmlFonts.cc b/utils/HtmlFonts.cc
index 49376d65..ad1fd934 100644
--- a/utils/HtmlFonts.cc
+++ b/utils/HtmlFonts.cc
@@ -26,6 +26,7 @@
 // Copyright (C) 2012 Igor Slepchin <igor.slepchin at gmail.com>
 // Copyright (C) 2012 Luis Parravicini <lparravi at gmail.com>
 // Copyright (C) 2013 Julien Nabet <serval2412 at yahoo.fr>
+// Copyright (C) 2017 Jason Crain <jason at inspiresomeone.us>
 //
 // 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
@@ -252,6 +253,11 @@ GooString* HtmlFont::HtmlFilter(Unicode* u, int uLen) {
   }
 
   for (int i = 0; i < uLen; ++i) {
+    // skip control characters.  W3C disallows them and they cause a warning
+    // with PHP.
+    if (u[i] <= 31)
+      continue;
+
     switch (u[i])
       { 
 	case '"': tmp->append(""");  break;
commit 0f4ea2f18b1953ccc88bcbd6b16ede828b44e561
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Mon Jul 10 21:06:30 2017 +0930

    Fix parsing of Type 1 fonts with newlines in encoding sequences
    
    Adobe Type 1 font spec states that the encoding sequences should be of
    the form:
    
      dup index /name put
    
    The bug 101728 test case has the encoding sequences in the form:
    
      dup
      index /name put
    
    Make the Type 1 parse handle encoding sequences split over more than one line.
    
    Bug 101728

diff --git a/fofi/FoFiType1.cc b/fofi/FoFiType1.cc
index 151f2d5f..8974cc99 100644
--- a/fofi/FoFiType1.cc
+++ b/fofi/FoFiType1.cc
@@ -17,6 +17,7 @@
 // Copyright (C) 2005 Kristian Høgsberg <krh at redhat.com>
 // Copyright (C) 2010 Jakub Wilk <jwilk at jwilk.net>
 // Copyright (C) 2014 Carlos Garcia Campos <carlosgc at gnome.org>
+// Copyright (C) 2017 Adrian Johnson <ajohnson at redneon.com>
 //
 // 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
@@ -209,12 +210,12 @@ char *FoFiType1::getNextLine(char *line) {
 }
 
 void FoFiType1::parse() {
-  char *line, *line1, *p, *p2;
+  char *line, *line1, *firstLine, *p, *p2;
   char buf[256];
   char c;
   int n, code, base, i, j;
   char *tokptr;
-  GBool gotMatrix;
+  GBool gotMatrix, continueLine;
 
   gotMatrix = gFalse;
   for (i = 1, line = (char *)file;
@@ -241,6 +242,7 @@ void FoFiType1::parse() {
       for (j = 0; j < 256; ++j) {
 	encoding[j] = NULL;
       }
+      continueLine = gFalse;
       for (j = 0, line = getNextLine(line);
 	   j < 300 && line && (line1 = getNextLine(line));
 	   ++j, line = line1) {
@@ -248,8 +250,26 @@ void FoFiType1::parse() {
 	  error(errSyntaxWarning, -1, "FoFiType1::parse a line has more than 255 characters, we don't support this");
 	  n = 255;
 	}
-	strncpy(buf, line, n);
-	buf[n] = '\0';
+	if (continueLine) {
+	  continueLine = gFalse;
+	  if ((line1 - firstLine) + 1 > (int)sizeof(buf))
+	    break;
+	  p = firstLine;
+	  p2 = buf;
+	  while (p < line1) {
+	    if (*p == '\n' || *p == '\r') {
+	      *p2++ = ' ';
+	      p++;
+	    } else {
+	      *p2++ = *p++;
+	    }
+	  }
+	  *p2 = '\0';
+	} else {
+	  firstLine = line;
+	  strncpy(buf, line, n);
+	  buf[n] = '\0';
+	}
 	for (p = buf; *p == ' ' || *p == '\t'; ++p) ;
 	if (!strncmp(p, "dup", 3)) {
 	  while (1) {
@@ -261,6 +281,9 @@ void FoFiType1::parse() {
 	      p += 2;
 	    } else if (*p >= '0' && *p <= '9') {
 	      base = 10;
+	    } else if (*p == '\n' || *p == '\r') {
+	      continueLine = gTrue;
+	      break;
 	    } else {
 	      break;
 	    }
@@ -268,7 +291,10 @@ void FoFiType1::parse() {
 	      code = code * base + (*p - '0');
 	    }
 	    for (; *p == ' ' || *p == '\t'; ++p) ;
-	    if (*p != '/') {
+	    if (*p == '\n' || *p == '\r') {
+	      continueLine = gTrue;
+	      break;
+	    } else if (*p != '/') {
 	      break;
 	    }
 	    ++p;
@@ -280,6 +306,10 @@ void FoFiType1::parse() {
 	      *p2 = c;
 	    }
 	    for (p = p2; *p == ' ' || *p == '\t'; ++p) ;
+	    if (*p == '\n' || *p == '\r') {
+	      continueLine = gTrue;
+	      break;
+	    }
 	    if (strncmp(p, "put", 3)) {
 	      break;
 	    }
commit 75fff6556eaf0ef3a6fcdef2c2229d0b6d1c58d9
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Jul 12 14:12:46 2017 +0100

    CVE-2017-9865 (fdo#100774) avoid stack buffer overflow
    
    in GfxImageColorMap:getGray
    
    by passing first arg to getGray of maximum possibly required size
    
    and similar in HtmlOutputDev::drawPngImage

diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc
index 5f5dc9ff..ac80dc18 100644
--- a/utils/HtmlOutputDev.cc
+++ b/utils/HtmlOutputDev.cc
@@ -39,6 +39,7 @@
 // Copyright (C) 2013 Johannes Brandstätter <jbrandstaetter at gmail.com>
 // Copyright (C) 2014 Fabio D'Urso <fabiodurso at hotmail.it>
 // Copyright (C) 2016 Vincent Le Garrec <legarrec.vincent at gmail.com>
+// Copyright (C) 2017 Caolán McNamara <caolanm at redhat.com>
 //
 // 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
@@ -1433,8 +1434,9 @@ void HtmlOutputDev::drawPngImage(GfxState *state, Stream *str, int width, int he
     int invert_bits = 0xff;
     if (colorMap) {
       GfxGray gray;
-      Guchar zero = 0;
-      colorMap->getGray(&zero, &gray);
+      Guchar zero[gfxColorMaxComps];
+      memset(zero, 0, sizeof(zero));
+      colorMap->getGray(zero, &gray);
       if (colToByte(gray) == 0)
         invert_bits = 0x00;
     }
diff --git a/utils/ImageOutputDev.cc b/utils/ImageOutputDev.cc
index 069d8210..f6fb35dd 100644
--- a/utils/ImageOutputDev.cc
+++ b/utils/ImageOutputDev.cc
@@ -23,6 +23,7 @@
 // Copyright (C) 2012, 2013, 2017 Adrian Johnson <ajohnson at redneon.com>
 // Copyright (C) 2013 Thomas Fischer <fischer at unix-ag.uni-kl.de>
 // Copyright (C) 2013 Hib Eris <hib at hiberis.nl>
+// Copyright (C) 2017 Caolán McNamara <caolanm at redhat.com>
 //
 // 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
@@ -344,7 +345,7 @@ void ImageOutputDev::writeImageFile(ImgWriter *writer, ImageFormat format, const
   GfxRGB rgb;
   GfxCMYK cmyk;
   GfxGray gray;
-  Guchar zero = 0;
+  Guchar zero[gfxColorMaxComps];
   int invert_bits;
 
   if (writer) {
@@ -383,7 +384,8 @@ void ImageOutputDev::writeImageFile(ImgWriter *writer, ImageFormat format, const
   // the mask we leave the data unchanged.
   invert_bits = 0xff;
   if (colorMap) {
-    colorMap->getGray(&zero, &gray);
+    memset(zero, 0, sizeof(zero));
+    colorMap->getGray(zero, &gray);
     if (colToByte(gray) == 0)
       invert_bits = 0x00;
   }
commit 5d0c23a9f6cdc3fd216335124788958f46932158
Author: Jan-Erik S <janerik234678 at gmail.com>
Date:   Sat Jul 29 18:23:39 2017 +0200

    Fix crash in broken document

diff --git a/poppler/StructTreeRoot.cc b/poppler/StructTreeRoot.cc
index e46e3e28..29beeecc 100644
--- a/poppler/StructTreeRoot.cc
+++ b/poppler/StructTreeRoot.cc
@@ -67,13 +67,13 @@ void StructTreeRoot::parse(Dict *root)
             index.free();
             continue;
           }
-          if (index.getInt() < 0) {
-            error(errSyntaxError, -1, "Nums item at position {0:d} is invalid value ({1:d})", i, index.getInt());
+          const unsigned idx = index.getInt();
+          if (idx < 0 || idx >= parentTree.size()) {
+            error(errSyntaxError, -1, "Nums item at position {0:d} is invalid value ({1:d}): [0..{2:d}]", i, idx, parentTree.size() - 1);
             index.free();
             continue;
           }
 
-          const unsigned idx = index.getInt();
           if (nums.arrayGetNF(i + 1, &value)->isRef()) {
             parentTree[idx].resize(1);
             parentTree[idx][0].ref = value.getRef();
commit 852fd28674e14f25c6902c0adab19909f73f2632
Author: David Faure <faure at kde.org>
Date:   Sat Jul 29 18:18:23 2017 +0200

    Set RUNPATH for poppler shared libs
    
    Bug #101945

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 98d23a61..576b1f9f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -55,6 +55,8 @@ endif(WIN32)
 set(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)")
 set(SHARE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share" CACHE STRING "Share directory name")
 
+set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+
 set(TESTDATADIR "${CMAKE_SOURCE_DIR}/../test" CACHE STRING "Specify test data dir.")
 if(NOT (EXISTS ${TESTDATADIR} AND EXISTS ${TESTDATADIR}/test-poppler.c))
   message(WARNING "
commit 771c82623e8e1e0c92b8ca6f7c2b8a81ccbb60d3
Author: Albert Astals Cid <aacid at kde.org>
Date:   Mon Jul 3 22:44:42 2017 +0200

    pdfunite: fix crash in broken documents
    
    Bug #101208

diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc
index f02f192f..ec5c7002 100644
--- a/poppler/PDFDoc.cc
+++ b/poppler/PDFDoc.cc
@@ -1127,8 +1127,22 @@ void PDFDoc::saveCompleteRewrite (OutStream* outStr)
 }
 
 void PDFDoc::writeDictionnary (Dict* dict, OutStream* outStr, XRef *xRef, Guint numOffset, Guchar *fileKey,
-                               CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen)
+                               CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen, std::set<Dict*> *alreadyWrittenDicts)
 {
+  bool deleteSet = false;
+  if (!alreadyWrittenDicts) {
+    alreadyWrittenDicts = new std::set<Dict*>;
+    deleteSet = true;
+  }
+
+  if (alreadyWrittenDicts->find(dict) != alreadyWrittenDicts->end()) {
+    error(errSyntaxWarning, -1, "PDFDoc::writeDictionnary: Found recursive dicts");
+    if (deleteSet) delete alreadyWrittenDicts;
+    return;
+  } else {
+    alreadyWrittenDicts->insert(dict);
+  }
+
   Object obj1;
   outStr->printf("<<");
   for (int i=0; i<dict->getLength(); i++) {
@@ -1136,10 +1150,14 @@ void PDFDoc::writeDictionnary (Dict* dict, OutStream* outStr, XRef *xRef, Guint
     GooString *keyNameToPrint = keyName.sanitizedName(gFalse /* non ps mode */);
     outStr->printf("/%s ", keyNameToPrint->getCString());
     delete keyNameToPrint;
-    writeObject(dict->getValNF(i, &obj1), outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen);
+    writeObject(dict->getValNF(i, &obj1), outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen, alreadyWrittenDicts);
     obj1.free();
   }
   outStr->printf(">> ");
+
+  if (deleteSet) {
+    delete alreadyWrittenDicts;
+  }
 }
 
 void PDFDoc::writeStream (Stream* str, OutStream* outStr)
@@ -1246,7 +1264,7 @@ Goffset PDFDoc::writeObjectHeader (Ref *ref, OutStream* outStr)
 }
 
 void PDFDoc::writeObject (Object* obj, OutStream* outStr, XRef *xRef, Guint numOffset, Guchar *fileKey,
-                          CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen)
+                          CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen, std::set<Dict*> *alreadyWrittenDicts)
 {
   Array *array;
   Object obj1;
@@ -1293,7 +1311,7 @@ void PDFDoc::writeObject (Object* obj, OutStream* outStr, XRef *xRef, Guint numO
       outStr->printf("] ");
       break;
     case objDict:
-      writeDictionnary (obj->getDict(), outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen);
+      writeDictionnary (obj->getDict(), outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen, alreadyWrittenDicts);
       break;
     case objStream: 
       {
@@ -1356,7 +1374,7 @@ void PDFDoc::writeObject (Object* obj, OutStream* outStr, XRef *xRef, Guint numO
           }
           stream->getDict()->remove("DecodeParms");
 
-          writeDictionnary (stream->getDict(),outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen);
+          writeDictionnary (stream->getDict(),outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen, alreadyWrittenDicts);
           writeStream (stream,outStr);
           delete encStream;
           obj1.free();
@@ -1374,7 +1392,7 @@ void PDFDoc::writeObject (Object* obj, OutStream* outStr, XRef *xRef, Guint numO
                 }
               }
           }
-          writeDictionnary (stream->getDict(), outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen);
+          writeDictionnary (stream->getDict(), outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, objNum, objGen, alreadyWrittenDicts);
           writeRawStream (stream, outStr);
         }
         break;
@@ -1509,7 +1527,7 @@ void PDFDoc::writeXRefTableTrailer(Dict *trailerDict, XRef *uxref, GBool writeAl
 {
   uxref->writeTableToFile( outStr, writeAllEntries );
   outStr->printf( "trailer\r\n");
-  writeDictionnary(trailerDict, outStr, xRef, 0, NULL, cryptRC4, 0, 0, 0);
+  writeDictionnary(trailerDict, outStr, xRef, 0, NULL, cryptRC4, 0, 0, 0, nullptr);
   outStr->printf( "\r\nstartxref\r\n");
   outStr->printf( "%lli\r\n", uxrefOffset);
   outStr->printf( "%%%%EOF\r\n");
@@ -1563,26 +1581,44 @@ void PDFDoc::writeHeader(OutStream *outStr, int major, int minor)
    outStr->printf("%%\xE2\xE3\xCF\xD3\n");
 }
 
-void PDFDoc::markDictionnary (Dict* dict, XRef * xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum)
+void PDFDoc::markDictionnary (Dict* dict, XRef * xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum, std::set<Dict*> *alreadyMarkedDicts)
 {
+  bool deleteSet = false;
+  if (!alreadyMarkedDicts) {
+    alreadyMarkedDicts = new std::set<Dict*>;
+    deleteSet = true;
+  }
+
+  if (alreadyMarkedDicts->find(dict) != alreadyMarkedDicts->end()) {
+    error(errSyntaxWarning, -1, "PDFDoc::markDictionnary: Found recursive dicts");
+    if (deleteSet) delete alreadyMarkedDicts;
+    return;
+  } else {
+    alreadyMarkedDicts->insert(dict);
+  }
+
   Object obj1;
   for (int i=0; i<dict->getLength(); i++) {
     const char *key = dict->getKey(i);
     if (strcmp(key, "Annots") != 0) {
-      markObject(dict->getValNF(i, &obj1), xRef, countRef, numOffset, oldRefNum, newRefNum);
+      markObject(dict->getValNF(i, &obj1), xRef, countRef, numOffset, oldRefNum, newRefNum, alreadyMarkedDicts);
     } else {
       Object annotsObj;
       dict->getValNF(i, &annotsObj);
       if (!annotsObj.isNull()) {
-        markAnnotations(&annotsObj, xRef, countRef, 0, oldRefNum, newRefNum);
+        markAnnotations(&annotsObj, xRef, countRef, 0, oldRefNum, newRefNum, alreadyMarkedDicts);
         annotsObj.free();
       }
     }
     obj1.free();
   }
+
+  if (deleteSet) {
+    delete alreadyMarkedDicts;
+  }
 }
 
-void PDFDoc::markObject (Object* obj, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum)
+void PDFDoc::markObject (Object* obj, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum, std::set<Dict*> *alreadyMarkedDicts)
 {
   Array *array;
   Object obj1;
@@ -1596,12 +1632,12 @@ void PDFDoc::markObject (Object* obj, XRef *xRef, XRef *countRef, Guint numOffse
       }
       break;
     case objDict:
-      markDictionnary (obj->getDict(), xRef, countRef, numOffset, oldRefNum, newRefNum);
+      markDictionnary (obj->getDict(), xRef, countRef, numOffset, oldRefNum, newRefNum, alreadyMarkedDicts);
       break;
     case objStream: 
       {
         Stream *stream = obj->getStream();
-        markDictionnary (stream->getDict(), xRef, countRef, numOffset, oldRefNum, newRefNum);
+        markDictionnary (stream->getDict(), xRef, countRef, numOffset, oldRefNum, newRefNum, alreadyMarkedDicts);
       }
       break;
     case objRef:
@@ -1695,7 +1731,7 @@ void PDFDoc::replacePageDict(int pageNo, int rotate,
   page.free();
 }
 
-void PDFDoc::markPageObjects(Dict *pageDict, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum) 
+void PDFDoc::markPageObjects(Dict *pageDict, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum, std::set<Dict*> *alreadyMarkedDicts)
 {
   pageDict->remove("OpenAction");
   pageDict->remove("Outlines");
@@ -1710,13 +1746,13 @@ void PDFDoc::markPageObjects(Dict *pageDict, XRef *xRef, XRef *countRef, Guint n
 	      strcmp(key, "Annots") != 0 &&
 	      strcmp(key, "P") != 0 &&
         strcmp(key, "Root") != 0) {
-      markObject(&value, xRef, countRef, numOffset, oldRefNum, newRefNum);
+      markObject(&value, xRef, countRef, numOffset, oldRefNum, newRefNum, alreadyMarkedDicts);
     }
     value.free();
   }
 }
 
-GBool PDFDoc::markAnnotations(Object *annotsObj, XRef *xRef, XRef *countRef, Guint numOffset, int oldPageNum, int newPageNum) {
+GBool PDFDoc::markAnnotations(Object *annotsObj, XRef *xRef, XRef *countRef, Guint numOffset, int oldPageNum, int newPageNum, std::set<Dict*> *alreadyMarkedDicts) {
   Object annots;
   GBool modified = gFalse;
   annotsObj->fetch(getXRef(), &annots);
@@ -1775,7 +1811,7 @@ GBool PDFDoc::markAnnotations(Object *annotsObj, XRef *xRef, XRef *countRef, Gui
             obj2.free();
           }
           type.free();
-          markPageObjects(dict, xRef, countRef, numOffset, oldPageNum, newPageNum);
+          markPageObjects(dict, xRef, countRef, numOffset, oldPageNum, newPageNum, alreadyMarkedDicts);
         }
         obj1.free();
         array->getNF(i, &obj1);
diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h
index 99de8a21..c5621ec2 100644
--- a/poppler/PDFDoc.h
+++ b/poppler/PDFDoc.h
@@ -14,7 +14,7 @@
 // under GPL version 2 or later
 //
 // Copyright (C) 2005, 2006, 2008 Brad Hards <bradh at frogmouth.net>
-// Copyright (C) 2005, 2009, 2014, 2015 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2005, 2009, 2014, 2015, 2017 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2008 Julien Rebetez <julienr at svn.gnome.org>
 // Copyright (C) 2008 Pino Toscano <pino at kde.org>
 // Copyright (C) 2008 Carlos Garcia Campos <carlosgc at gnome.org>
@@ -292,13 +292,13 @@ public:
 
   // rewrite pageDict with MediaBox, CropBox and new page CTM
   void replacePageDict(int pageNo, int rotate, PDFRectangle *mediaBox, PDFRectangle *cropBox);
-  void markPageObjects(Dict *pageDict, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum);
-  GBool markAnnotations(Object *annots, XRef *xRef, XRef *countRef, Guint numOffset, int oldPageNum, int newPageNum);
+  void markPageObjects(Dict *pageDict, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum, std::set<Dict*> *alreadyMarkedDicts = nullptr);
+  GBool markAnnotations(Object *annots, XRef *xRef, XRef *countRef, Guint numOffset, int oldPageNum, int newPageNum, std::set<Dict*> *alreadyMarkedDicts = nullptr);
   void markAcroForm(Object *acrpForm, XRef *xRef, XRef *countRef, Guint numOffset, int oldPageNum, int newPageNum);
   // write all objects used by pageDict to outStr
   Guint writePageObjects(OutStream *outStr, XRef *xRef, Guint numOffset, GBool combine = gFalse);
   static void writeObject (Object *obj, OutStream* outStr, XRef *xref, Guint numOffset, Guchar *fileKey,
-                           CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen);
+                           CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen, std::set<Dict*> *alreadyWrittenDicts = nullptr);
   static void writeHeader(OutStream *outStr, int major, int minor);
 
   // Ownership goes to the caller
@@ -311,21 +311,18 @@ public:
 
 private:
   // insert referenced objects in XRef
-  void markDictionnary (Dict* dict, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum);
-  void markObject (Object *obj, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum);
+  void markDictionnary (Dict* dict, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum, std::set<Dict*> *alreadyMarkedDicts);
+  void markObject (Object *obj, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum, std::set<Dict*> *alreadyMarkedDicts = nullptr);
   static void writeDictionnary (Dict* dict, OutStream* outStr, XRef *xRef, Guint numOffset, Guchar *fileKey,
-                                CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen);
+                                CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen, std::set<Dict*> *alreadyWrittenDicts);
 
   // Write object header to current file stream and return its offset
   static Goffset writeObjectHeader (Ref *ref, OutStream* outStr);
   static void writeObjectFooter (OutStream* outStr);
 
   void writeObject (Object *obj, OutStream* outStr, Guchar *fileKey, CryptAlgorithm encAlgorithm,
-                    int keyLength, int objNum, int objGen)
-  { writeObject(obj, outStr, getXRef(), 0, fileKey, encAlgorithm, keyLength, objNum, objGen); }
-  void writeDictionnary (Dict* dict, OutStream* outStr, Guchar *fileKey, CryptAlgorithm encAlgorithm,
-                         int keyLength, int objNum, int objGen)
-  { writeDictionnary(dict, outStr, getXRef(), 0, fileKey, encAlgorithm, keyLength, objNum, objGen); }
+                    int keyLength, int objNum, int objGen, std::set<Dict*> *alreadyWrittenDicts = nullptr)
+  { writeObject(obj, outStr, getXRef(), 0, fileKey, encAlgorithm, keyLength, objNum, objGen, alreadyWrittenDicts); }
   static void writeStream (Stream* str, OutStream* outStr);
   static void writeRawStream (Stream* str, OutStream* outStr);
   void writeXRefTableTrailer (Goffset uxrefOffset, XRef *uxref, GBool writeAllEntries,
commit 02d9b182b80d5745b79480b0b8d0eb49b0be304e
Author: Albert Astals Cid <aacid at kde.org>
Date:   Wed Jun 21 22:49:26 2017 +0200

    Poppler 0.56

diff --git a/CMakeLists.txt b/CMakeLists.txt
index a79db356..98d23a61 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -22,7 +22,7 @@ if (ECM_FOUND)
 endif()
 
 set(POPPLER_MAJOR_VERSION "0")
-set(POPPLER_MINOR_VERSION "55")
+set(POPPLER_MINOR_VERSION "56")
 set(POPPLER_MICRO_VERSION "0")
 set(POPPLER_VERSION "${POPPLER_MAJOR_VERSION}.${POPPLER_MINOR_VERSION}.${POPPLER_MICRO_VERSION}")
 
diff --git a/NEWS b/NEWS
index 448b06e7..0ca52ca2 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,11 @@
+Release 0.56.0
+        core:
+         * FormFieldButton::setState() shouldn't check the field is readOnly
+         * Fix crashes on multiple broken files
+
+        utils:
+         * pdfunite: Fix crash with broken documents. Bugs #101153 #101149
+
 Release 0.55.0
         core:
          * Fix abort in files with broken Decode arrays. KDE bug #379835
diff --git a/configure.ac b/configure.ac
index 6e3c6a4e..98d497a9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
 m4_define([poppler_version_major],[0])
-m4_define([poppler_version_minor],[55])
+m4_define([poppler_version_minor],[56])
 m4_define([poppler_version_micro],[0])
 m4_define([poppler_version],[poppler_version_major.poppler_version_minor.poppler_version_micro])
 
diff --git a/cpp/Doxyfile b/cpp/Doxyfile
index d29e6a5a..53d14523 100644
--- a/cpp/Doxyfile
+++ b/cpp/Doxyfile
@@ -31,7 +31,7 @@ PROJECT_NAME           = "Poppler CPP"
 # This could be handy for archiving the generated documentation or
 # if some version control system is used.
 
-PROJECT_NUMBER         = 0.55.0
+PROJECT_NUMBER         = 0.56.0
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
 # base path where the generated documentation will be put.
diff --git a/qt4/src/Doxyfile b/qt4/src/Doxyfile
index f756dce9..b85278d3 100644
--- a/qt4/src/Doxyfile
+++ b/qt4/src/Doxyfile
@@ -31,7 +31,7 @@ PROJECT_NAME           = "Poppler Qt4 "
 # This could be handy for archiving the generated documentation or
 # if some version control system is used.
 
-PROJECT_NUMBER         = 0.55.0
+PROJECT_NUMBER         = 0.56.0
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
 # base path where the generated documentation will be put.
diff --git a/qt5/src/Doxyfile b/qt5/src/Doxyfile
index c5c873a3..a7f71f40 100644
--- a/qt5/src/Doxyfile
+++ b/qt5/src/Doxyfile
@@ -31,7 +31,7 @@ PROJECT_NAME           = "Poppler Qt5"
 # This could be handy for archiving the generated documentation or
 # if some version control system is used.
 
-PROJECT_NUMBER         = 0.55.0
+PROJECT_NUMBER         = 0.56.0
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
 # base path where the generated documentation will be put.
commit 3a2759aa2a98c2157cb35731b95e393b8882f8d3
Author: Jose Aliste <jaliste at src.gnome.org>
Date:   Tue May 16 18:44:49 2017 -0400

    Check numComps is between reasonable bounds
    
    Before this patch, some PDF might crash because of an overflow
    if numComps does not lie between 0 and 4.
    This is a security fix for CVE-2017-0319.

diff --git a/poppler/Stream.cc b/poppler/Stream.cc
index d93c560e..e3d5cf6a 100644
--- a/poppler/Stream.cc
+++ b/poppler/Stream.cc
@@ -32,6 +32,7 @@
 // Copyright (C) 2013 Pino Toscano <pino at kde.org>
 // Copyright (C) 2015 Suzuki Toshiya <mpsuzuki at hiroshima-u.ac.jp>
 // Copyright (C) 2015 Jason Crain <jason at aquaticape.us>
+// Copyright (C) 2017 Jose Aliste <jaliste at src.gnome.org>
 //
 // 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
@@ -3585,6 +3586,12 @@ GBool DCTStream::readProgressiveSOF() {
   height = read16();
   width = read16();
   numComps = str->getChar();
+
+  if (numComps <= 0 || numComps > 4) {
+    error(errSyntaxError, getPos(), "Bad number of components in DCT stream");
+    numComps = 0;
+    return gFalse;
+  }
   if (prec != 8) {
     error(errSyntaxError, getPos(), "Bad DCT precision {0:d}", prec);
     return gFalse;
commit d9c88e1c8892c79b8865a0dabdcc0d3ffd55c195
Author: Albert Astals Cid <aacid at kde.org>
Date:   Wed Jun 21 00:56:38 2017 +0200

    Fix crash in malformed documents

diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index e6cd329b..f61f8124 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -4034,18 +4034,18 @@ GfxUnivariateShading::~GfxUnivariateShading() {
 
 void GfxUnivariateShading::getColor(double t, GfxColor *color) {
   double out[gfxColorMaxComps];
-  int i, nComps;
+  int i;
+
+  // NB: there can be one function with n outputs or n functions with
+  // one output each (where n = number of color components)
+  const int nComps = nFuncs * funcs[0]->getOutputSize();
 
-  if (unlikely(nFuncs < 1)) {
+  if (unlikely(nFuncs < 1 || nComps > gfxColorMaxComps)) {
     for (int i = 0; i < gfxColorMaxComps; i++)
         color->c[i] = 0;
     return;
   }
 
-  // NB: there can be one function with n outputs or n functions with
-  // one output each (where n = number of color components)
-  nComps = nFuncs * funcs[0]->getOutputSize();
-
   if (cacheSize > 0) {
     double x, ix, *l, *u, *upper;
 
commit 55db66c69fd56826b8523710046deab1a8d14ba2
Author: Albert Astals Cid <aacid at kde.org>
Date:   Wed Jun 21 00:55:20 2017 +0200

    Fix crash in malformed documents

diff --git a/poppler/JBIG2Stream.cc b/poppler/JBIG2Stream.cc
index 48535883..d89108c8 100644
--- a/poppler/JBIG2Stream.cc
+++ b/poppler/JBIG2Stream.cc
@@ -896,7 +896,7 @@ void JBIG2Bitmap::combine(JBIG2Bitmap *bitmap, int x, int y,
   oneByte = x0 == ((x1 - 1) & ~7);
 
   for (yy = y0; yy < y1; ++yy) {
-    if (unlikely(y + yy) >= h)
+    if (unlikely((y + yy >= h) || (y + yy < 0)))
       continue;
 
     // one byte per line -- need to mask both left and right side
commit 5266fa426d73c5dbdb3dd903d50885097833acc6
Author: Albert Astals Cid <aacid at kde.org>
Date:   Tue Jun 20 23:58:26 2017 +0200

    Fix crash in malformed document
    
    Bug #101526

diff --git a/poppler/Stream.cc b/poppler/Stream.cc
index 4ac91078..d93c560e 100644
--- a/poppler/Stream.cc
+++ b/poppler/Stream.cc
@@ -468,7 +468,7 @@ ImageStream::ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA) {
 
   nVals = width * nComps;
   inputLineSize = (nVals * nBits + 7) >> 3;
-  if (nBits <= 0 || nVals > INT_MAX / nBits - 7 || width > INT_MAX / nComps) {
+  if (nComps <= 0 || nBits <= 0 || nVals > INT_MAX / nBits - 7 || width > INT_MAX / nComps) {
     inputLineSize = -1;
   }
   inputLine = (Guchar *)gmallocn_checkoverflow(inputLineSize, sizeof(char));
commit 112b8ab16128c6e7f80fe7c1890f7b63abd85cce
Author: Albert Astals Cid <aacid at kde.org>
Date:   Tue Jun 20 23:51:16 2017 +0200

    Fix crash in broken documents
    
    Fixes bug #101525

diff --git a/poppler/JBIG2Stream.cc b/poppler/JBIG2Stream.cc
index 067fb7f0..48535883 100644
--- a/poppler/JBIG2Stream.cc
+++ b/poppler/JBIG2Stream.cc
@@ -760,6 +760,10 @@ JBIG2Bitmap *JBIG2Bitmap::getSlice(Guint x, Guint y, Guint wA, Guint hA) {
   JBIG2Bitmap *slice;
   Guint xx, yy;
 
+  if (!data) {
+      return nullptr;
+  }
+
   slice = new JBIG2Bitmap(0, wA, hA);
   if (slice->isOk()) {
     slice->clearToZero();
@@ -3827,6 +3831,10 @@ JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h,
   JBIG2BitmapPtr tpgrCXPtr2 = {0};
   int x, y, pix;
 
+  if (!refBitmap) {
+      return nullptr;
+  }
+
   bitmap = new JBIG2Bitmap(0, w, h);
   if (!bitmap->isOk())
   {
commit 4e68bf998f886cab8a45fa315164d8ba7aa0dee4
Author: Albert Astals Cid <aacid at kde.org>
Date:   Tue Jun 20 23:43:23 2017 +0200

    Fix crash on broken documents
    
    Fixes bug #101524

diff --git a/poppler/JBIG2Stream.cc b/poppler/JBIG2Stream.cc
index d26ba02b..067fb7f0 100644
--- a/poppler/JBIG2Stream.cc
+++ b/poppler/JBIG2Stream.cc
@@ -15,7 +15,7 @@
 //
 // Copyright (C) 2006 Raj Kumar <rkumar at archive.org>
 // Copyright (C) 2006 Paul Walmsley <paul at booyaka.com>
-// Copyright (C) 2006-2010, 2012, 2014-2016 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2006-2010, 2012, 2014-2017 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2009 David Benjamin <davidben at mit.edu>
 // Copyright (C) 2011 Edward Jiang <ejiang at google.com>
 // Copyright (C) 2012 William Bader <williambader at hotmail.com>
@@ -1304,7 +1304,7 @@ Goffset JBIG2Stream::getPos() {
 int JBIG2Stream::getChars(int nChars, Guchar *buffer) {
   int n, i;
 
-  if (nChars <= 0) {
+  if (nChars <= 0 || !dataPtr) {
     return 0;
   }
   if (dataEnd - dataPtr < nChars) {
commit 558cdb4a4efbb2227f4009f5d87cdd94bfb40107
Author: Albert Astals Cid <aacid at kde.org>
Date:   Tue Jun 20 23:37:26 2017 +0200

    Fix crash in malformed documents
    
    Fixes bug #101523

diff --git a/poppler/GfxFont.cc b/poppler/GfxFont.cc
index ea23e03a..b59ec06c 100644
--- a/poppler/GfxFont.cc
+++ b/poppler/GfxFont.cc
@@ -13,7 +13,7 @@
 // All changes made under the Poppler project to this file are licensed
 // under GPL version 2 or later
 //
-// Copyright (C) 2005, 2006, 2008-2010, 2012, 2014, 2015 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2005, 2006, 2008-2010, 2012, 2014, 2015, 2017 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2005, 2006 Kristian Høgsberg <krh at redhat.com>
 // Copyright (C) 2006 Takashi Iwai <tiwai at suse.de>
 // Copyright (C) 2007 Julien Rebetez <julienr at svn.gnome.org>
@@ -2371,7 +2371,7 @@ int *GfxCIDFont::getCodeToGIDMap(FoFiTrueType *ff, int *mapsizep) {
   Ref embID;
 
   *mapsizep = 0;
-  if (!ctu) return NULL;
+  if (!ctu || !getCollection()) return NULL;
   if (getCollection()->cmp("Adobe-Identity") == 0) return NULL;
   if (getEmbeddedFontID(&embID)) {
    /* if this font is embedded font, 
commit f7030a0176ed0ab484a401acc26072060e420679
Author: Albert Astals Cid <aacid at kde.org>
Date:   Mon Jun 19 23:45:24 2017 +0200

    Fix crash on broken documents
    
    Bug #101505

diff --git a/goo/GooHash.cc b/goo/GooHash.cc
index f4a92f17..49f58c5f 100644
--- a/goo/GooHash.cc
+++ b/goo/GooHash.cc
@@ -6,6 +6,20 @@
 //
 //========================================================================
 
+//========================================================================
+//
+// Modified under the Poppler project - http://poppler.freedesktop.org
+//
+// All changes made under the Poppler project to this file are licensed
+// under GPL version 2 or later
+//
+// Copyright (C) 2017 Albert Astals Cid <aacid at kde.org>
+//
+// 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
+//
+//========================================================================
+
 #include <config.h>
 
 #ifdef USE_GCC_PRAGMAS
@@ -15,6 +29,7 @@
 #include "gmem.h"
 #include "GooString.h"
 #include "GooHash.h"
+#include "GooLikely.h"
 
 //------------------------------------------------------------------------
 
@@ -339,6 +354,9 @@ void GooHash::expand() {
 GooHashBucket *GooHash::find(GooString *key, int *h) {
   GooHashBucket *p;
 
+  if (unlikely(!key))
+    return nullptr;
+
   *h = hash(key);
   for (p = tab[*h]; p; p = p->next) {
     if (!p->key->cmp(key)) {
commit e465d36b8ecf46b80af4ac6b941ae56eb4883a89
Author: Albert Astals Cid <aacid at kde.org>
Date:   Mon Jun 19 23:35:29 2017 +0200

    Fix crash on malformed files
    
    Bug #101502

diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index b17925f4..e6cd329b 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -4036,6 +4036,12 @@ void GfxUnivariateShading::getColor(double t, GfxColor *color) {
   double out[gfxColorMaxComps];
   int i, nComps;
 
+  if (unlikely(nFuncs < 1)) {
+    for (int i = 0; i < gfxColorMaxComps; i++)
+        color->c[i] = 0;
+    return;
+  }
+
   // NB: there can be one function with n outputs or n functions with
   // one output each (where n = number of color components)
   nComps = nFuncs * funcs[0]->getOutputSize();
@@ -4089,6 +4095,9 @@ void GfxUnivariateShading::setupCache(const Matrix *ctm,
   cacheBounds = NULL;
   cacheSize = 0;
 
+  if (unlikely(nFuncs < 1))
+    return;
+
   // NB: there can be one function with n outputs or n functions with
   // one output each (where n = number of color components)
   nComps = nFuncs * funcs[0]->getOutputSize();
commit e2ab2fa9d8c41e0115b2c276a2594cd2f7c217e6
Author: Albert Astals Cid <aacid at kde.org>
Date:   Mon Jun 19 23:18:51 2017 +0200

    Fix crash on malformed files
    
    Bug #101500

diff --git a/poppler/Function.cc b/poppler/Function.cc
index 7f359b8e..785933df 100644
--- a/poppler/Function.cc
+++ b/poppler/Function.cc
@@ -13,7 +13,7 @@
 // All changes made under the Poppler project to this file are licensed
 // under GPL version 2 or later
 //
-// Copyright (C) 2006, 2008-2010, 2013-2015 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2006, 2008-2010, 2013-2015, 2017 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2006 Jeff Muizelaar <jeff at infidigm.net>
 // Copyright (C) 2010 Christian Feuersänger <cfeuersaenger at googlemail.com>
 // Copyright (C) 2011 Andrea Canciani <ranma42 at gmail.com>
@@ -1623,7 +1623,9 @@ void PostScriptFunction::exec(PSStack *stack, int codePtr) {
       case psOpIdiv:
 	i2 = stack->popInt();
 	i1 = stack->popInt();
-	stack->pushInt(i1 / i2);
+	if (likely(i2 != 0)) {
+	  stack->pushInt(i1 / i2);
+	}
 	break;
       case psOpIndex:
 	stack->index(stack->popInt());
@@ -1659,7 +1661,9 @@ void PostScriptFunction::exec(PSStack *stack, int codePtr) {
       case psOpMod:
 	i2 = stack->popInt();
 	i1 = stack->popInt();
-	stack->pushInt(i1 % i2);
+	if (likely(i2 != 0)) {
+	  stack->pushInt(i1 % i2);
+	}
 	break;
       case psOpMul:
 	if (stack->topTwoAreInts()) {
commit 17e4111da1ae5c9798ca0c040bf75c01bbb72a8a
Author: Albert Astals Cid <aacid at kde.org>
Date:   Sat Jun 17 17:47:23 2017 +0200

    Break earlier on reaching recursion limit
    
    Bug #101379

diff --git a/poppler/Parser.cc b/poppler/Parser.cc
index 28a54607..8079ca1d 100644
--- a/poppler/Parser.cc
+++ b/poppler/Parser.cc
@@ -13,7 +13,7 @@
 // All changes made under the Poppler project to this file are licensed
 // under GPL version 2 or later
 //
-// Copyright (C) 2006, 2009, 201, 2010, 2013, 2014 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2006, 2009, 201, 2010, 2013, 2014, 2017 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2006 Krzysztof Kowalczyk <kkowalczyk at gmail.com>
 // Copyright (C) 2009 Ilya Gorenbein <igorenbein at finjan.com>
 // Copyright (C) 2012 Hib Eris <hib at hiberis.nl>
@@ -87,8 +87,14 @@ Object *Parser::getObj(Object *obj, GBool simpleOnly,
     inlineImg = 0;
   }
 
+  if (unlikely(recursion >= recursionLimit)) {
+    obj->free();
+    obj->initError();
+    return obj;
+  }
+
   // array
-  if (!simpleOnly && likely(recursion < recursionLimit) && buf1.isCmd("[")) {
+  if (!simpleOnly && buf1.isCmd("[")) {
     shift();
     obj->initArray(xref);
     while (!buf1.isCmd("]") && !buf1.isEOF())
@@ -101,7 +107,7 @@ Object *Parser::getObj(Object *obj, GBool simpleOnly,
     shift();
 
   // dictionary or stream
-  } else if (!simpleOnly && likely(recursion < recursionLimit) && buf1.isCmd("<<")) {
+  } else if (!simpleOnly && buf1.isCmd("<<")) {
     shift(objNum);
     obj->initDict(xref);
     while (!buf1.isCmd(">>") && !buf1.isEOF()) {
@@ -119,6 +125,9 @@ Object *Parser::getObj(Object *obj, GBool simpleOnly,
 	  break;
 	}
 	obj->dictAdd(key, getObj(&obj2, gFalse, fileKey, encAlgorithm, keyLength, objNum, objGen, recursion + 1));
+	if (unlikely(obj2.isError() && recursion + 1 >= recursionLimit)) {
+	  break;
+	}
       }
     }
     if (buf1.isEOF()) {
commit 8e1a2474c5513f7b2f4718258ca90e2d6e03f127
Author: Albert Astals Cid <aacid at kde.org>
Date:   Sat Jun 17 12:35:41 2017 +0200

    pdftohmtl: Initialize rotSkewMat
    
    Fixes uninitialized memory read at bug #100314

diff --git a/utils/HtmlFonts.cc b/utils/HtmlFonts.cc
index a12992ec..49376d65 100644
--- a/utils/HtmlFonts.cc
+++ b/utils/HtmlFonts.cc
@@ -156,6 +156,7 @@ HtmlFont::HtmlFont(GfxFont *font, int _size, GfxRGB rgb){
     pos = font_num; 
   if (!DefaultFont) DefaultFont=new GooString(fonts[font_num].name);
 
+  rotSkewMat[0] = rotSkewMat[1] = rotSkewMat[2] = rotSkewMat[3] = 0;
 }
  
 HtmlFont::HtmlFont(const HtmlFont& x){
commit dd7b0eec87ffc389ee3ba7319442e681e19b15ba
Author: Albert Astals Cid <aacid at kde.org>
Date:   Sat Jun 17 12:33:35 2017 +0200

    Remove unused constructor

diff --git a/utils/HtmlFonts.h b/utils/HtmlFonts.h
index 7993c78e..252d5f90 100644
--- a/utils/HtmlFonts.h
+++ b/utils/HtmlFonts.h
@@ -18,7 +18,7 @@
 // under GPL version 2 or later
 //
 // Copyright (C) 2010 OSSD CDAC Mumbai by Leena Chourey (leenac at cdacmumbai.in) and Onkar Potdar (onkar at cdacmumbai.in)
-// Copyright (C) 2010, 2012 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2010, 2012, 2017 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2011 Steven Murdoch <Steven.Murdoch at cl.cam.ac.uk>
 // Copyright (C) 2011 Joshua Richardson <jric at chegg.com>
 // Copyright (C) 2012 Igor Slepchin <igor.slepchin at gmail.com>
@@ -72,7 +72,6 @@ class HtmlFont{
    double rotSkewMat[4]; // only four values needed for rotation and skew
 public:  
 
-   HtmlFont(){FontName=NULL; rotOrSkewed = gFalse;}
    HtmlFont(GfxFont *font,int _size, GfxRGB rgb);
    HtmlFont(const HtmlFont& x);
    HtmlFont& operator=(const HtmlFont& x);
commit 5b05222ccd18a121ea2ae1d67b8b5d4947cdfce0
Author: Albert Astals Cid <aacid at kde.org>
Date:   Sat Jun 17 12:33:06 2017 +0200

    Fix crash in malformed file
    
    Bug #101429

diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 279f650d..974b098b 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -5401,7 +5401,7 @@ void AnnotScreen::initialize(PDFDoc *docA, Dict* dict) {
   action = NULL;
   if (dict->lookup("A", &obj1)->isDict()) {
     action = LinkAction::parseAction(&obj1, doc->getCatalog()->getBaseURI());
-    if (action->getKind() == actionRendition && page == 0) {
+    if (action && action->getKind() == actionRendition && page == 0) {
       error (errSyntaxError, -1, "Invalid Rendition action: associated screen annotation without P");
       delete action;
       action = NULL;
commit e1b5053e54b0ef7d6b09f3b9c97883db533d509a
Author: Even Rouault <even.rouault at spatialys.com>
Date:   Fri Jun 16 00:21:53 2017 +0200

    Fix crash on broken file
    
    Fixes bug #101366

diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc
index b9fa6cbd..5502be64 100644
--- a/poppler/SplashOutputDev.cc
+++ b/poppler/SplashOutputDev.cc
@@ -37,6 +37,7 @@
 // Copyright (C) 2015 Tamas Szekeres <szekerest at gmail.com>
 // Copyright (C) 2015 Kenji Uno <ku at digitaldolphins.jp>
 // Copyright (C) 2016 Takahiro Hashimoto <kenya888.en at gmail.com>
+// Copyright (C) 2017 Even Rouault <even.rouault at spatialys.com>
 //
 // 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
@@ -2725,7 +2726,7 @@ void SplashOutputDev::type3D1(GfxState *state, double wx, double wy,
   int i, j;
 
   // ignore multiple d0/d1 operators
-  if (t3GlyphStack->haveDx) {
+  if (!t3GlyphStack || t3GlyphStack->haveDx) {
     return;
   }
   t3GlyphStack->haveDx = gTrue;
commit 9e05af3da0ce14c48f0652e01718960c6bc7b4b0
Author: Hans-Ulrich Jüttner <huj at froreich-bioscientia.de>
Date:   Wed Jun 14 23:19:48 2017 +0200

    FormFieldButton::setState() shouldn't check the field is readOnly
    
    Bug #101419

diff --git a/poppler/Form.cc b/poppler/Form.cc
index ced3140c..4627a432 100644
--- a/poppler/Form.cc
+++ b/poppler/Form.cc
@@ -17,6 +17,7 @@
 // Copyright 2012 Fabio D'Urso <fabiodurso at hotmail.it>
 // Copyright 2015 André Guerreiro <aguerreiro1985 at gmail.com>
 // Copyright 2015 André Esser <bepandre at hotmail.com>
+// Copyright 2017 Hans-Ulrich Jüttner <huj at froreich-bioscientia.de>
 //
 //========================================================================
 
@@ -903,11 +904,6 @@ void FormFieldButton::fillChildrenSiblingsID()
 
 GBool FormFieldButton::setState(char *state)
 {
-  if (readOnly) {
-    error(errInternal, -1, "FormFieldButton::setState called on a readOnly field\n");
-    return gFalse;
-  }
-
   // A check button could behave as a radio button
   // when it's in a set of more than 1 buttons
   if (btype != formButtonRadio && btype != formButtonCheck)


More information about the poppler mailing list