import poppler-20.11.0-1.el8

This commit is contained in:
CentOS Sources 2020-12-08 08:13:09 +00:00 committed by Andrew Lukoshko
parent 10124b7d66
commit fb1291f993
28 changed files with 1124 additions and 2671 deletions

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
SOURCES/poppler-0.66.0.tar.xz
SOURCES/poppler-20.11.0.tar.xz
SOURCES/poppler-test-2009-05-13_0d2bfd4af4c76a3bac27ccaff793d9129df7b57a.tar.xz

View File

@ -1,2 +1,2 @@
95f58069ddbeb7db9bee68873266a5dc8aaaef96 SOURCES/poppler-0.66.0.tar.xz
0aa751121aed6ee2220ef3ea16b9df8f9b2e81c1 SOURCES/poppler-20.11.0.tar.xz
b58229322eb8f44a2bb1d98114b9fa3dfbef6a0a SOURCES/poppler-test-2009-05-13_0d2bfd4af4c76a3bac27ccaff793d9129df7b57a.tar.xz

View File

@ -17,18 +17,18 @@ index 7c2ca78..e93908c 100644
--- a/poppler/TextOutputDev.cc
+++ b/poppler/TextOutputDev.cc
@@ -178,6 +178,12 @@
#define combMaxMidDelta 0.3
#define combMaxBaseDelta 0.4
// to read the underlying image. Issue #157
#define glyphlessSelectionOpacity 0.4
+// Returns whether x is between a and b or equal to a or b.
+// a and b don't need to be sorted.
+#define XBetweenAB(x,a,b) (!(((x) > (a) && (x) > (b)) || \
+ ((x) < (a) && (x) < (b))) ? \
+ gTrue : gFalse)
+ true : false)
+
static int reorderText(Unicode *text, int len, UnicodeMap *uMap, GBool primaryLR, GooString *s, Unicode* u) {
char lre[8], rle[8], popdf[8], buf[8];
int lreLen = 0, rleLen = 0, popdfLen = 0, n;
namespace {
inline bool isAscii7(Unicode uchar)
@@ -4411,11 +4417,37 @@ void TextSelectionSizer::visitLine (TextLine *line,
PDFRectangle *rect;
double x1, y1, x2, y2, margin;
@ -70,17 +70,17 @@ index 7c2ca78..e93908c 100644
+ break;
+ }
rect = new PDFRectangle (floor (x1 * scale),
floor (y1 * scale),
rect = new PDFRectangle(floor(x1 * scale), floor(y1 * scale), ceil(x2 * scale), ceil(y2 * scale));
list->push_back(rect);
@@ -4499,19 +4531,56 @@ void TextSelectionPainter::visitLine (TextLine *line,
{
double x1, y1, x2, y2, margin;
- margin = (line->yMax - line->yMin) / 8;
- x1 = floor (line->edge[edge_begin]);
- y1 = floor (line->yMin - margin);
- x2 = ceil (line->edge[edge_end]);
- y2 = ceil (line->yMax + margin);
- x1 = floor(line->edge[edge_begin]);
- y1 = floor(line->yMin - margin);
- x2 = ceil(line->edge[edge_end]);
- y2 = ceil(line->yMax + margin);
+ switch (line->rot) {
+ default:
+ case 0:
@ -119,29 +119,29 @@ index 7c2ca78..e93908c 100644
- ctm.transform(line->edge[edge_begin], line->yMin - margin, &x1, &y1);
- ctm.transform(line->edge[edge_end], line->yMax + margin, &x2, &y2);
+ if (x1 < x2) {
+ x1 = floor (x1);
+ x2 = ceil (x2);
+ x1 = floor(x1);
+ x2 = ceil(x2);
+ } else {
+ x1 = ceil (x1);
+ x2 = floor (x2);
+ x1 = ceil(x1);
+ x2 = floor(x2);
+ }
- x1 = floor (x1);
- y1 = floor (y1);
- x2 = ceil (x2);
- y2 = ceil (y2);
- x1 = floor(x1);
- y1 = floor(y1);
- x2 = ceil(x2);
- y2 = ceil(y2);
+ if (y1 < y2) {
+ y1 = floor (y1);
+ y2 = ceil (y2);
+ y1 = floor(y1);
+ y2 = ceil(y2);
+ } else {
+ y1 = ceil (y1);
+ y2 = floor (y2);
+ y1 = ceil(y1);
+ y2 = floor(y2);
+ }
ictm.transform(x1, y1, &x1, &y1);
ictm.transform(x2, y2, &x2, &y2);
@@ -4589,17 +4658,27 @@ void TextWord::visitSelection(TextSelectionVisitor *visitor,
SelectionStyle style)
@@ -4589,17 +4658,26 @@ void TextWord::visitSelection(TextSelectionVisitor *visitor,
void TextWord::visitSelection(TextSelectionVisitor *visitor, const PDFRectangle *selection, SelectionStyle style)
{
int i, begin, end;
- double mid;
@ -164,8 +164,7 @@ index 7c2ca78..e93908c 100644
- begin = i;
- if (mid < selection->x1 || mid < selection->x2)
- end = i + 1;
+ if (XBetweenAB (mid, s1, s2))
+ {
+ if (XBetweenAB (mid, s1, s2)) {
+ if (i < begin)
+ begin = i;
+
@ -174,7 +173,7 @@ index 7c2ca78..e93908c 100644
}
/* Skip empty selection. */
@@ -4615,30 +4694,41 @@ void TextLine::visitSelection(TextSelectionVisitor *visitor,
@@ -4615,26 +4694,41 @@ void TextLine::visitSelection(TextSelectionVisitor *visitor,
TextWord *p, *begin, *end, *current;
int i, edge_begin, edge_end;
PDFRectangle child_selection;
@ -201,34 +200,30 @@ index 7c2ca78..e93908c 100644
+ }
+
if (blk->page->primaryLR) {
- if ((selection->x1 < p->xMax) ||
- (selection->x2 < p->xMax))
- if ((selection->x1 < p->xMax) || (selection->x2 < p->xMax))
- if (begin == nullptr)
- begin = p;
+ if (((s1 < p_max) || (s2 < p_max)) && begin == nullptr)
+ begin = p;
- if (((selection->x1 > p->xMin) ||
- (selection->x2 > p->xMin)) && (begin != nullptr)) {
- if (((selection->x1 > p->xMin) || (selection->x2 > p->xMin)) && (begin != nullptr)) {
+ if (((s1 > p_min) || (s2 > p_min)) && begin != nullptr) {
end = p->next;
current = p;
}
} else {
- if ((selection->x1 > p->xMin) ||
- (selection->x2 > p->xMin))
- if ((selection->x1 > p->xMin) || (selection->x2 > p->xMin))
- if (begin == nullptr)
- begin = p;
+ if (((s1 > p_min) || (s2 > p_min)) && begin == nullptr)
+ begin = p;
- if (((selection->x1 < p->xMax) ||
- (selection->x2 < p->xMax)) && (begin != nullptr)) {
- if (((selection->x1 < p->xMax) || (selection->x2 < p->xMax)) && (begin != nullptr)) {
+ if (((s1 < p_max) || (s2 < p_max)) && begin != nullptr) {
end = p->next;
current = p;
}
@@ -4650,23 +4740,42 @@ void TextLine::visitSelection(TextSelectionVisitor *visitor,
@@ -4650,23 +4740,41 @@ void TextLine::visitSelection(TextSelectionVisitor *visitor,
child_selection = *selection;
if (style == selectionStyleWord) {
@ -270,8 +265,7 @@ index 7c2ca78..e93908c 100644
- edge_begin = i;
- if (mid < child_selection.x2 || mid < child_selection.x1)
- edge_end = i + 1;
+ if (XBetweenAB (mid, s1, s2))
+ {
+ if (XBetweenAB (mid, s1, s2)) {
+ if (i < edge_begin)
+ edge_begin = i;
+

View File

@ -1,8 +0,0 @@
--- poppler-0.62.0/make-glib-api-docs
+++ poppler-0.62.0/make-glib-api-docs
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright (C) 2017 Carlos Garcia Campos <carlosgc@gnome.org>
#

View File

@ -1,26 +0,0 @@
From 68ef84e5968a4249c2162b839ca6d7975048a557 Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <aacid@kde.org>
Date: Mon, 15 Jul 2019 23:24:22 +0200
Subject: [PATCH] JPXStream::init: ignore dict Length if clearly broken
Fixes issue #805
---
poppler/JPEG2000Stream.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/poppler/JPEG2000Stream.cc b/poppler/JPEG2000Stream.cc
index 0eea3a2d..8e6902f4 100644
--- a/poppler/JPEG2000Stream.cc
+++ b/poppler/JPEG2000Stream.cc
@@ -219,7 +219,7 @@ void JPXStream::init()
}
int bufSize = BUFFER_INITIAL_SIZE;
- if (oLen.isInt()) bufSize = oLen.getInt();
+ if (oLen.isInt() && oLen.getInt() > 0) bufSize = oLen.getInt();
GBool indexed = gFalse;
if (cspace.isArray() && cspace.arrayGetLength() > 0) {
--
2.21.0

View File

@ -1,372 +0,0 @@
From 64aa150a92ccb082db6a3383fa734a6ac91cf1bf Mon Sep 17 00:00:00 2001
From: Marek Kasik <mkasik@redhat.com>
Date: Tue, 30 Apr 2019 18:47:44 +0200
Subject: [PATCH] PSOutputDev: Don't read outside of image buffer
Check whether input image is RGB or BGR to not treat
it as CMYK in those cases in PSOutputDev::checkPageSlice().
Fixes #751
---
poppler/PSOutputDev.cc | 248 ++++++++++++++++++++++++++++++++---------
1 file changed, 196 insertions(+), 52 deletions(-)
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 0d201835..155a8cbe 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -3385,13 +3385,21 @@ GBool PSOutputDev::checkPageSlice(Page *
}
break;
case psLevel1Sep:
+ GfxColor inputColor;
+ GfxCMYK cmyk;
+ unsigned char cmykColor[4];
+ GfxDeviceRGBColorSpace *rgbCS;
+ SplashColorMode colorMode;
+
+ colorMode = bitmap->getMode();
+
p = bitmap->getDataPtr();
// Check for an all gray image
if (getOptimizeColorSpace()) {
isGray = gTrue;
for (y = 0; y < h; ++y) {
for (x = 0; x < w; ++x) {
- if (p[4*x] != p[4*x + 1] || p[4*x] != p[4*x + 2]) {
+ if (p[numComps*x] != p[numComps*x + 1] || p[numComps*x] != p[numComps*x + 2]) {
isGray = gFalse;
y = h;
break;
@@ -3411,7 +3419,9 @@ GBool PSOutputDev::checkPageSlice(Page *
col[0] = col[1] = col[2] = col[3] = 0;
if (isGray) {
int g;
- if ((psProcessBlack & processColors) == 0) {
+ if ((psProcessBlack & processColors) == 0 &&
+ colorMode != splashModeRGB8 &&
+ colorMode != splashModeBGR8) {
// Check if the image uses black
for (y = 0; y < h; ++y) {
for (x = 0; x < w; ++x) {
@@ -3425,59 +3435,23 @@ GBool PSOutputDev::checkPageSlice(Page *
}
p = bitmap->getDataPtr() + (h - 1) * bitmap->getRowSize();
}
- for (y = 0; y < h; ++y) {
- if (useBinary) {
- // Binary gray image
- for (x = 0; x < w; ++x) {
- g = p[4*x] + p[4*x + 3];
- g = 255 - g;
- if (g < 0) g = 0;
- hexBuf[i++] = (Guchar) g;
- if (i >= 64) {
- writePSBuf(hexBuf, i);
- i = 0;
- }
- }
- } else {
- // Hex gray image
- for (x = 0; x < w; ++x) {
- g = p[4*x] + p[4*x + 3];
- g = 255 - g;
- if (g < 0) g = 0;
- digit = g / 16;
- hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
- digit = g % 16;
- hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
- if (i >= 64) {
- hexBuf[i++] = '\n';
- writePSBuf(hexBuf, i);
- i = 0;
- }
- }
- }
- p -= bitmap->getRowSize();
- }
- } else if (((psProcessCyan | psProcessMagenta | psProcessYellow | psProcessBlack) & ~processColors) != 0) {
- // Color image, need to check color flags for each dot
- for (y = 0; y < h; ++y) {
- for (comp = 0; comp < 4; ++comp) {
+ if (colorMode == splashModeRGB8 || colorMode != splashModeBGR8) {
+ for (y = 0; y < h; ++y) {
if (useBinary) {
- // Binary color image
+ // Binary gray image
for (x = 0; x < w; ++x) {
- col[comp] |= p[4*x + comp];
- hexBuf[i++] = p[4*x + comp];
+ hexBuf[i++] = (Guchar) p[3*x];
if (i >= 64) {
writePSBuf(hexBuf, i);
i = 0;
}
}
} else {
- // Gray color image
+ // Hex gray image
for (x = 0; x < w; ++x) {
- col[comp] |= p[4*x + comp];
- digit = p[4*x + comp] / 16;
+ digit = p[3*x] / 16;
hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
- digit = p[4*x + comp] % 16;
+ digit = p[3*x] % 16;
hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
if (i >= 64) {
hexBuf[i++] = '\n';
@@ -3485,29 +3459,31 @@ GBool PSOutputDev::checkPageSlice(Page *
i = 0;
}
}
- }
+ }
}
- p -= bitmap->getRowSize();
- }
- } else {
- // Color image, do not need to check color flags
- for (y = 0; y < h; ++y) {
- for (comp = 0; comp < 4; ++comp) {
+ } else {
+ for (y = 0; y < h; ++y) {
if (useBinary) {
- // Binary color image
+ // Binary gray image
for (x = 0; x < w; ++x) {
- hexBuf[i++] = p[4*x + comp];
+ g = p[4*x] + p[4*x + 3];
+ g = 255 - g;
+ if (g < 0) g = 0;
+ hexBuf[i++] = (Guchar) g;
if (i >= 64) {
writePSBuf(hexBuf, i);
i = 0;
}
}
} else {
- // Hex color image
+ // Hex gray image
for (x = 0; x < w; ++x) {
- digit = p[4*x + comp] / 16;
+ g = p[4*x] + p[4*x + 3];
+ g = 255 - g;
+ if (g < 0) g = 0;
+ digit = g / 16;
hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
- digit = p[4*x + comp] % 16;
+ digit = g % 16;
hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
if (i >= 64) {
hexBuf[i++] = '\n';
@@ -3515,9 +3491,207 @@ GBool PSOutputDev::checkPageSlice(Page *
i = 0;
}
}
- }
+ }
}
- p -= bitmap->getRowSize();
+ }
+ p -= bitmap->getRowSize();
+ } else if (((psProcessCyan | psProcessMagenta | psProcessYellow | psProcessBlack) & ~processColors) != 0) {
+ // Color image, need to check color flags for each dot
+ switch (colorMode) {
+ case splashModeRGB8:
+ case splashModeBGR8:
+ rgbCS = new GfxDeviceRGBColorSpace();
+ for (y = 0; y < h; ++y) {
+ for (comp = 0; comp < 4; ++comp) {
+ if (useBinary) {
+ // Binary color image
+ for (x = 0; x < w; ++x) {
+ if (likely(colorMode == splashModeRGB8)) {
+ inputColor.c[0] = byteToCol(p[3*x + 0]);
+ inputColor.c[1] = byteToCol(p[3*x + 1]);
+ inputColor.c[2] = byteToCol(p[3*x + 2]);
+ } else {
+ inputColor.c[0] = byteToCol(p[3*x + 2]);
+ inputColor.c[1] = byteToCol(p[3*x + 1]);
+ inputColor.c[2] = byteToCol(p[3*x + 0]);
+ }
+ rgbCS->getCMYK(&inputColor, &cmyk);
+ cmykColor[0] = colToByte(cmyk.c);
+ cmykColor[1] = colToByte(cmyk.m);
+ cmykColor[2] = colToByte(cmyk.y);
+ cmykColor[3] = colToByte(cmyk.k);
+
+ col[comp] |= cmykColor[comp];
+ hexBuf[i++] = cmykColor[comp];
+ if (i >= 64) {
+ writePSBuf(hexBuf, i);
+ i = 0;
+ }
+ }
+ } else {
+ // Gray color image
+ for (x = 0; x < w; ++x) {
+ if (likely(colorMode == splashModeRGB8)) {
+ inputColor.c[0] = byteToCol(p[3*x + 0]);
+ inputColor.c[1] = byteToCol(p[3*x + 1]);
+ inputColor.c[2] = byteToCol(p[3*x + 2]);
+ } else {
+ inputColor.c[0] = byteToCol(p[3*x + 2]);
+ inputColor.c[1] = byteToCol(p[3*x + 1]);
+ inputColor.c[2] = byteToCol(p[3*x + 0]);
+ }
+ rgbCS->getCMYK(&inputColor, &cmyk);
+ cmykColor[0] = colToByte(cmyk.c);
+ cmykColor[1] = colToByte(cmyk.m);
+ cmykColor[2] = colToByte(cmyk.y);
+ cmykColor[3] = colToByte(cmyk.k);
+
+ col[comp] |= cmykColor[comp];
+ digit = cmykColor[comp] / 16;
+ hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
+ digit = cmykColor[comp] % 16;
+ hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
+ if (i >= 64) {
+ hexBuf[i++] = '\n';
+ writePSBuf(hexBuf, i);
+ i = 0;
+ }
+ }
+ }
+ }
+ p -= bitmap->getRowSize();
+ }
+ delete rgbCS;
+ break;
+ default:
+ for (y = 0; y < h; ++y) {
+ for (comp = 0; comp < 4; ++comp) {
+ if (useBinary) {
+ // Binary color image
+ for (x = 0; x < w; ++x) {
+ col[comp] |= p[4*x + comp];
+ hexBuf[i++] = p[4*x + comp];
+ if (i >= 64) {
+ writePSBuf(hexBuf, i);
+ i = 0;
+ }
+ }
+ } else {
+ // Gray color image
+ for (x = 0; x < w; ++x) {
+ col[comp] |= p[4*x + comp];
+ digit = p[4*x + comp] / 16;
+ hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
+ digit = p[4*x + comp] % 16;
+ hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
+ if (i >= 64) {
+ hexBuf[i++] = '\n';
+ writePSBuf(hexBuf, i);
+ i = 0;
+ }
+ }
+ }
+ }
+ p -= bitmap->getRowSize();
+ }
+ break;
+ }
+ } else {
+ // Color image, do not need to check color flags
+ switch (colorMode) {
+ case splashModeRGB8:
+ case splashModeBGR8:
+ rgbCS = new GfxDeviceRGBColorSpace();
+ for (y = 0; y < h; ++y) {
+ for (comp = 0; comp < 4; ++comp) {
+ if (useBinary) {
+ // Binary color image
+ for (x = 0; x < w; ++x) {
+ if (likely(colorMode == splashModeRGB8)) {
+ inputColor.c[0] = byteToCol(p[3*x + 0]);
+ inputColor.c[1] = byteToCol(p[3*x + 1]);
+ inputColor.c[2] = byteToCol(p[3*x + 2]);
+ } else {
+ inputColor.c[0] = byteToCol(p[3*x + 2]);
+ inputColor.c[1] = byteToCol(p[3*x + 1]);
+ inputColor.c[2] = byteToCol(p[3*x + 0]);
+ }
+ rgbCS->getCMYK(&inputColor, &cmyk);
+ cmykColor[0] = colToByte(cmyk.c);
+ cmykColor[1] = colToByte(cmyk.m);
+ cmykColor[2] = colToByte(cmyk.y);
+ cmykColor[3] = colToByte(cmyk.k);
+
+ hexBuf[i++] = cmykColor[comp];
+ if (i >= 64) {
+ writePSBuf(hexBuf, i);
+ i = 0;
+ }
+ }
+ } else {
+ // Hex color image
+ for (x = 0; x < w; ++x) {
+ if (likely(colorMode == splashModeRGB8)) {
+ inputColor.c[0] = byteToCol(p[3*x + 0]);
+ inputColor.c[1] = byteToCol(p[3*x + 1]);
+ inputColor.c[2] = byteToCol(p[3*x + 2]);
+ } else {
+ inputColor.c[0] = byteToCol(p[3*x + 2]);
+ inputColor.c[1] = byteToCol(p[3*x + 1]);
+ inputColor.c[2] = byteToCol(p[3*x + 0]);
+ }
+ rgbCS->getCMYK(&inputColor, &cmyk);
+ cmykColor[0] = colToByte(cmyk.c);
+ cmykColor[1] = colToByte(cmyk.m);
+ cmykColor[2] = colToByte(cmyk.y);
+ cmykColor[3] = colToByte(cmyk.k);
+
+ digit = cmykColor[comp] / 16;
+ hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
+ digit = cmykColor[comp] % 16;
+ hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
+ if (i >= 64) {
+ hexBuf[i++] = '\n';
+ writePSBuf(hexBuf, i);
+ i = 0;
+ }
+ }
+ }
+ }
+ p -= bitmap->getRowSize();
+ }
+ delete rgbCS;
+ break;
+ default:
+ for (y = 0; y < h; ++y) {
+ for (comp = 0; comp < 4; ++comp) {
+ if (useBinary) {
+ // Binary color image
+ for (x = 0; x < w; ++x) {
+ hexBuf[i++] = p[4*x + comp];
+ if (i >= 64) {
+ writePSBuf(hexBuf, i);
+ i = 0;
+ }
+ }
+ } else {
+ // Hex color image
+ for (x = 0; x < w; ++x) {
+ digit = p[4*x + comp] / 16;
+ hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
+ digit = p[4*x + comp] % 16;
+ hexBuf[i++] = digit + ((digit >= 10)? 'a' - 10: '0');
+ if (i >= 64) {
+ hexBuf[i++] = '\n';
+ writePSBuf(hexBuf, i);
+ i = 0;
+ }
+ }
+ }
+ }
+ p -= bitmap->getRowSize();
+ }
+ break;
}
}
if (i != 0) {

View File

@ -1,29 +0,0 @@
--- a/utils/pdfunite.cc
+++ b/utils/pdfunite.cc
@@ -165,7 +165,9 @@ int main (int argc, char *argv[])
for (i = 1; i < argc - 1; i++) {
GooString *gfileName = new GooString(argv[i]);
PDFDoc *doc = new PDFDoc(gfileName, nullptr, nullptr, nullptr);
- if (doc->isOk() && !doc->isEncrypted()) {
+ if (doc->isOk() && !doc->isEncrypted() &&
+ (doc->getCatalog()->getPageRef(1) || gTrue) &&
+ doc->getXRef()->getCatalog().isDict()) {
docs.push_back(doc);
if (doc->getPDFMajorVersion() > majorVersion) {
majorVersion = doc->getPDFMajorVersion();
@@ -176,8 +177,13 @@ int main (int argc, char *argv[])
}
}
} else if (doc->isOk()) {
- error(errUnimplemented, -1, "Could not merge encrypted files ('{0:s}')", argv[i]);
- return -1;
+ if (doc->isEncrypted()) {
+ error(errUnimplemented, -1, "Could not merge encrypted files ('{0:s}')", argv[i]);
+ return -1;
+ } else if (!doc->getXRef()->getCatalog().isDict()) {
+ error(errSyntaxError, -1, "XRef's Catalog is not a dictionary ('{0:s}')", argv[i]);
+ return -1;
+ }
} else {
error(errSyntaxError, -1, "Could not merge damaged documents ('{0:s}')", argv[i]);
return -1;

View File

@ -1,35 +0,0 @@
From d716e636231c8d636bf2139896d817b66fe6d510 Mon Sep 17 00:00:00 2001
From: Marek Kasik <mkasik@redhat.com>
Date: Thu, 21 Mar 2019 13:15:37 +0100
Subject: [PATCH 1/2] cairo: Compute correct coverage values for box filter
Use double precision for computation of coverage
of the left most pixel in the box filter.
Issue #736
---
poppler/CairoRescaleBox.cc | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/poppler/CairoRescaleBox.cc b/poppler/CairoRescaleBox.cc
index b8371a5b..d7615010 100644
--- a/poppler/CairoRescaleBox.cc
+++ b/poppler/CairoRescaleBox.cc
@@ -226,10 +227,10 @@ static int compute_coverage (int coverage[], int src_length, int dest_length)
/* I have a proof of this, which this margin is too narrow to contain */
for (i=0; i<dest_length; i++)
{
- float left_side = i*scale;
- float right_side = (i+1)*scale;
- float right_fract = right_side - floor (right_side);
- float left_fract = ceil (left_side) - left_side;
+ double left_side = i*scale;
+ double right_side = (i+1)*scale;
+ double right_fract = right_side - floor (right_side);
+ double left_fract = ceil (left_side) - left_side;
int overage;
/* find out how many source pixels will be used to fill the box */
int count = floor (right_side) - ceil (left_side);
--
2.20.1

View File

@ -1,21 +1,21 @@
--- poppler/glib/poppler-document.cc
+++ poppler/glib/poppler-document.cc
@@ -2872,6 +2872,7 @@ poppler_document_get_form_field (Poppler
@@ -3405,6 +3405,7 @@ PopplerFormField *poppler_document_get_f
unsigned fieldNum;
FormPageWidgets *widgets;
FormWidget *field;
+ PopplerFormField *formField;
FormWidget::decodeID (id, &pageNum, &fieldNum);
FormWidget::decodeID(id, &pageNum, &fieldNum);
@@ -2884,8 +2885,14 @@ poppler_document_get_form_field (Poppler
@@ -3417,8 +3418,14 @@ PopplerFormField *poppler_document_get_f
return nullptr;
field = widgets->getWidget (fieldNum);
field = widgets->getWidget(fieldNum);
- if (field)
- return _poppler_form_field_new (document, field);
- return _poppler_form_field_new(document, field);
+ if (field) {
+ formField = _poppler_form_field_new (document, field);
+ formField = _poppler_form_field_new(document, field);
+ delete widgets;
+
+ return formField;
@ -27,7 +27,7 @@
}
--- poppler/poppler/CairoOutputDev.cc
+++ poppler/poppler/CairoOutputDev.cc
@@ -3010,8 +3010,10 @@ void CairoOutputDev::setMimeData(GfxStat
@@ -2921,8 +2921,10 @@ void CairoOutputDev::setMimeData(GfxStat
// colorspace in stream dict may be different from colorspace in jpx
// data
@ -39,55 +39,25 @@
// only embed mime data for gray, rgb, and cmyk colorspaces.
if (colorSpace) {
--- poppler/poppler/Link.cc
+++ poppler/poppler/Link.cc
@@ -193,6 +193,7 @@ LinkAction *LinkAction::parseAction(cons
const Ref ref = obj3Ref.getRef();
if (!seenNextActions->insert(ref.num).second) {
error(errSyntaxWarning, -1, "parseAction: Circular next actions detected in array.");
+ delete actionList;
return action;
}
}
--- poppler/poppler/SplashOutputDev.cc
+++ poppler/poppler/SplashOutputDev.cc
@@ -2207,6 +2207,8 @@ reload:
error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
gfxFont->getName() ? gfxFont->getName()->getCString()
: "(unnamed)");
+ if (fontsrc && fontsrc->isFile)
+ fontsrc->unref();
goto err2;
}
codeToGID = ((GfxCIDFont *)gfxFont)->getCodeToGIDMap(ff, &n);
@@ -2225,6 +2227,8 @@ reload:
break;
default:
// this shouldn't happen
+ if (fontsrc && fontsrc->isFile)
+ fontsrc->unref();
goto err2;
}
fontFile->doAdjustMatrix = doAdjustFontMatrix;
--- poppler/poppler/TextOutputDev.cc
+++ poppler/poppler/TextOutputDev.cc
@@ -1526,7 +1526,6 @@ TextBlock::~TextBlock() {
}
@@ -1619,7 +1619,6 @@ TextBlock::~TextBlock()
void TextBlock::addWord(TextWord *word) {
void TextBlock::addWord(TextWord *word)
{
- pool->addWord(word);
if (xMin > xMax) {
xMin = word->xMin;
xMax = word->xMax;
@@ -1546,6 +1545,7 @@ void TextBlock::addWord(TextWord *word)
@@ -1639,6 +1638,7 @@ void TextBlock::addWord(TextWord *word)
yMax = word->yMax;
}
}
+ pool->addWord(word);
}
void TextBlock::coalesce(UnicodeMap *uMap, double fixedPitch) {
@@ -2999,11 +2999,13 @@ void TextPage::coalesce(GBool physLayout
void TextBlock::coalesce(const UnicodeMap *uMap, double fixedPitch)
@@ -3064,11 +3064,13 @@ void TextPage::coalesce(bool physLayout,
word0 = pool->getPool(startBaseIdx);
pool->setPool(startBaseIdx, word0->next);
word0->next = nullptr;
@ -103,29 +73,29 @@
colSpace1 = minColSpacing1 * fontSize;
colSpace2 = minColSpacing2 * fontSize;
lineSpace = maxLineSpacingDelta * fontSize;
@@ -3037,9 +3039,9 @@ void TextPage::coalesce(GBool physLayout
@@ -3095,9 +3097,9 @@ void TextPage::coalesce(bool physLayout,
}
word1 = word1->next;
word2->next = nullptr;
+ newMinBase = word2->base;
blk->addWord(word2);
found = gTrue;
found = true;
- newMinBase = word2->base;
} else {
word0 = word1;
word1 = word1->next;
@@ -3072,9 +3074,9 @@ void TextPage::coalesce(GBool physLayout
@@ -3123,9 +3125,9 @@ void TextPage::coalesce(bool physLayout,
}
word1 = word1->next;
word2->next = nullptr;
+ newMaxBase = word2->base;
blk->addWord(word2);
found = gTrue;
found = true;
- newMaxBase = word2->base;
} else {
word0 = word1;
word1 = word1->next;
@@ -3171,12 +3173,12 @@ void TextPage::coalesce(GBool physLayout
@@ -3198,12 +3200,12 @@ void TextPage::coalesce(bool physLayout,
}
word1 = word1->next;
word2->next = nullptr;
@ -136,10 +106,10 @@
maxBase = word2->base;
}
+ blk->addWord(word2);
found = gTrue;
found = true;
break;
} else {
@@ -3235,12 +3237,12 @@ void TextPage::coalesce(GBool physLayout
@@ -3246,12 +3248,12 @@ void TextPage::coalesce(bool physLayout,
}
word1 = word1->next;
word2->next = nullptr;
@ -150,64 +120,12 @@
maxBase = word2->base;
}
+ blk->addWord(word2);
found = gTrue;
found = true;
break;
} else {
@@ -4509,7 +4511,7 @@ GooList **TextSelectionDumper::takeWordL
class TextSelectionSizer : public TextSelectionVisitor {
public:
TextSelectionSizer(TextPage *page, double scale);
- ~TextSelectionSizer() { }
+ ~TextSelectionSizer();
void visitBlock (TextBlock *block,
TextLine *begin,
@@ -4526,7 +4526,7 @@ public:
void visitWord (TextWord *word, int begin, int end,
PDFRectangle *selection) override { };
- GooList *getRegion () { return list; }
+ GooList *getRegion ();
private:
GooList *list;
@@ -4538,6 +4540,11 @@ TextSelectionSizer::TextSelectionSizer(T
list = new GooList();
}
+TextSelectionSizer::~TextSelectionSizer()
+{
+ deleteGooList(list, PDFRectangle);
+}
+
void TextSelectionSizer::visitLine (TextLine *line,
TextWord *begin,
TextWord *end,
@@ -4594,6 +4594,21 @@ void TextSelectionSizer::visitLine (Text
list->append (rect);
}
+GooList *TextSelectionSizer::getRegion () {
+ GooList *recList;
+ int i;
+
+ recList = new GooList();
+
+ for (i = 0; i < list->getLength(); i++) {
+ PDFRectangle *selection_rect = (PDFRectangle *) list->get(i);
+
+ recList->append (new PDFRectangle(selection_rect->x1, selection_rect->y1, selection_rect->x2, selection_rect->y2));
+ }
+
+ return recList;
+}
+
class TextSelectionPainter : public TextSelectionVisitor {
public:
--- poppler/poppler/XRef.cc
+++ poppler/poppler/XRef.cc
@@ -456,6 +456,7 @@ int XRef::reserve(int newSize)
@@ -402,6 +402,7 @@ int XRef::reserve(int newSize)
void *p = greallocn_checkoverflow(entries, realNewSize, sizeof(XRefEntry));
if (p == nullptr) {
@ -215,7 +133,7 @@
return 0;
}
@@ -877,7 +878,6 @@ GBool XRef::constructXRef(GBool *wasReco
@@ -835,7 +836,6 @@ bool XRef::constructXRef(bool *wasRecons
int offset = 0;
resize(0); // free entries properly
@ -223,97 +141,31 @@
capacity = 0;
size = 0;
entries = nullptr;
--- poppler/qt5/src/ArthurOutputDev.cc
+++ poppler/qt5/src/ArthurOutputDev.cc
@@ -703,7 +703,11 @@ void ArthurOutputDev::updateFont(GfxStat
else
ff = FoFiTrueType::make(tmpBuf, tmpBufLen);
if (! ff)
+ {
+ if (fontsrc && fontsrc->isFile)
+ fontsrc->unref();
goto err2;
+ }
codeToGID = ((GfxCIDFont *)gfxFont)->getCodeToGIDMap(ff, &n);
delete ff;
}
@@ -719,6 +723,8 @@ void ArthurOutputDev::updateFont(GfxStat
break;
default:
// this shouldn't happen
+ if (fontsrc && fontsrc->isFile)
+ fontsrc->unref();
goto err2;
}
}
@@ -738,6 +744,8 @@ void ArthurOutputDev::updateFont(GfxStat
return;
err2:
+ if (fontsrc && !fontsrc->isFile)
+ fontsrc->unref();
delete id;
#endif
}
--- poppler/qt5/src/poppler-page.cc
+++ poppler/qt5/src/poppler-page.cc
@@ -782,6 +782,7 @@ QList<TextBox*> Page::textList(Rotation
if (!word_list || (shouldAbortExtractionCallback && shouldAbortExtractionCallback(closure))) {
delete output_dev;
+ delete word_list;
return output_list;
}
--- poppler/test/pdf-inspector.cc
+++ poppler/test/pdf-inspector.cc
@@ -46,6 +46,7 @@ class PdfInspector {
@@ -43,6 +43,7 @@ class PdfInspector
{
public:
PdfInspector();
+ ~PdfInspector();
PdfInspector(void);
+ ~PdfInspector(void);
void set_file_name (const char *file_name);
void load (const char *file_name);
@@ -136,6 +137,11 @@ PdfInspector::PdfInspector(void)
// set up initial widgets
load (nullptr);
void set_file_name(const char *file_name);
void load(const char *file_name);
@@ -108,6 +109,11 @@ PdfInspector::PdfInspector()
load(nullptr);
}
+
+PdfInspector::~PdfInspector(void)
+{
+ delete output;
+}
void
PdfInspector::set_file_name(const char *file_name)
--- poppler/test/perf-test.cc
+++ poppler/test/perf-test.cc
@@ -1053,6 +1053,7 @@ static void ParseCommandLine(int argc, c
++i;
if (i == argc)
PrintUsageAndExit(argc, argv);
+ free(gOutFileName);
gOutFileName = str_dup(argv[i]);
} else if (str_ieq(arg, PREVIEW_ARG)) {
gfPreview = true;
+
void PdfInspector::set_file_name(const char *file_name)
{
GtkWidget *widget;
--- poppler/utils/HtmlOutputDev.cc
+++ poppler/utils/HtmlOutputDev.cc
@@ -920,10 +920,11 @@ void HtmlPage::dumpComplex(FILE *file, i
fputs("</div>\n", pageFile);
- if( !noframes )
- {
+ if( !noframes ){
fputs("</body>\n</html>\n",pageFile);
fclose(pageFile);
+ } else if (pageFile != nullptr && pageFile != file){
+ fclose(pageFile);
}
}
@@ -1376,6 +1377,7 @@ void HtmlOutputDev::drawPngImage(GfxStat
@@ -1337,6 +1337,7 @@ void HtmlOutputDev::drawPngImage(GfxStat
// TODO can we calculate the resolution of the image?
if (!writer->init(f1, width, height, 72, 72)) {
error(errInternal, -1, "Can't init PNG for image '{0:t}'", fName);
@ -321,42 +173,9 @@
delete writer;
fclose(f1);
return;
@@ -1417,6 +1419,7 @@ void HtmlOutputDev::drawPngImage(GfxStat
if (!writer->writeRow(row_pointer)) {
error(errIO, -1, "Failed to write into PNG '{0:t}'", fName);
+ delete fName;
delete writer;
delete imgStr;
fclose(f1);
@@ -1455,6 +1458,7 @@ void HtmlOutputDev::drawPngImage(GfxStat
if (!writer->writeRow( &png_row ))
{
error(errIO, -1, "Failed to write into PNG '{0:t}'", fName);
+ delete fName;
delete writer;
fclose(f1);
gfree(png_row);
@@ -1472,6 +1476,8 @@ void HtmlOutputDev::drawPngImage(GfxStat
fclose(f1);
pages->addImage(fName, state);
+
+ delete fName;
#else
return;
#endif
@@ -1617,6 +1623,7 @@ GooString* HtmlOutputDev::getLinkDest(An
}
else
{
+ delete file;
return new GooString();
}
}
--- poppler/utils/pdftotext.cc
+++ poppler/utils/pdftotext.cc
@@ -356,6 +356,7 @@ int main(int argc, char *argv[]) {
@@ -329,6 +329,7 @@ int main(int argc, char *argv[])
fputs("<pre>\n", f);
if (f != stdout) {
fclose(f);
@ -364,7 +183,7 @@
}
}
}
@@ -372,8 +373,9 @@ int main(int argc, char *argv[]) {
@@ -348,8 +349,9 @@ int main(int argc, char *argv[])
printWordBBox(f, doc, textOut, firstPage, lastPage);
}
}
@ -374,9 +193,9 @@
+ f = nullptr;
}
} else {
textOut = new TextOutputDev(textFileName->getCString(),
@@ -413,7 +415,7 @@ int main(int argc, char *argv[]) {
if (!bbox) fputs("</pre>\n", f);
textOut = new TextOutputDev(textFileName->c_str(), physLayout, fixedPitch, rawOrder, htmlMeta, discardDiag);
@@ -390,7 +392,7 @@ int main(int argc, char *argv[])
fputs("</pre>\n", f);
fputs("</body>\n", f);
fputs("</html>\n", f);
- if (f != stdout) {

View File

@ -1,61 +0,0 @@
From 3d35d209c19c1d3b09b794a0c863ba5de44a9c0a Mon Sep 17 00:00:00 2001
From: Marek Kasik <mkasik@redhat.com>
Date: Mon, 29 Oct 2018 17:44:47 +0100
Subject: [PATCH] Avoid cycles in PDF parsing
Mark objects being processed in Parser::makeStream() as being processed
and check the mark when entering this method to avoid processing
of the same object recursively.
---
poppler/Parser.cc | 15 +++++++++++++++
poppler/XRef.h | 1 +
2 files changed, 16 insertions(+)
diff --git a/poppler/Parser.cc b/poppler/Parser.cc
index bd4845ab..8f48efbe 100644
--- a/poppler/Parser.cc
+++ b/poppler/Parser.cc
@@ -197,6 +197,18 @@ Stream *Parser::makeStream(Object &&dict, Guchar *fileKey,
Stream *str;
Goffset length;
Goffset pos, endPos;
+ XRefEntry *entry = nullptr;
+
+ if (xref && (entry = xref->getEntry(objNum, false))) {
+ if (!entry->getFlag(XRefEntry::Parsing) ||
+ (objNum == 0 && objGen == 0)) {
+ entry->setFlag(XRefEntry::Parsing, true);
+ } else {
+ error(errSyntaxError, getPos(),
+ "Object '{0:d} {1:d} obj' is being already parsed", objNum, objGen);
+ return nullptr;
+ }
+ }
// get stream start position
lexer->skipToNextLine();
@@ -278,6 +290,9 @@ Stream *Parser::makeStream(Object &&dict, Guchar *fileKey,
// get filters
str = str->addFilters(str->getDict(), recursion);
+ if (entry)
+ entry->setFlag(XRefEntry::Parsing, false);
+
return str;
}
diff --git a/poppler/XRef.h b/poppler/XRef.h
index 11ee5e03..2eb2f9fd 100644
--- a/poppler/XRef.h
+++ b/poppler/XRef.h
@@ -65,6 +65,7 @@ struct XRefEntry {
enum Flag {
// Regular flags
Updated, // Entry was modified
+ Parsing, // Entry is currently being parsed
// Special flags -- available only after xref->scanSpecialFlags() is run
Unencrypted, // Entry is stored in unencrypted form (meaningless in unencrypted documents)
--
2.19.1

View File

@ -1,63 +0,0 @@
From e07c8b4784234383cb5ddcf1133ea91a772506e2 Mon Sep 17 00:00:00 2001
From: Adam Reichold <adam.reichold@t-online.de>
Date: Tue, 1 Jan 2019 10:54:40 +0100
Subject: [PATCH] Avoid global display profile state becoming an uncontrolled
memory leak by enforcing single initialization. Closes #654
---
poppler/GfxState.cc | 9 +++++++++
qt5/src/poppler-qt5.h | 4 ++++
2 files changed, 13 insertions(+)
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 87b7ce03..4e3ccbfd 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -226,6 +226,10 @@ static unsigned int getCMSNChannels(cmsColorSpaceSignature cs);
static cmsHPROFILE loadColorProfile(const char *fileName);
void GfxColorSpace::setDisplayProfile(void *displayProfileA) {
+ if (displayProfile != nullptr) {
+ error(errInternal, -1, "The display color profile can only be set once before any rendering is done.");
+ return;
+ }
displayProfile = displayProfileA;
if (displayProfile != nullptr) {
cmsHTRANSFORM transform;
@@ -249,6 +253,11 @@ void GfxColorSpace::setDisplayProfile(void *displayProfileA) {
}
void GfxColorSpace::setDisplayProfileName(GooString *name) {
+ if (displayProfile != nullptr) {
+ error(errInternal, -1, "The display color profile can only be set before any rendering is done.");
+ return;
+ }
+ delete displayProfileName;
displayProfileName = name->copy();
}
diff --git a/qt5/src/poppler-qt5.h b/qt5/src/poppler-qt5.h
index 4f06c47e..ddac7dfb 100644
--- a/qt5/src/poppler-qt5.h
+++ b/qt5/src/poppler-qt5.h
@@ -1102,6 +1102,8 @@ delete it;
\param outputProfileA is a \c cmsHPROFILE of the LCMS library.
+ \note This should be called before any rendering happens and only once during the lifetime of the current process.
+
\since 0.12
*/
void setColorDisplayProfile(void *outputProfileA);
@@ -1110,6 +1112,8 @@ delete it;
\param name is the name of the display profile to set.
+ \note This should be called before any rendering happens.
+
\since 0.12
*/
void setColorDisplayProfileName(const QString &name);
--
2.20.1

View File

@ -1,63 +0,0 @@
From 39a251b1b3a3343400a08e2f03c5518a26624626 Mon Sep 17 00:00:00 2001
From: Adam Reichold <adam.reichold@t-online.de>
Date: Mon, 24 Dec 2018 15:40:38 +0100
Subject: [PATCH] Do not try to parse into unallocated XRef entry and return
pointer to dummy entry instead. Closes #692 and oss-fuzz/12330
---
poppler/XRef.cc | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)
diff --git a/poppler/XRef.cc b/poppler/XRef.cc
index 0ec66944..d042d1f4 100644
--- a/poppler/XRef.cc
+++ b/poppler/XRef.cc
@@ -1548,11 +1548,31 @@ void XRef::readXRefUntil(int untilEntryNum, std::vector<int> *xrefStreamObjsNum)
}
}
+namespace {
+
+struct DummyXRefEntry : XRefEntry {
+ DummyXRefEntry() {
+ offset = 0;
+ gen = -1;
+ type = xrefEntryNone;
+ flags = 0;
+ }
+};
+
+DummyXRefEntry dummyXRefEntry;
+
+}
+
XRefEntry *XRef::getEntry(int i, GBool complainIfMissing)
{
if (i >= size || entries[i].type == xrefEntryNone) {
if ((!xRefStream) && mainXRefEntriesOffset) {
+ if (unlikely(i >= capacity)) {
+ error(errInternal, -1, "Request for out-of-bounds XRef entry [{0:d}]", i);
+ return &dummyXRefEntry;
+ }
+
if (!parseEntry(mainXRefEntriesOffset + 20*i, &entries[i])) {
error(errSyntaxError, -1, "Failed to parse XRef entry [{0:d}].", i);
}
@@ -1563,12 +1583,7 @@ XRefEntry *XRef::getEntry(int i, bool complainIfMissing)
// We might have reconstructed the xref
// Check again i is in bounds
if (unlikely(i >= size)) {
- static XRefEntry dummy;
- dummy.offset = 0;
- dummy.gen = -1;
- dummy.type = xrefEntryNone;
- dummy.flags = 0;
- return &dummy;
+ return &dummyXRefEntry;
}
if (entries[i].type == xrefEntryNone) {
--
2.20.1

View File

@ -1,71 +0,0 @@
From 614514f577bbe676f736afcd8065892df8391315 Mon Sep 17 00:00:00 2001
From: Marek Kasik <mkasik@redhat.com>
Date: Fri, 20 Apr 2018 11:38:13 +0200
Subject: [PATCH] Fix crash on missing embedded file
Check whether an embedded file is actually present in the PDF
and show warning in that case.
https://bugs.freedesktop.org/show_bug.cgi?id=106137
https://gitlab.freedesktop.org/poppler/poppler/issues/236
---
glib/poppler-attachment.cc | 26 +++++++++++++++++---------
glib/poppler-document.cc | 3 ++-
2 files changed, 19 insertions(+), 10 deletions(-)
diff --git a/glib/poppler-attachment.cc b/glib/poppler-attachment.cc
index c6502e9d..11ba5bb5 100644
--- a/glib/poppler-attachment.cc
+++ b/glib/poppler-attachment.cc
@@ -111,17 +111,25 @@ _poppler_attachment_new (FileSpec *emb_file)
attachment->description = _poppler_goo_string_to_utf8 (emb_file->getDescription ());
embFile = emb_file->getEmbeddedFile();
- attachment->size = embFile->size ();
+ if (embFile != NULL && embFile->streamObject()->isStream())
+ {
+ attachment->size = embFile->size ();
- if (embFile->createDate ())
- _poppler_convert_pdf_date_to_gtime (embFile->createDate (), (time_t *)&attachment->ctime);
- if (embFile->modDate ())
- _poppler_convert_pdf_date_to_gtime (embFile->modDate (), (time_t *)&attachment->mtime);
+ if (embFile->createDate ())
+ _poppler_convert_pdf_date_to_gtime (embFile->createDate (), (time_t *)&attachment->ctime);
+ if (embFile->modDate ())
+ _poppler_convert_pdf_date_to_gtime (embFile->modDate (), (time_t *)&attachment->mtime);
- if (embFile->checksum () && embFile->checksum ()->getLength () > 0)
- attachment->checksum = g_string_new_len (embFile->checksum ()->getCString (),
- embFile->checksum ()->getLength ());
- priv->obj_stream = embFile->streamObject()->copy();
+ if (embFile->checksum () && embFile->checksum ()->getLength () > 0)
+ attachment->checksum = g_string_new_len (embFile->checksum ()->getCString (),
+ embFile->checksum ()->getLength ());
+ priv->obj_stream = embFile->streamObject()->copy();
+ }
+ else
+ {
+ g_warning ("Missing stream object for embedded file");
+ g_clear_object (&attachment);
+ }
return attachment;
}
diff --git a/glib/poppler-document.cc b/glib/poppler-document.cc
index b343eb90..df0aa47f 100644
--- a/glib/poppler-document.cc
+++ b/glib/poppler-document.cc
@@ -666,7 +666,8 @@ poppler_document_get_attachments (PopplerDocument *document)
attachment = _poppler_attachment_new (emb_file);
delete emb_file;
- retval = g_list_prepend (retval, attachment);
+ if (attachment != NULL)
+ retval = g_list_prepend (retval, attachment);
}
return g_list_reverse (retval);
}
--
2.17.0

View File

@ -1,35 +0,0 @@
From de0c0b8324e776f0b851485e0fc9622fc35695b7 Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <aacid@kde.org>
Date: Sat, 29 Dec 2018 01:25:17 +0100
Subject: [PATCH] FileSpec: Move the fileSpec.dictLookup call inside
fileSpec.isDict if
Fixes #704
---
poppler/FileSpec.cc | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/poppler/FileSpec.cc b/poppler/FileSpec.cc
index 8a8b9e7e..7c12da63 100644
--- a/poppler/FileSpec.cc
+++ b/poppler/FileSpec.cc
@@ -133,11 +133,12 @@ FileSpec::FileSpec(const Object *fileSpecA)
return;
}
}
- }
- obj1 = fileSpec.dictLookup("Desc");
- if (obj1.isString())
- desc = obj1.getString()->copy();
+ obj1 = fileSpec.dictLookup("Desc");
+ if (obj1.isString()) {
+ desc = obj1.getString()->copy();
+ }
+ }
}
FileSpec::~FileSpec()
--
2.20.1

View File

@ -1,27 +0,0 @@
From f4136a6353162db249f63ddb0f20611622ab61b4 Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <aacid@kde.org>
Date: Wed, 27 Feb 2019 19:43:22 +0100
Subject: [PATCH] ImageStream::getLine: fix crash on broken files
Fixes #728
---
poppler/Stream.cc | 3 +++
1 file changed, 3 insertions(+)
diff --git a/poppler/Stream.cc b/poppler/Stream.cc
index 33537b0e..a41435ab 100644
--- a/poppler/Stream.cc
+++ b/poppler/Stream.cc
@@ -496,6 +496,9 @@ unsigned char *ImageStream::getLine() {
}
int readChars = str->doGetChars(inputLineSize, inputLine);
+ if (unlikely(readChars == -1)) {
+ readChars = 0;
+ }
for ( ; readChars < inputLineSize; readChars++) inputLine[readChars] = EOF;
if (nBits == 1) {
p = inputLine;
--
2.20.1

View File

@ -1,41 +0,0 @@
From 89a5367d49b2556a2635dbb6d48d6a6b182a2c6c Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <aacid@kde.org>
Date: Thu, 23 May 2019 00:54:29 +0200
Subject: [PATCH] JPEG2000Stream: fail gracefully if not all components have
the same WxH
I think this is just a mistake, or at least the only file we have with
this scenario is a fuzzed one
---
poppler/JPEG2000Stream.cc | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/poppler/JPEG2000Stream.cc b/poppler/JPEG2000Stream.cc
index 15bbcae4..0eea3a2d 100644
--- a/poppler/JPEG2000Stream.cc
+++ b/poppler/JPEG2000Stream.cc
@@ -4,7 +4,7 @@
//
// A JPX stream decoder using OpenJPEG
//
-// Copyright 2008-2010, 2012, 2017, 2018 Albert Astals Cid <aacid@kde.org>
+// Copyright 2008-2010, 2012, 2017-2019 Albert Astals Cid <aacid@kde.org>
// Copyright 2011 Daniel Glöckner <daniel-gl@gmx.net>
// Copyright 2014, 2016 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright 2013, 2014 Adrian Johnson <ajohnson@redneon.com>
@@ -253,6 +253,12 @@ void JPXStream::init()
close();
break;
}
+ const int componentPixels = priv->image->comps[component].w * priv->image->comps[component].h;
+ if (componentPixels != priv->npixels) {
+ error(errSyntaxWarning, -1, "Component {0:d} has different WxH than component 0", component);
+ close();
+ break;
+ }
unsigned char *cdata = (unsigned char *)priv->image->comps[component].data;
int adjust = 0;
int depth = priv->image->comps[component].prec;
--
2.21.0

View File

@ -1,25 +0,0 @@
From 004e3c10df0abda214f0c293f9e269fdd979c5ee Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <aacid@kde.org>
Date: Wed, 18 Jul 2018 20:31:27 +0200
Subject: Fix crash when Object has negative number
Spec says object number has to be > 0 and gen has to be >= 0
Reported by email
diff --git a/poppler/Parser.cc b/poppler/Parser.cc
index 39c9a967..8b0093e3 100644
--- a/poppler/Parser.cc
+++ b/poppler/Parser.cc
@@ -154,6 +154,11 @@ Object Parser::getObj(GBool simpleOnly,
const int gen = buf1.getInt();
shift();
shift();
+
+ if (unlikely(num <= 0 || gen < 0)) {
+ return Object();
+ }
+
return Object(num, gen);
} else {
return Object(num);

View File

@ -1,29 +0,0 @@
From b54e1fc3e0d2600621a28d50f9f085b9e38619c2 Mon Sep 17 00:00:00 2001
From: Adam Reichold <adam.reichold@t-online.de>
Date: Fri, 1 Feb 2019 08:42:27 +0100
Subject: [PATCH] Also defend against requests for negative XRef indices.
oss-fuzz/12797
---
poppler/XRef.cc | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/poppler/XRef.cc b/poppler/XRef.cc
index d042d1f4..ac2cd0ce 100644
--- a/poppler/XRef.cc
+++ b/poppler/XRef.cc
@@ -1565,6 +1565,11 @@ DummyXRefEntry dummyXRefEntry;
XRefEntry *XRef::getEntry(int i, GBool complainIfMissing)
{
+ if (unlikely(i < 0)) {
+ error(errInternal, -1, "Request for invalid XRef entry [{0:d}]", i);
+ return &dummyXRefEntry;
+ }
+
if (i >= size || entries[i].type == xrefEntryNone) {
if ((!xRefStream) && mainXRefEntriesOffset) {
--
2.20.1

View File

@ -28,30 +28,30 @@ index 16476f4f..9f4adda3 100644
+#endif
+
+#ifdef ENABLE_NSS3
+static PK11Context *rc4InitContext(const Guchar *key, int keyLen);
+static Guchar rc4DecryptByte(PK11Context *context, Guchar c);
+static PK11Context *rc4InitContext(const unsigned char *key, int keyLen);
+static unsigned char rc4DecryptByte(PK11Context *context, unsigned char c);
+#else
static void rc4InitKey(Guchar *key, int keyLen, Guchar *state);
static Guchar rc4DecryptByte(Guchar *state, Guchar *x, Guchar *y, Guchar c);
static void rc4InitKey(const unsigned char *key, int keyLen, unsigned char *state);
static unsigned char rc4DecryptByte(unsigned char *state, unsigned char *x, unsigned char *y, unsigned char c);
+#endif
static GBool aesReadBlock(Stream *str, Guchar *in, GBool addPadding);
static bool aesReadBlock(Stream *str, unsigned char *in, bool addPadding);
+#ifdef ENABLE_NSS3
+static PK11Context *aesInitContext(Guchar *in, Guchar *objKey, int objKeyLength, GBool decrypt);
+static PK11Context *aesInitContext(unsigned char *in, unsigned char *objKey, int objKeyLength, bool decrypt);
+#else
static void aesKeyExpansion(DecryptAESState *s, Guchar *objKey, int objKeyLen, GBool decrypt);
static void aesKeyExpansion(DecryptAESState *s, const unsigned char *objKey, int objKeyLen, bool decrypt);
+#endif
static void aesEncryptBlock(DecryptAESState *s, Guchar *in);
static void aesDecryptBlock(DecryptAESState *s, Guchar *in, GBool last);
static void aesEncryptBlock(DecryptAESState *s, const unsigned char *in);
static void aesDecryptBlock(DecryptAESState *s, const unsigned char *in, bool last);
+#ifndef ENABLE_NSS3
static void aes256KeyExpansion(DecryptAES256State *s, Guchar *objKey, int objKeyLen, GBool decrypt);
static void aes256KeyExpansion(DecryptAES256State *s, const unsigned char *objKey, int objKeyLen, bool decrypt);
+#endif
static void aes256EncryptBlock(DecryptAES256State *s, Guchar *in);
static void aes256DecryptBlock(DecryptAES256State *s, Guchar *in, GBool last);
static void aes256EncryptBlock(DecryptAES256State *s, const unsigned char *in);
static void aes256DecryptBlock(DecryptAES256State *s, const unsigned char *in, bool last);
@@ -70,6 +86,31 @@ static const Guchar passwordPad[32] = {
@@ -70,6 +86,31 @@ static const unsigned char passwordPad[32] = {
// Decrypt
//------------------------------------------------------------------------
@ -64,41 +64,41 @@ index 16476f4f..9f4adda3 100644
+ }
+}
+
+static GBool initNSS() {
+static bool initNSS() {
+ if (NSS_IsInitialized()) {
+ return gTrue;
+ return true;
+ } else {
+ if (NSS_NoDB_Init(".") != SECSuccess) {
+ error(errInternal, -1, "NSS initialization failed: {0:s}",
+ PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
+ return gFalse;
+ return false;
+ } else {
+ atexit(shutdownNSS);
+ return gTrue;
+ return true;
+ }
+ }
+}
+#endif
+
GBool Decrypt::makeFileKey(int encVersion, int encRevision, int keyLength,
GooString *ownerKey, GooString *userKey,
GooString *ownerEnc, GooString *userEnc,
@@ -80,13 +121,21 @@ GBool Decrypt::makeFileKey(int encVersio
bool Decrypt::makeFileKey(int encVersion, int encRevision, int keyLength, const GooString *ownerKey, const GooString *userKey, const GooString *ownerEnc, const GooString *userEnc, int permissions, const GooString *fileID,
const GooString *ownerPassword, const GooString *userPassword, unsigned char *fileKey, bool encryptMetadata, bool *ownerPasswordOk)
{
@@ -80,13 +121,21 @@ bool Decrypt::makeFileKey(int encVersio
DecryptAES256State state;
Guchar test[127 + 56], test2[32];
unsigned char test[127 + 56], test2[32];
GooString *userPassword2;
- Guchar fState[256];
Guchar tmpKey[16];
- Guchar fx, fy;
- unsigned char fState[256];
unsigned char tmpKey[16];
- unsigned char fx, fy;
int len, i, j;
+#ifdef ENABLE_NSS3
+ PK11Context *rc4Context;
+#else
+ Guchar fState[256];
+ Guchar fx, fy;
+ unsigned char fState[256];
+ unsigned char fx, fy;
+#endif
*ownerPasswordOk = gFalse;
*ownerPasswordOk = false;
+#ifdef ENABLE_NSS3
+ initNSS();
@ -107,63 +107,61 @@ index 16476f4f..9f4adda3 100644
if (encRevision == 5 || encRevision == 6) {
// check the owner password
@@ -115,15 +164,27 @@ GBool Decrypt::makeFileKey(int encVersio
//test contains the initial SHA-256 hash input K.
revision6Hash(ownerPassword, test, userKey->getCString());
@@ -115,14 +164,26 @@ bool Decrypt::makeFileKey(int encVersio
// test contains the initial SHA-256 hash input K.
revision6Hash(ownerPassword, test, userKey->c_str());
}
+#ifndef ENABLE_NSS3
aes256KeyExpansion(&state, test, 32, gTrue);
aes256KeyExpansion(&state, test, 32, true);
+#endif
for (i = 0; i < 16; ++i) {
state.cbc[i] = 0;
}
+#ifdef ENABLE_NSS3
+ state.context = aesInitContext(state.cbc, test, 32, gTrue);
+ state.context = aesInitContext(state.cbc, test, 32, true);
+ if (state.context) {
+#endif
aes256DecryptBlock(&state, (Guchar *)ownerEnc->getCString(), gFalse);
aes256DecryptBlock(&state, (unsigned char *)ownerEnc->c_str(), false);
memcpy(fileKey, state.buf, 16);
aes256DecryptBlock(&state, (Guchar *)ownerEnc->getCString() + 16,
gFalse);
aes256DecryptBlock(&state, (unsigned char *)ownerEnc->c_str() + 16, false);
memcpy(fileKey + 16, state.buf, 16);
+#ifdef ENABLE_NSS3
+ PK11_DestroyContext(state.context, PR_TRUE);
+ } else {
+ return gFalse;
+ return false;
+ }
+#endif
*ownerPasswordOk = gTrue;
return gTrue;
@@ -156,15 +217,27 @@ GBool Decrypt::makeFileKey(int encVersio
//user key is not used in computing intermediate user key.
*ownerPasswordOk = true;
return true;
@@ -156,14 +217,26 @@ bool Decrypt::makeFileKey(int encVersio
// user key is not used in computing intermediate user key.
revision6Hash(userPassword, test, nullptr);
}
+#ifndef ENABLE_NSS3
aes256KeyExpansion(&state, test, 32, gTrue);
aes256KeyExpansion(&state, test, 32, true);
+#endif
for (i = 0; i < 16; ++i) {
state.cbc[i] = 0;
}
+#ifdef ENABLE_NSS3
+ state.context = aesInitContext(state.cbc, test, 32, gTrue);
+ state.context = aesInitContext(state.cbc, test, 32, true);
+ if (state.context) {
+#endif
aes256DecryptBlock(&state, (Guchar *)userEnc->getCString(), gFalse);
aes256DecryptBlock(&state, (unsigned char *)userEnc->c_str(), false);
memcpy(fileKey, state.buf, 16);
aes256DecryptBlock(&state, (Guchar *)userEnc->getCString() + 16,
gFalse);
aes256DecryptBlock(&state, (unsigned char *)userEnc->c_str() + 16, false);
memcpy(fileKey + 16, state.buf, 16);
+#ifdef ENABLE_NSS3
+ PK11_DestroyContext(state.context, PR_TRUE);
+ } else {
+ return gFalse;
+ return false;
+ }
+#endif
return gTrue;
return true;
}
@@ -189,22 +262,41 @@ GBool Decrypt::makeFileKey(int encVersio
@@ -189,22 +262,41 @@ bool Decrypt::makeFileKey(int encVersio
}
}
if (encRevision == 2) {
@ -182,7 +180,7 @@ index 16476f4f..9f4adda3 100644
}
+#endif
} else {
memcpy(test2, ownerKey->getCString(), 32);
memcpy(test2, ownerKey->c_str(), 32);
for (i = 19; i >= 0; --i) {
for (j = 0; j < keyLength; ++j) {
tmpKey[j] = test[j] ^ i;
@ -205,26 +203,26 @@ index 16476f4f..9f4adda3 100644
}
}
userPassword2 = new GooString((char *)test2, 32);
@@ -232,11 +324,15 @@ GBool Decrypt::makeFileKey2(int encVersi
GBool encryptMetadata) {
Guchar *buf;
Guchar test[32];
- Guchar fState[256];
Guchar tmpKey[16];
- Guchar fx, fy;
@@ -232,11 +324,15 @@ bool Decrypt::makeFileKey2(int encVersi
{
unsigned char *buf;
unsigned char test[32];
- unsigned char fState[256];
unsigned char tmpKey[16];
- unsigned char fx, fy;
int len, i, j;
- GBool ok;
+ GBool ok = gTrue;
- bool ok;
+ bool ok = true;
+#ifdef ENABLE_NSS3
+ PK11Context *rc4Context;
+#else
+ Guchar fState[256];
+ Guchar fx, fy;
+ unsigned char fState[256];
+ unsigned char fx, fy;
+#endif
// generate file key
buf = (Guchar *)gmalloc(72 + fileID->getLength());
@@ -273,28 +369,52 @@ GBool Decrypt::makeFileKey2(int encVersi
buf = (unsigned char *)gmalloc(72 + fileID->getLength());
@@ -273,28 +369,52 @@ bool Decrypt::makeFileKey2(int encVersi
// test user password
if (encRevision == 2) {
@ -235,7 +233,7 @@ index 16476f4f..9f4adda3 100644
+ test[i] = rc4DecryptByte(rc4Context, userKey->getChar(i));
+ PK11_DestroyContext(rc4Context, PR_TRUE);
+ } else {
+ ok = gFalse;
+ ok = false;
+ }
+#else
rc4InitKey(fileKey, keyLength, fState);
@ -248,7 +246,7 @@ index 16476f4f..9f4adda3 100644
+ if (ok)
+ ok = memcmp(test, passwordPad, 32) == 0;
} else if (encRevision == 3) {
memcpy(test, userKey->getCString(), 32);
memcpy(test, userKey->c_str(), 32);
for (i = 19; i >= 0; --i) {
for (j = 0; j < keyLength; ++j) {
tmpKey[j] = fileKey[j] ^ i;
@ -260,7 +258,7 @@ index 16476f4f..9f4adda3 100644
+ test[j] = rc4DecryptByte(rc4Context, test[j]);
+ PK11_DestroyContext(rc4Context, PR_TRUE);
+ } else {
+ ok = gFalse;
+ ok = false;
+ }
+#else
rc4InitKey(tmpKey, keyLength, fState);
@ -271,13 +269,13 @@ index 16476f4f..9f4adda3 100644
+#endif
}
memcpy(buf, passwordPad, 32);
memcpy(buf + 32, fileID->getCString(), fileID->getLength());
memcpy(buf + 32, fileID->c_str(), fileID->getLength());
md5(buf, 32 + fileID->getLength(), buf);
- ok = memcmp(test, buf, 16) == 0;
+ if (ok)
+ ok = memcmp(test, buf, 16) == 0;
} else {
ok = gFalse;
ok = false;
}
@@ -334,6 +454,9 @@ BaseCryptStream::BaseCryptStream(Stream
if ((objKeyLength = keyLength + 5) > 16) {
@ -288,7 +286,7 @@ index 16476f4f..9f4adda3 100644
+#endif
break;
case cryptAES:
objKey[keyLength] = objNum & 0xff;
objKey[keyLength] = refA.num & 0xff;
@@ -349,9 +472,15 @@ BaseCryptStream::BaseCryptStream(Stream
if ((objKeyLength = keyLength + 5) > 16) {
objKeyLength = 16;
@ -305,17 +303,18 @@ index 16476f4f..9f4adda3 100644
break;
case cryptNone:
break;
@@ -359,9 +488,32 @@ BaseCryptStream::BaseCryptStream(Stream
@@ -359,10 +488,33 @@ BaseCryptStream::BaseCryptStream(Stream
charactersRead = 0;
autoDelete = gTrue;
nextCharBuff = EOF;
autoDelete = true;
+
+#ifdef ENABLE_NSS3
+ initNSS();
+#endif
}
BaseCryptStream::~BaseCryptStream() {
BaseCryptStream::~BaseCryptStream()
{
+#ifdef ENABLE_NSS3
+ switch (algo) {
+ case cryptRC4:
@ -357,13 +356,13 @@ index 16476f4f..9f4adda3 100644
+ if (state.aes.context)
+ PK11_DestroyContext(state.aes.context, PR_TRUE);
+ state.aes.context = aesInitContext(state.aes.cbc, objKey, objKeyLength,
+ gFalse);
+ false);
+#else
aesKeyExpansion(&state.aes, objKey, objKeyLength, gFalse);
aesKeyExpansion(&state.aes, objKey, objKeyLength, false);
memcpy(state.aes.buf, state.aes.cbc, 16); // Copy CBC IV to buf
+#endif
state.aes.bufIdx = 0;
state.aes.paddingReached = gFalse;
state.aes.paddingReached = false;
break;
case cryptAES256:
+#ifdef ENABLE_NSS3
@ -371,22 +370,22 @@ index 16476f4f..9f4adda3 100644
+ if (state.aes256.context)
+ PK11_DestroyContext(state.aes256.context, PR_TRUE);
+ state.aes256.context = aesInitContext(state.aes256.cbc, objKey, objKeyLength,
+ gFalse);
+ false);
+#else
aes256KeyExpansion(&state.aes256, objKey, objKeyLength, gFalse);
aes256KeyExpansion(&state.aes256, objKey, objKeyLength, false);
memcpy(state.aes256.buf, state.aes256.cbc, 16); // Copy CBC IV to buf
+#endif
state.aes256.bufIdx = 0;
state.aes256.paddingReached = gFalse;
state.aes256.paddingReached = false;
break;
@@ -456,7 +630,11 @@ int EncryptStream::lookChar() {
case cryptRC4:
if ((c = str->getChar()) != EOF) {
// RC4 is XOR-based: the decryption algorithm works for encryption too
+#ifdef ENABLE_NSS3
+ c = rc4DecryptByte(state.rc4.context, (Guchar)c);
+ c = rc4DecryptByte(state.rc4.context, (unsigned char)c);
+#else
c = rc4DecryptByte(state.rc4.state, &state.rc4.x, &state.rc4.y, (Guchar)c);
c = rc4DecryptByte(state.rc4.state, &state.rc4.x, &state.rc4.y, (unsigned char)c);
+#endif
}
break;
@ -412,9 +411,9 @@ index 16476f4f..9f4adda3 100644
+ state.aes.cbc[i] = str->getChar();
+ }
+ state.aes.context = aesInitContext(state.aes.cbc, objKey, objKeyLength,
+ gTrue);
+ true);
+#else
aesKeyExpansion(&state.aes, objKey, objKeyLength, gTrue);
aesKeyExpansion(&state.aes, objKey, objKeyLength, true);
for (i = 0; i < 16; ++i) {
state.aes.cbc[i] = str->getChar();
}
@ -429,9 +428,9 @@ index 16476f4f..9f4adda3 100644
+ state.aes256.cbc[i] = str->getChar();
+ }
+ state.aes256.context = aesInitContext(state.aes256.cbc, objKey, objKeyLength,
+ gTrue);
+ true);
+#else
aes256KeyExpansion(&state.aes256, objKey, objKeyLength, gTrue);
aes256KeyExpansion(&state.aes256, objKey, objKeyLength, true);
for (i = 0; i < 16; ++i) {
state.aes256.cbc[i] = str->getChar();
}
@ -447,9 +446,9 @@ index 16476f4f..9f4adda3 100644
+ if (unlikely(state.rc4.context == nullptr))
+ c = EOF;
+ else
+ c = rc4DecryptByte(state.rc4.context, (Guchar)c);
+ c = rc4DecryptByte(state.rc4.context, (unsigned char)c);
+#else
c = rc4DecryptByte(state.rc4.state, &state.rc4.x, &state.rc4.y, (Guchar)c);
c = rc4DecryptByte(state.rc4.state, &state.rc4.x, &state.rc4.y, (unsigned char)c);
+#endif
}
break;
@ -459,7 +458,7 @@ index 16476f4f..9f4adda3 100644
+ break;
+#endif
if (state.aes.bufIdx == 16) {
if (aesReadBlock(str, in, gFalse)) {
if (aesReadBlock(str, in, false)) {
aesDecryptBlock(&state.aes, in, str->lookChar() == EOF);
@@ -555,6 +770,10 @@ int DecryptStream::lookChar() {
}
@ -470,9 +469,9 @@ index 16476f4f..9f4adda3 100644
+ break;
+#endif
if (state.aes256.bufIdx == 16) {
if (aesReadBlock(str, in, gFalse)) {
if (aesReadBlock(str, in, false)) {
aes256DecryptBlock(&state.aes256, in, str->lookChar() == EOF);
@@ -576,6 +795,175 @@ int DecryptStream::lookChar() {
@@ -576,7 +795,176 @@ int DecryptStream::lookChar() {
// RC4-compatible decryption
//------------------------------------------------------------------------
@ -481,7 +480,7 @@ index 16476f4f..9f4adda3 100644
+ * This function turns given key into token key (compared to a session key
+ * which is prohibited in FIPS mode).
+ */
+static PK11SymKey *tokenizeKey(const Guchar *key, int keyLen,
+static PK11SymKey *tokenizeKey(const unsigned char *key, int keyLen,
+ CK_ATTRIBUTE_TYPE operation) {
+ CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC_PAD;
+ PK11SlotInfo *slot;
@ -491,9 +490,9 @@ index 16476f4f..9f4adda3 100644
+ SECStatus retval;
+ SECItem *secParam = nullptr;
+ SECItem ivItem, wrappedKey;
+ Guchar output[48]; // Buffer to hold 256 bit key + padding
+ Guchar iv[16]; // Initialization vector for AES
+ Guint outputLength;
+ unsigned char output[48]; // Buffer to hold 256 bit key + padding
+ unsigned char iv[16]; // Initialization vector for AES
+ unsigned int outputLength;
+ int i;
+
+ slot = PK11_GetBestSlot(CKM_AES_KEY_GEN, nullptr);
@ -573,7 +572,7 @@ index 16476f4f..9f4adda3 100644
+ return token;
+}
+
+static PK11Context *rc4InitContext(const Guchar *key, int keyLen) {
+static PK11Context *rc4InitContext(const unsigned char *key, int keyLen) {
+ CK_MECHANISM_TYPE cipherMech = CKM_RC4;
+ PK11SlotInfo *slot = nullptr;
+ PK11SymKey *symKey = nullptr;
@ -623,8 +622,8 @@ index 16476f4f..9f4adda3 100644
+ return context;
+}
+
+static Guchar rc4DecryptByte(PK11Context *context, Guchar c) {
+ Guchar outputChar = 0;
+static unsigned char rc4DecryptByte(PK11Context *context, unsigned char c) {
+ unsigned char outputChar = 0;
+ SECStatus retval;
+ int outputLength;
+
@ -645,10 +644,11 @@ index 16476f4f..9f4adda3 100644
+
+#else
+
static void rc4InitKey(Guchar *key, int keyLen, Guchar *state) {
Guchar index1, index2;
Guchar t;
@@ -609,6 +997,8 @@ static Guchar rc4DecryptByte(Guchar *sta
static void rc4InitKey(const unsigned char *key, int keyLen, unsigned char *state)
{
unsigned char index1, index2;
unsigned char t;
@@ -609,6 +997,8 @@ static unsigned char rc4DecryptByte(unsigned char *sta
return c ^ state[(tx + ty) % 256];
}
@ -657,14 +657,14 @@ index 16476f4f..9f4adda3 100644
//------------------------------------------------------------------------
// AES decryption
//------------------------------------------------------------------------
@@ -639,6 +1029,178 @@ static GBool aesReadBlock(Stream *str, G
@@ -639,6 +1029,178 @@ static bool aesReadBlock(Stream *str, G
}
}
+#ifdef ENABLE_NSS3
+
+static PK11Context *aesInitContext(Guchar *in, Guchar *objKey,
+ int objKeyLength, GBool decrypt) {
+static PK11Context *aesInitContext(unsigned char *in, unsigned char *objKey,
+ int objKeyLength, bool decrypt) {
+ CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC;
+ CK_ATTRIBUTE_TYPE operationType = decrypt ? CKA_DECRYPT : CKA_ENCRYPT;
+ PK11SlotInfo *slot;
@ -716,7 +716,7 @@ index 16476f4f..9f4adda3 100644
+ return context;
+}
+
+static void aesEncryptBlock(DecryptAESState *s, Guchar *in) {
+static void aesEncryptBlock(DecryptAESState *s, const unsigned char *in) {
+ SECStatus rv;
+ int outputLength;
+
@ -739,7 +739,7 @@ index 16476f4f..9f4adda3 100644
+ return;
+}
+
+static void aesDecryptBlock(DecryptAESState *s, Guchar *in, GBool last) {
+static void aesDecryptBlock(DecryptAESState *s, const unsigned char *in, bool last) {
+ SECStatus rv1;
+ int outputLen;
+ int n, i;
@ -773,7 +773,7 @@ index 16476f4f..9f4adda3 100644
+ return;
+}
+
+static void aes256EncryptBlock(DecryptAES256State *s, Guchar *in) {
+static void aes256EncryptBlock(DecryptAES256State *s, const unsigned char *in) {
+ SECStatus rv;
+ int outputLength;
+
@ -796,8 +796,8 @@ index 16476f4f..9f4adda3 100644
+ return;
+}
+
+static void aes256DecryptBlock(DecryptAES256State *s, Guchar *in,
+ GBool last) {
+static void aes256DecryptBlock(DecryptAES256State *s, const unsigned char *in,
+ bool last) {
+ SECStatus rv1;
+ int outputLen;
+ int n, i;
@ -833,9 +833,9 @@ index 16476f4f..9f4adda3 100644
+
+#else
+
static const Guchar sbox[256] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
static const unsigned char sbox[256] = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
@@ -1121,10 +1683,33 @@ static void aes256DecryptBlock(DecryptAE
}
}
@ -847,10 +847,10 @@ index 16476f4f..9f4adda3 100644
//------------------------------------------------------------------------
+#ifdef ENABLE_NSS3
+static void hashFunc(const Guchar *msg, int msgLen, Guchar *hash,
+static void hashFunc(const unsigned char *msg, int msgLen, unsigned char *hash,
+ HASH_HashType type) {
+ HASHContext *context;
+ Guint hashLen = 0;
+ unsigned int hashLen = 0;
+
+ if (!initNSS())
+ return;
@ -868,25 +868,26 @@ index 16476f4f..9f4adda3 100644
+#else
+
// this works around a bug in older Sun compilers
static inline Gulong rotateLeft(Gulong x, int r) {
x &= 0xffffffff;
@@ -1151,7 +1736,12 @@ static inline Gulong md5Round4(Gulong a,
return b + rotateLeft((a + (c ^ (b | ~d)) + Xk + Ti), s);
static inline unsigned long rotateLeft(unsigned long x, int r)
{
@@ -1151,8 +1736,13 @@ static inline unsigned long md5Round4(unsigned long a,
state->digest[15] = (unsigned char)(state->d >> 24);
}
+#endif
+
void md5(Guchar *msg, int msgLen, Guchar *digest) {
void md5(const unsigned char *msg, int msgLen, unsigned char *digest)
{
+#ifdef ENABLE_NSS3
+ hashFunc(msg, msgLen, digest, HASH_AlgMD5);
+#else
Gulong x[16] = {};
Gulong a, b, c, d, aa, bb, cc, dd;
int n64;
@@ -1296,12 +1886,14 @@ void md5(Guchar *msg, int msgLen, Guchar
digest[13] = (Guchar)((d >>= 8) & 0xff);
digest[14] = (Guchar)((d >>= 8) & 0xff);
digest[15] = (Guchar)((d >>= 8) & 0xff);
if (msgLen < 0) {
return;
}
@@ -1296,12 +1886,14 @@ void md5(unsigned char *msg, int msgLen, unsigned char
for (int i = 0; i < 16; ++i) {
digest[i] = state.digest[i];
}
+#endif
}
@ -895,25 +896,26 @@ index 16476f4f..9f4adda3 100644
//------------------------------------------------------------------------
+#ifndef ENABLE_NSS3
static Guint sha256K[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
@@ -1400,8 +1992,12 @@ static void sha256HashBlock(Guchar *blk,
static const unsigned int sha256K[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
@@ -1400,9 +1992,13 @@ static void sha256HashBlock(unsigned char *blk,
H[6] += g;
H[7] += h;
}
+#endif
static void sha256(Guchar *msg, int msgLen, Guchar *hash) {
static void sha256(unsigned char *msg, int msgLen, unsigned char *hash)
{
+#ifdef ENABLE_NSS3
+ hashFunc(msg, msgLen, hash, HASH_AlgSHA256);
+#else
Guchar blk[64];
Guint H[8];
unsigned char blk[64];
unsigned int H[8];
int blkLen, i;
@@ -1453,7 +2049,10 @@ static void sha256(Guchar *msg, int msgL
hash[i*4 + 2] = (Guchar)(H[i] >> 8);
hash[i*4 + 3] = (Guchar)H[i];
@@ -1453,7 +2049,10 @@ static void sha256(unsigned char *msg, int msgL
hash[i * 4 + 2] = (unsigned char)(H[i] >> 8);
hash[i * 4 + 3] = (unsigned char)H[i];
}
+#endif
}
@ -922,67 +924,58 @@ index 16476f4f..9f4adda3 100644
//------------------------------------------------------------------------
// SHA-512 hash (see FIPS 180-4)
//------------------------------------------------------------------------
@@ -1557,8 +2156,12 @@ static void sha512HashBlock(Guchar *blk,
@@ -1557,9 +2156,13 @@ static void sha512HashBlock(unsigned char *blk,
H[6] += g;
H[7] += h;
}
+#endif
static void sha512(Guchar *msg, int msgLen, Guchar *hash) {
static void sha512(unsigned char *msg, int msgLen, unsigned char *hash)
{
+#ifdef ENABLE_NSS3
+ hashFunc(msg, msgLen, hash, HASH_AlgSHA512);
+#else
Guchar blk[128];
unsigned char blk[128];
uint64_t H[8];
int blkLen = 0, i;
@@ -1622,6 +2225,7 @@ static void sha512(Guchar *msg, int msgL
hash[i*8 + 6] = (Guchar)(H[i] >> 8);
hash[i*8 + 7] = (Guchar)H[i];
@@ -1622,6 +2225,7 @@ static void sha512(unsigned char *msg, int msgL
hash[i * 8 + 6] = (unsigned char)(H[i] >> 8);
hash[i * 8 + 7] = (unsigned char)H[i];
}
+#endif
}
//------------------------------------------------------------------------
@@ -1631,6 +2235,9 @@ static void sha512(Guchar *msg, int msgL
//1.Initial hash value is different.
//2.A 384 bit message digest is obtained by truncating the final hash value.
static void sha384(Guchar *msg, int msgLen, Guchar *hash) {
@@ -1631,6 +2235,9 @@ static void sha512(unsigned char *msg, int msgL
// 2.A 384 bit message digest is obtained by truncating the final hash value.
static void sha384(unsigned char *msg, int msgLen, unsigned char *hash)
{
+#ifdef ENABLE_NSS3
+ hashFunc(msg, msgLen, hash, HASH_AlgSHA384);
+#else
Guchar blk[128];
unsigned char blk[128];
uint64_t H[8];
int blkLen, i;
@@ -1696,6 +2303,7 @@ static void sha384(Guchar *msg, int msgL
hash[i*8 + 6] = (Guchar)(H[i] >> 8);
hash[i*8 + 7] = (Guchar)H[i];
@@ -1696,6 +2303,7 @@ static void sha384(unsigned char *msg, int msgL
hash[i * 8 + 6] = (unsigned char)(H[i] >> 8);
hash[i * 8 + 7] = (unsigned char)H[i];
}
+#endif
}
//------------------------------------------------------------------------
@@ -1725,7 +2333,8 @@ static void revision6Hash(GooString *inp
//a.make the string K1
memcpy(K1, inputPassword, inputPasswordLength);
memcpy(K1 + inputPasswordLength, K , KLength);
- memcpy(K1 + inputPasswordLength + KLength, userKey, userKeyLength);
+ if (userKey)
+ memcpy(K1 + inputPasswordLength + KLength, userKey, userKeyLength);
for(int i = 1; i < 64 ; ++i) {
memcpy(K1 + (i * sequenceLength),K1,sequenceLength);
}
@@ -1735,7 +2344,11 @@ static void revision6Hash(GooString *inp
memcpy(state.buf, state.cbc, 16); // Copy CBC IV to buf
state.bufIdx = 0;
state.paddingReached = gFalse;
state.paddingReached = false;
+#ifdef ENABLE_NSS3
+ state.context = aesInitContext(state.cbc, aesKey, 16, gFalse);
+ state.context = aesInitContext(state.cbc, aesKey, 16, false);
+#else
aesKeyExpansion(&state,aesKey,16,gFalse);
aesKeyExpansion(&state, aesKey, 16, false);
+#endif
for(int i = 0; i < (4 * sequenceLength); i++) {
aesEncryptBlock(&state,K1 + (16 * i));
for (int i = 0; i < (4 * sequenceLength); i++) {
aesEncryptBlock(&state, K1 + (16 * i));
@@ -1776,6 +2389,9 @@ static void revision6Hash(GooString *inp
sha512(E, totalLength, K);
}
@ -1007,47 +1000,48 @@ index d4667c8c..16fa9830 100644
//------------------------------------------------------------------------
// Decrypt
@@ -73,13 +77,21 @@ private:
* previous output is kept in buf. The paddingReached field is only used in
@@ -73,14 +77,22 @@ private:
* case of encryption. */
struct DecryptRC4State {
struct DecryptRC4State
{
+#ifdef ENABLE_NSS3
+ PK11Context *context;
+#else
Guchar state[256];
Guchar x, y;
unsigned char state[256];
unsigned char x, y;
+#endif
};
struct DecryptAESState {
struct DecryptAESState
{
+#ifdef ENABLE_NSS3
+ PK11Context *context;
+#else
Guint w[44];
Guchar state[16];
unsigned int w[44];
unsigned char state[16];
+#endif
Guchar cbc[16];
Guchar buf[16];
GBool paddingReached; // encryption only
unsigned char cbc[16];
unsigned char buf[16];
bool paddingReached; // encryption only
@@ -87,8 +99,12 @@ struct DecryptAESState {
};
struct DecryptAES256State {
struct DecryptAES256State
{
+#ifdef ENABLE_NSS3
+ PK11Context *context;
+#else
Guint w[60];
Guchar state[16];
unsigned int w[60];
unsigned char state[16];
+#endif
Guchar cbc[16];
Guchar buf[16];
GBool paddingReached; // encryption only
unsigned char cbc[16];
unsigned char buf[16];
bool paddingReached; // encryption only
diff --git a/poppler/poppler-config.h.cmake b/poppler/poppler-config.h.cmake
index f0a5a1a0..dcaade6f 100644
--- a/poppler/poppler-config.h.cmake
+++ b/poppler/poppler-config.h.cmake
@@ -115,6 +115,12 @@
#cmakedefine USE_CMS 1
#cmakedefine USE_BOOST_HEADERS 1
#endif
+/* Build against libnss3 for digital signature validation and
@ -1056,17 +1050,6 @@ index f0a5a1a0..dcaade6f 100644
+#cmakedefine ENABLE_NSS3 1
+#endif
+
// Also, there are preprocessor symbols in the header files
// that are used but never defined when building poppler using configure
// or cmake: DISABLE_OUTLINE, DEBUG_MEM,
--- poppler-0.66.0/CMakeLists.txt
+++ poppler-0.66.0/CMakeLists.txt
@@ -490,7 +490,7 @@ add_library(poppler STATIC ${poppler_SRC
else()
add_library(poppler ${poppler_SRCS})
endif()
-set_target_properties(poppler PROPERTIES VERSION 77.0.0 SOVERSION 77)
+set_target_properties(poppler PROPERTIES VERSION 78.0.0 SOVERSION 78)
if(MINGW)
get_target_property(POPPLER_SOVERSION poppler SOVERSION)
set_target_properties(poppler PROPERTIES SUFFIX "-${POPPLER_SOVERSION}${CMAKE_SHARED_LIBRARY_SUFFIX}")
//------------------------------------------------------------------------
// version
//------------------------------------------------------------------------

View File

@ -1,100 +0,0 @@
From 8122f6d6d409b53151a20c5578fc525ee97315e8 Mon Sep 17 00:00:00 2001
From: Marek Kasik <mkasik@redhat.com>
Date: Thu, 21 Mar 2019 13:47:51 +0100
Subject: [PATCH 2/2] cairo: Constrain number of cycles in rescale filter
Pass address of the first byte after end of the source buffer
to downsample_row_box_filter() so that we can check
that we don't run out of it.
Fixes issue #736
---
poppler/CairoRescaleBox.cc | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/poppler/CairoRescaleBox.cc b/poppler/CairoRescaleBox.cc
index d7615010..7fd07041 100644
--- a/poppler/CairoRescaleBox.cc
+++ b/poppler/CairoRescaleBox.cc
@@ -62,7 +62,7 @@
static void downsample_row_box_filter (
int start, int width,
- uint32_t *src, uint32_t *dest,
+ uint32_t *src, uint32_t *src_limit, uint32_t *dest,
int coverage[], int pixel_coverage)
{
/* we need an array of the pixel contribution of each destination pixel on the boundaries.
@@ -90,13 +90,13 @@ static void downsample_row_box_filter (
/* skip to start */
/* XXX: it might be possible to do this directly instead of iteratively, however
* the iterative solution is simple */
- while (x < start)
+ while (x < start && src < src_limit)
{
int box = 1 << FIXED_SHIFT;
int start_coverage = coverage[x];
box -= start_coverage;
src++;
- while (box >= pixel_coverage)
+ while (box >= pixel_coverage && src < src_limit)
{
src++;
box -= pixel_coverage;
@@ -104,7 +104,7 @@ static void downsample_row_box_filter (
x++;
}
- while (x < start + width)
+ while (x < start + width && src < src_limit)
{
uint32_t a = 0;
uint32_t r = 0;
@@ -121,7 +121,7 @@ static void downsample_row_box_filter (
x++;
box -= start_coverage;
- while (box >= pixel_coverage)
+ while (box >= pixel_coverage && src < src_limit)
{
a += ((*src >> 24) & 0xff) * pixel_coverage;
r += ((*src >> 16) & 0xff) * pixel_coverage;
@@ -135,7 +135,7 @@ static void downsample_row_box_filter (
/* multiply by whatever is leftover
* this ensures that we don't bias down.
* i.e. start_coverage + n*pixel_coverage + box == 1 << 24 */
- if (box > 0)
+ if (box > 0 && src < src_limit)
{
a += ((*src >> 24) & 0xff) * box;
r += ((*src >> 16) & 0xff) * box;
@@ -337,7 +337,7 @@ bool CairoRescaleBox::downScaleImage(unsigned orig_width, unsigned orig_height,
int start_coverage_y = y_coverage[dest_y];
getRow(src_y, scanline);
- downsample_row_box_filter (start_column, width, scanline, temp_buf + width * columns, x_coverage, pixel_coverage_x);
+ downsample_row_box_filter (start_column, width, scanline, scanline + orig_width, temp_buf + width * columns, x_coverage, pixel_coverage_x);
columns++;
src_y++;
box -= start_coverage_y;
@@ -345,7 +345,7 @@ bool CairoRescaleBox::downScaleImage(unsigned orig_width, unsigned orig_height,
while (box >= pixel_coverage_y)
{
getRow(src_y, scanline);
- downsample_row_box_filter (start_column, width, scanline, temp_buf + width * columns, x_coverage, pixel_coverage_x);
+ downsample_row_box_filter (start_column, width, scanline, scanline + orig_width, temp_buf + width * columns, x_coverage, pixel_coverage_x);
columns++;
src_y++;
box -= pixel_coverage_y;
@@ -355,7 +355,7 @@ bool CairoRescaleBox::downScaleImage(unsigned orig_width, unsigned orig_height,
if (box > 0)
{
getRow(src_y, scanline);
- downsample_row_box_filter (start_column, width, scanline, temp_buf + width * columns, x_coverage, pixel_coverage_x);
+ downsample_row_box_filter (start_column, width, scanline, scanline + orig_width, temp_buf + width * columns, x_coverage, pixel_coverage_x);
columns++;
}
--
2.20.1

View File

@ -1,51 +0,0 @@
From 7f87dc10b6adccd6d1b977a28b064add254aa2da Mon Sep 17 00:00:00 2001
From: Adam Reichold <adam.reichold@t-online.de>
Date: Thu, 27 Dec 2018 11:54:53 +0100
Subject: [PATCH] Do not try to construct invalid rich media annotation assets.
Closes #703
---
poppler/Annot.cc | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 2e4770ab..1750dc70 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -6418,20 +6418,22 @@ AnnotRichMedia::Content::Content(Dict *dict) {
if (obj1.isDict()) {
Object obj2 = obj1.getDict()->lookup("Names");
if (obj2.isArray()) {
- nAssets = obj2.arrayGetLength() / 2;
+ const int length = obj2.arrayGetLength() / 2;
- assets = (Asset **)gmallocn(nAssets, sizeof(Asset *));
+ assets = (Asset **)gmallocn(length, sizeof(Asset *));
+ for (int i = 0; i < length; ++i) {
+ Object objKey = obj2.arrayGet(2 * i);
+ Object objVal = obj2.arrayGet(2 * i + 1);
- int counter = 0;
- for (int i = 0; i < nAssets; ++i) {
- assets[counter] = new AnnotRichMedia::Asset;
-
- Object objKey = obj2.arrayGet(i * 2);
- assets[counter]->fileSpec = obj2.arrayGet(i * 2 + 1);
-
- assets[counter]->name = new GooString( objKey.getString() );
- ++counter;
+ if (!objKey.isString() || objVal.isNull()) {
+ error(errSyntaxError, -1, "Bad Annot Asset");
+ continue;
+ }
+ assets[nAssets] = new AnnotRichMedia::Asset;
+ assets[nAssets]->name = new GooString( objKey.getString() );
+ assets[nAssets]->fileSpec = std::move(objVal);
+ ++nAssets;
}
}
}
--
2.20.1

View File

@ -1,20 +0,0 @@
From fada09a2ccc11a3a1d308e810f1336d8df6011fd Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <aacid@kde.org>
Date: Mon, 18 Mar 2019 00:50:00 +0100
Subject: pdfunite: Fix stack overflow on broken file
Fixes issue #741
diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc
index 26842f84..ab4abcad 100644
--- a/poppler/PDFDoc.cc
+++ b/poppler/PDFDoc.cc
@@ -1703,7 +1703,7 @@ void PDFDoc::markObject (Object* obj, XRef *xRef, XRef *countRef, unsigned int n
array = obj->getArray();
for (int i=0; i<array->getLength(); i++) {
Object obj1 = array->getNF(i);
- markObject(&obj1, xRef, countRef, numOffset, oldRefNum, newRefNum);
+ markObject(&obj1, xRef, countRef, numOffset, oldRefNum, newRefNum, alreadyMarkedDicts);
}
break;
case objDict:

View File

@ -1,28 +0,0 @@
From 6912e06d9ab19ba28991b5cab3319d61d856bd6d Mon Sep 17 00:00:00 2001
From: Adam Reichold <adam.reichold@t-online.de>
Date: Tue, 6 Nov 2018 09:00:02 +0100
Subject: [PATCH] Check for stream before calling stream methods when saving an
embedded file.
Closes #659
---
poppler/FileSpec.cc | 3 +++
1 file changed, 3 insertions(+)
diff --git a/poppler/FileSpec.cc b/poppler/FileSpec.cc
index 7479c2d2..d5543041 100644
--- a/poppler/FileSpec.cc
+++ b/poppler/FileSpec.cc
@@ -93,6 +93,9 @@ bool EmbFile::save(const char *path) {
GBool EmbFile::save2(FILE *f) {
int c;
+ if (unlikely(!m_objStr.isStream()))
+ return false;
+
m_objStr.streamReset();
while ((c = m_objStr.streamGetChar()) != EOF) {
fputc(c, f);
--
2.19.1

View File

@ -1,47 +0,0 @@
From 718d428984e3a84fda521c0f5e6d975c7390af2b Mon Sep 17 00:00:00 2001
From: Marek Kasik <mkasik@redhat.com>
Date: Fri, 6 Apr 2018 15:06:46 +0200
Subject: [PATCH] cairo: Fix tiling patterns when pattern cell is too far
Rendering of tiling pattern which has pattern matrix moving pattern cell
far away can fail on allocation of memory. This commit solves the issue by
modifying of cairo pattern matrix so that its offset is closer to the path
filled by the pattern.
https://bugs.freedesktop.org/show_bug.cgi?id=105905
---
poppler/CairoOutputDev.cc | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index 631ab27b..b2e730bf 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -915,6 +915,8 @@ GBool CairoOutputDev::tilingPatternFill(GfxState *state, Gfx *gfxA, Catalog *cat
StrokePathClip *strokePathTmp;
GBool adjusted_stroke_width_tmp;
cairo_pattern_t *maskTmp;
+ double xoffset, yoffset;
+ double det;
width = bbox[2] - bbox[0];
height = bbox[3] - bbox[1];
@@ -976,6 +978,15 @@ GBool CairoOutputDev::tilingPatternFill(GfxState *state, Gfx *gfxA, Catalog *cat
if (cairo_pattern_status (pattern))
return gFalse;
+ det = pmat[0] * pmat[3] - pmat[1] * pmat[2];
+ if (fabs(det) < 0.000001)
+ return gFalse;
+
+ xoffset = round ((pmat[3] * pmat[4] - pmat[2] * pmat[5]) / (xStep * det));
+ yoffset = - round ((pmat[1] * pmat[4] - pmat[0] * pmat[5]) / (yStep * det));
+ pattern_matrix.x0 -= xoffset * pattern_matrix.xx * xStep + yoffset * pattern_matrix.xy * yStep;
+ pattern_matrix.y0 -= xoffset * pattern_matrix.yx * xStep + yoffset * pattern_matrix.yy * yStep;
+
state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
cairo_rectangle (cairo, xMin, yMin, xMax - xMin, yMax - yMin);
--
2.14.3

View File

@ -1,28 +0,0 @@
From b224e2f5739fe61de9fa69955d016725b2a4b78d Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <aacid@kde.org>
Date: Mon, 15 Jul 2019 22:11:09 +0200
Subject: [PATCH] SplashOutputDev::tilingPatternFill: Fix crash on broken file
Issue #802
---
poppler/SplashOutputDev.cc | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc
index 544f132d..3d2befc2 100644
--- a/poppler/SplashOutputDev.cc
+++ b/poppler/SplashOutputDev.cc
@@ -4581,6 +4581,10 @@ bool SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfxA, Catalog *cat
surface_width = (int) ceil (fabs(kx));
surface_height = (int) ceil (fabs(ky));
// adjust repeat values to completely fill region
+ if (unlikely(surface_width == 0 || surface_height == 0)) {
+ state->setCTM(savedCTM[0], savedCTM[1], savedCTM[2], savedCTM[3], savedCTM[4], savedCTM[5]);
+ return gFalse;
+ }
repeatX = result_width / surface_width;
repeatY = result_height / surface_height;
if (surface_width * repeatX < result_width)
--
2.24.1

View File

@ -1,81 +0,0 @@
From d2f5d424ba8752f9a9e9dad410546ec1b46caa0a Mon Sep 17 00:00:00 2001
From: Adam Reichold <adam.reichold@t-online.de>
Date: Tue, 6 Nov 2018 09:08:06 +0100
Subject: [PATCH] pdfdetach: Check for valid file name of embedded file before
using it to determine save path.
Closes #660
---
utils/pdfdetach.cc | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/utils/pdfdetach.cc b/utils/pdfdetach.cc
index a8720c64..71fa8608 100644
--- a/utils/pdfdetach.cc
+++ b/utils/pdfdetach.cc
@@ -191,14 +191,18 @@ int main(int argc, char *argv[]) {
fileSpec = static_cast<FileSpec *>(embeddedFiles->get(i));
printf("%d: ", i+1);
s1 = fileSpec->getFileName();
- if ((s1->getChar(0) & 0xff) == 0xfe && (s1->getChar(1) & 0xff) == 0xff) {
+ if (!s1) {
+ exitCode = 3;
+ goto err2;
+ }
+ if (s1->hasUnicodeMarker()) {
isUnicode = gTrue;
j = 2;
} else {
isUnicode = gFalse;
j = 0;
}
- while (j < fileSpec->getFileName()->getLength()) {
+ while (j < s1->getLength()) {
if (isUnicode) {
u = ((s1->getChar(j) & 0xff) << 8) | (s1->getChar(j+1) & 0xff);
j += 2;
@@ -228,14 +232,18 @@ int main(int argc, char *argv[]) {
p = path;
}
s1 = fileSpec->getFileName();
- if ((s1->getChar(0) & 0xff) == 0xfe && (s1->getChar(1) & 0xff) == 0xff) {
+ if (!s1) {
+ exitCode = 3;
+ goto err2;
+ }
+ if (s1->hasUnicodeMarker()) {
isUnicode = gTrue;
j = 2;
} else {
isUnicode = gFalse;
j = 0;
}
- while (j < fileSpec->getFileName()->getLength()) {
+ while (j < s1->getLength()) {
if (isUnicode) {
u = ((s1->getChar(j) & 0xff) << 8) | (s1->getChar(j+1) & 0xff);
j += 2;
@@ -276,14 +284,18 @@ int main(int argc, char *argv[]) {
} else {
p = path;
s1 = fileSpec->getFileName();
- if ((s1->getChar(0) & 0xff) == 0xfe && (s1->getChar(1) & 0xff) == 0xff) {
+ if (!s1) {
+ exitCode = 3;
+ goto err2;
+ }
+ if (s1->hasUnicodeMarker()) {
isUnicode = gTrue;
j = 2;
} else {
isUnicode = gFalse;
j = 0;
}
- while (j < fileSpec->getFileName()->getLength()) {
+ while (j < s1->getLength()) {
if (isUnicode) {
u = ((s1->getChar(j) & 0xff) << 8) | (s1->getChar(j+1) & 0xff);
j += 2;
--
2.19.1

View File

@ -1,46 +0,0 @@
From 77a30e94d96220d7e22dff5b3f0a7f296f01b118 Mon Sep 17 00:00:00 2001
From: Adam Reichold <adam.reichold@t-online.de>
Date: Tue, 6 Nov 2018 09:13:41 +0100
Subject: [PATCH] pdfdetach: Check for valid embedded file before trying to
save it.
Closes #661
---
utils/pdfdetach.cc | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/utils/pdfdetach.cc b/utils/pdfdetach.cc
index 846584a4..a8720c64 100644
--- a/utils/pdfdetach.cc
+++ b/utils/pdfdetach.cc
@@ -251,7 +251,12 @@ int main(int argc, char *argv[]) {
}
*p = '\0';
- if (!fileSpec->getEmbeddedFile()->save(path)) {
+ auto *embFile = fileSpec->getEmbeddedFile();
+ if (!embFile || !embFile->isOk()) {
+ exitCode = 3;
+ goto err2;
+ }
+ if (!embFile->save(path)) {
error(errIO, -1, "Error saving embedded file as '{0:s}'", p);
exitCode = 2;
goto err2;
@@ -296,7 +301,12 @@ int main(int argc, char *argv[]) {
p = path;
}
- if (!fileSpec->getEmbeddedFile()->save(p)) {
+ auto *embFile = fileSpec->getEmbeddedFile();
+ if (!embFile || !embFile->isOk()) {
+ exitCode = 3;
+ goto err2;
+ }
+ if (!embFile->save(p)) {
error(errIO, -1, "Error saving embedded file as '{0:s}'", p);
exitCode = 2;
goto err2;
--
2.19.1

View File

@ -3,8 +3,8 @@
Summary: PDF rendering library
Name: poppler
Version: 0.66.0
Release: 27%{?dist}
Version: 20.11.0
Release: 1%{?dist}
License: (GPLv2 or GPLv3) and GPLv2+ and LGPLv2+ and MIT
URL: http://poppler.freedesktop.org/
Source0: http://poppler.freedesktop.org/poppler-%{version}.tar.xz
@ -14,77 +14,13 @@ Source1: %{name}-test-%{test_date}_%{test_sha}.tar.xz
# https://bugzilla.redhat.com/show_bug.cgi?id=1185007
Patch0: poppler-0.30.0-rotated-words-selection.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1580849
Patch2: poppler-0.62.0-python3.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1602838
Patch3: poppler-0.66.0-negative-object-number.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1602662
# https://bugzilla.redhat.com/show_bug.cgi?id=1638712
Patch4: poppler-0.66.0-covscan.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1626623
Patch5: poppler-0.66.0-cycles-in-pdf-parsing.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1649457
Patch6: poppler-0.66.0-embedded-file-check.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1649435
Patch7: poppler-0.66.0-stream-check.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1649440
Patch8: poppler-0.66.0-valid-embedded-file.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1649450
Patch9: poppler-0.66.0-valid-embedded-file-name.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1644094
Patch10: poppler-0.66.0-tiling-patterns.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1646546
Patch11: poppler-0.66.0-display-profile.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1665266
Patch12: poppler-0.66.0-dummy-xref-entry.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1672419
Patch13: poppler-0.66.0-negative-xref-indices.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1665259
Patch14: poppler-0.66.0-rich-media-annotation.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1665263
Patch15: poppler-0.66.0-filespec.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1665273
Patch16: poppler-0.66.0-check-catalog-is-dict.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1683632
Patch17: poppler-0.66.0-image-stream-getline.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1686802
Patch18: poppler-0.66.0-coverage-values.patch
Patch19: poppler-0.66.0-rescale-filter.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1691724
Patch20: poppler-0.66.0-stack-overflow.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1618766
Patch21: poppler-0.66.0-nss.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1713582
Patch22: poppler-0.66.0-jpeg2000-component-size.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1732340
Patch23: poppler-0.66.0-JPXStream-length.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1696636
Patch24: poppler-0.66.0-PSOutputDev-rgb.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1797453
Patch25: poppler-0.66.0-tilingpatternfill-crash.patch
BuildRequires: cmake
BuildRequires: gettext-devel
BuildRequires: pkgconfig(cairo)
@ -190,6 +126,7 @@ other formats.
%prep
%autosetup -p1 -b 1
chmod -x poppler/CairoFontEngine.cc
%build
mkdir build
@ -200,9 +137,10 @@ export CC="gcc -fPIC" # hack to make the cmake call pass
-DENABLE_DCTDECODER=libjpeg \
-DENABLE_GTK_DOC=ON \
-DENABLE_LIBOPENJPEG=openjpeg2 \
-DENABLE_XPDF_HEADERS=ON \
-DENABLE_ZLIB=OFF \
-DENABLE_NSS=ON \
-DENABLE_UNSTABLE_API_ABI_HEADERS=ON \
-DENABLE_QT6=OFF \
..
unset CC
make %{?_smp_mflags}
@ -236,9 +174,9 @@ test "$(pkg-config --modversion poppler-splash)" = "%{version}"
%postun cpp -p /sbin/ldconfig
%files
%doc README
%doc README.md
%license COPYING
%{_libdir}/libpoppler.so.78*
%{_libdir}/libpoppler.so.104*
%files devel
%{_libdir}/pkgconfig/poppler.pc
@ -287,6 +225,11 @@ test "$(pkg-config --modversion poppler-splash)" = "%{version}"
%{_mandir}/man1/*
%changelog
* Fri Nov 6 2020 Marek Kasik <mkasik@redhat.com> - 20.11.0-1
- Rebase poppler to 20.11.0
- Modify/remove patches as needed
- Resolves: #1644423
* Thu Apr 16 2020 Marek Kasik <mkasik@redhat.com> - 0.66.0-27
- Fix crash on broken file in tilingPatternFill()
- Resolves: #1801341