summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Astals Cid <aacid@kde.org>2017-07-31 16:39:53 +0200
committerAlbert Astals Cid <aacid@kde.org>2017-07-31 16:39:53 +0200
commit66e718e753a527289ce86cd206fcffd23fc28d81 (patch)
treedc0c32b66c42fabc3553709e72d2b4ee9a8c1dcd
parent9cecd78ff12a145fd7a61d226d54fd8f9ce19638 (diff)
parent213ae24b4df97f557e771060e37197d0e57f6f7f (diff)
Merge remote-tracking branch 'origin/master' into better_object
-rw-r--r--CMakeLists.txt4
-rw-r--r--NEWS8
-rw-r--r--configure.ac2
-rw-r--r--cpp/Doxyfile2
-rw-r--r--fofi/FoFiType1.cc40
-rw-r--r--goo/GooHash.cc18
-rw-r--r--poppler/FlateStream.h16
-rw-r--r--poppler/Function.cc8
-rw-r--r--poppler/GfxFont.cc2
-rw-r--r--poppler/GfxState.cc13
-rw-r--r--poppler/JBIG2Stream.cc12
-rw-r--r--poppler/JPXStream.h16
-rw-r--r--poppler/PDFDoc.cc71
-rw-r--r--poppler/PDFDoc.h19
-rw-r--r--poppler/Stream.cc9
-rw-r--r--poppler/Stream.h16
-rw-r--r--poppler/StructTreeRoot.cc8
-rw-r--r--qt4/src/Doxyfile2
-rw-r--r--qt5/src/Doxyfile2
-rw-r--r--utils/HtmlFonts.cc6
-rw-r--r--utils/HtmlOutputDev.cc6
-rw-r--r--utils/ImageOutputDev.cc6
22 files changed, 208 insertions, 78 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a79db356..576b1f9f 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}")
@@ -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 "
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/fofi/FoFiType1.cc b/fofi/FoFiType1.cc
index 44f16972..f741d5d3 100644
--- a/fofi/FoFiType1.cc
+++ b/fofi/FoFiType1.cc
@@ -17,6 +17,7 @@
// Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2010 Jakub Wilk <jwilk@jwilk.net>
// Copyright (C) 2014 Carlos Garcia Campos <carlosgc@gnome.org>
+// Copyright (C) 2017 Adrian Johnson <ajohnson@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;
@@ -281,6 +307,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;
}
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@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)) {
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/Function.cc b/poppler/Function.cc
index 0f21f23e..92ba5f74 100644
--- a/poppler/Function.cc
+++ b/poppler/Function.cc
@@ -1576,7 +1576,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());
@@ -1612,7 +1614,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()) {
diff --git a/poppler/GfxFont.cc b/poppler/GfxFont.cc
index 5f6444b5..183f0497 100644
--- a/poppler/GfxFont.cc
+++ b/poppler/GfxFont.cc
@@ -2290,7 +2290,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,
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 2561d412..b2971ec0 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -3902,11 +3902,17 @@ 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)
- nComps = nFuncs * funcs[0]->getOutputSize();
+ const int nComps = nFuncs * funcs[0]->getOutputSize();
+
+ if (unlikely(nFuncs < 1 || nComps > gfxColorMaxComps)) {
+ for (int i = 0; i < gfxColorMaxComps; i++)
+ color->c[i] = 0;
+ return;
+ }
if (cacheSize > 0) {
double x, ix, *l, *u, *upper;
@@ -3957,6 +3963,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();
diff --git a/poppler/JBIG2Stream.cc b/poppler/JBIG2Stream.cc
index c6b86a50..50c6eee6 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();
@@ -892,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
@@ -1303,7 +1307,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) {
@@ -3826,6 +3830,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())
{
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/PDFDoc.cc b/poppler/PDFDoc.cc
index 206b7e42..35b3bc01 100644
--- a/poppler/PDFDoc.cc
+++ b/poppler/PDFDoc.cc
@@ -1074,8 +1074,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);
+ }
+
outStr->printf("<<");
for (int i=0; i<dict->getLength(); i++) {
GooString keyName(dict->getKey(i));
@@ -1083,9 +1097,13 @@ void PDFDoc::writeDictionnary (Dict* dict, OutStream* outStr, XRef *xRef, Guint
outStr->printf("/%s ", keyNameToPrint->getCString());
delete keyNameToPrint;
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,7 +1207,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;
@@ -1234,7 +1252,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:
{
@@ -1291,7 +1309,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;
} else {
@@ -1307,7 +1325,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;
@@ -1426,7 +1444,7 @@ void PDFDoc::writeXRefTableTrailer(Object &&trailerDict, XRef *uxref, GBool writ
{
uxref->writeTableToFile( outStr, writeAllEntries );
outStr->printf( "trailer\r\n");
- writeDictionnary(trailerDict.getDict(), outStr, xRef, 0, NULL, cryptRC4, 0, 0, 0);
+ 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");
@@ -1477,23 +1495,42 @@ 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) {
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);
if (!annotsObj.isNull()) {
- markAnnotations(&annotsObj, xRef, countRef, 0, oldRefNum, newRefNum);
+ markAnnotations(&annotsObj, xRef, countRef, 0, oldRefNum, newRefNum, alreadyMarkedDicts);
}
}
}
+
+ 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;
@@ -1506,12 +1543,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:
@@ -1581,7 +1618,7 @@ void PDFDoc::replacePageDict(int pageNo, int rotate,
getXRef()->setModifiedObject(&page, *refPage);
}
-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,12 +1633,12 @@ 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);
}
}
}
-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) {
GBool modified = gFalse;
Object annots = annotsObj->fetch(getXRef());
if (annots.isArray()) {
@@ -1637,7 +1674,7 @@ GBool PDFDoc::markAnnotations(Object *annotsObj, XRef *xRef, XRef *countRef, Gui
}
}
}
- markPageObjects(dict, xRef, countRef, numOffset, oldPageNum, newPageNum);
+ markPageObjects(dict, xRef, countRef, numOffset, oldPageNum, newPageNum, alreadyMarkedDicts);
}
obj1 = array->getNF(i);
if (obj1.isRef()) {
diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h
index 6a83c7c5..83a2e97e 100644
--- a/poppler/PDFDoc.h
+++ b/poppler/PDFDoc.h
@@ -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);
static Object createTrailerDict (int uxrefSize, GBool incrUpdate, Goffset startxRef,
@@ -310,21 +310,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,
diff --git a/poppler/Stream.cc b/poppler/Stream.cc
index e5905fb8..ac031a74 100644
--- a/poppler/Stream.cc
+++ b/poppler/Stream.cc
@@ -32,6 +32,7 @@
// Copyright (C) 2013 Pino Toscano <pino@kde.org>
// Copyright (C) 2015 Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp>
// Copyright (C) 2015 Jason Crain <jason@aquaticape.us>
+// Copyright (C) 2017 Jose Aliste <jaliste@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
@@ -442,7 +443,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));
@@ -3559,6 +3560,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;
diff --git a/poppler/Stream.h b/poppler/Stream.h
index 9c53ea39..2317080e 100644
--- a/poppler/Stream.h
+++ b/poppler/Stream.h
@@ -868,15 +868,15 @@ public:
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 --git a/poppler/StructTreeRoot.cc b/poppler/StructTreeRoot.cc
index 937df608..5af530e9 100644
--- a/poppler/StructTreeRoot.cc
+++ b/poppler/StructTreeRoot.cc
@@ -65,13 +65,13 @@ void StructTreeRoot::parse(Dict *root)
error(errSyntaxError, -1, "Nums item at position {0:d} is wrong type ({1:s})", i, index.getTypeName());
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);
continue;
}
- const unsigned idx = index.getInt();
- Object value = nums.arrayGetNF(i + 1);
+ Object value = nums.arrayGetNF(i + 1);
if (value.isRef()) {
parentTree[idx].resize(1);
parentTree[idx][0].ref = value.getRef();
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.
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@gmail.com>
// Copyright (C) 2012 Luis Parravicini <lparravi@gmail.com>
// Copyright (C) 2013 Julien Nabet <serval2412@yahoo.fr>
+// Copyright (C) 2017 Jason Crain <jason@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("&#34;"); break;
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@gmail.com>
// Copyright (C) 2014 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2016 Vincent Le Garrec <legarrec.vincent@gmail.com>
+// Copyright (C) 2017 Caolán McNamara <caolanm@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@redneon.com>
// Copyright (C) 2013 Thomas Fischer <fischer@unix-ag.uni-kl.de>
// Copyright (C) 2013 Hib Eris <hib@hiberis.nl>
+// Copyright (C) 2017 Caolán McNamara <caolanm@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;
}