diff options
author | Albert Astals Cid <aacid@kde.org> | 2017-07-31 16:39:53 +0200 |
---|---|---|
committer | Albert Astals Cid <aacid@kde.org> | 2017-07-31 16:39:53 +0200 |
commit | 66e718e753a527289ce86cd206fcffd23fc28d81 (patch) | |
tree | dc0c32b66c42fabc3553709e72d2b4ee9a8c1dcd | |
parent | 9cecd78ff12a145fd7a61d226d54fd8f9ce19638 (diff) | |
parent | 213ae24b4df97f557e771060e37197d0e57f6f7f (diff) |
Merge remote-tracking branch 'origin/master' into better_object
-rw-r--r-- | CMakeLists.txt | 4 | ||||
-rw-r--r-- | NEWS | 8 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | cpp/Doxyfile | 2 | ||||
-rw-r--r-- | fofi/FoFiType1.cc | 40 | ||||
-rw-r--r-- | goo/GooHash.cc | 18 | ||||
-rw-r--r-- | poppler/FlateStream.h | 16 | ||||
-rw-r--r-- | poppler/Function.cc | 8 | ||||
-rw-r--r-- | poppler/GfxFont.cc | 2 | ||||
-rw-r--r-- | poppler/GfxState.cc | 13 | ||||
-rw-r--r-- | poppler/JBIG2Stream.cc | 12 | ||||
-rw-r--r-- | poppler/JPXStream.h | 16 | ||||
-rw-r--r-- | poppler/PDFDoc.cc | 71 | ||||
-rw-r--r-- | poppler/PDFDoc.h | 19 | ||||
-rw-r--r-- | poppler/Stream.cc | 9 | ||||
-rw-r--r-- | poppler/Stream.h | 16 | ||||
-rw-r--r-- | poppler/StructTreeRoot.cc | 8 | ||||
-rw-r--r-- | qt4/src/Doxyfile | 2 | ||||
-rw-r--r-- | qt5/src/Doxyfile | 2 | ||||
-rw-r--r-- | utils/HtmlFonts.cc | 6 | ||||
-rw-r--r-- | utils/HtmlOutputDev.cc | 6 | ||||
-rw-r--r-- | utils/ImageOutputDev.cc | 6 |
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 " @@ -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("""); 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; } |