import poppler-20.11.0-2.el8

This commit is contained in:
CentOS Sources 2021-05-18 02:44:33 -04:00 committed by Andrew Lukoshko
parent 4c47de41a9
commit 29376cef82
28 changed files with 1129 additions and 2672 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,269 +17,263 @@ 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;
PDFRectangle *rect;
double x1, y1, x2, y2, margin;
- margin = (line->yMax - line->yMin) / 8;
- x1 = line->edge[edge_begin];
- y1 = line->yMin - margin;
- x2 = line->edge[edge_end];
- y2 = line->yMax + margin;
+ switch (line->rot) {
+ default:
+ case 0:
+ margin = (line->yMax - line->yMin) / 8;
+ x1 = line->edge[edge_begin];
+ x2 = line->edge[edge_end];
+ y1 = line->yMin - margin;
+ y2 = line->yMax + margin;
+ break;
+ case 1:
+ margin = (line->xMax - line->xMin) / 8;
+ x1 = line->xMin - margin;
+ x2 = line->xMax + margin;
+ y1 = line->edge[edge_begin];
+ y2 = line->edge[edge_end];
+ break;
+ case 2:
+ margin = (line->yMax - line->yMin) / 8;
+ x1 = line->edge[edge_end];
+ x2 = line->edge[edge_begin];
+ y1 = line->yMin - margin;
+ y2 = line->yMax + margin;
+ break;
+ case 3:
+ margin = (line->xMax - line->xMin) / 8;
+ x1 = line->xMin - margin;
+ x2 = line->xMax + margin;
+ y1 = line->edge[edge_end];
+ y2 = line->edge[edge_begin];
+ break;
+ }
- margin = (line->yMax - line->yMin) / 8;
- x1 = line->edge[edge_begin];
- y1 = line->yMin - margin;
- x2 = line->edge[edge_end];
- y2 = line->yMax + margin;
+ switch (line->rot) {
+ default:
+ case 0:
+ margin = (line->yMax - line->yMin) / 8;
+ x1 = line->edge[edge_begin];
+ x2 = line->edge[edge_end];
+ y1 = line->yMin - margin;
+ y2 = line->yMax + margin;
+ break;
+ case 1:
+ margin = (line->xMax - line->xMin) / 8;
+ x1 = line->xMin - margin;
+ x2 = line->xMax + margin;
+ y1 = line->edge[edge_begin];
+ y2 = line->edge[edge_end];
+ break;
+ case 2:
+ margin = (line->yMax - line->yMin) / 8;
+ x1 = line->edge[edge_end];
+ x2 = line->edge[edge_begin];
+ y1 = line->yMin - margin;
+ y2 = line->yMax + margin;
+ break;
+ case 3:
+ margin = (line->xMax - line->xMin) / 8;
+ x1 = line->xMin - margin;
+ x2 = line->xMax + margin;
+ y1 = line->edge[edge_end];
+ y2 = line->edge[edge_begin];
+ 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;
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);
+ switch (line->rot) {
+ default:
+ case 0:
+ margin = (line->yMax - line->yMin) / 8;
+ x1 = line->edge[edge_begin];
+ x2 = line->edge[edge_end];
+ y1 = line->yMin - margin;
+ y2 = line->yMax + margin;
+ break;
+ case 1:
+ margin = (line->xMax - line->xMin) / 8;
+ x1 = line->xMin - margin;
+ x2 = line->xMax + margin;
+ y1 = line->edge[edge_begin];
+ y2 = line->edge[edge_end];
+ break;
+ case 2:
+ margin = (line->yMax - line->yMin) / 8;
+ x1 = line->edge[edge_end];
+ x2 = line->edge[edge_begin];
+ y1 = line->yMin - margin;
+ y2 = line->yMax + margin;
+ break;
+ case 3:
+ margin = (line->xMax - line->xMin) / 8;
+ x1 = line->xMin - margin;
+ x2 = line->xMax + margin;
+ y1 = line->edge[edge_end];
+ y2 = line->edge[edge_begin];
+ break;
+ }
+
+ ctm.transform(x1, y1, &x1, &y1);
+ ctm.transform(x2, y2, &x2, &y2);
- 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);
+ } else {
+ x1 = ceil (x1);
+ x2 = floor (x2);
+ }
- x1 = floor (x1);
- y1 = floor (y1);
- x2 = ceil (x2);
- y2 = ceil (y2);
+ if (y1 < y2) {
+ y1 = floor (y1);
+ y2 = ceil (y2);
+ } else {
+ 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)
{
int i, begin, end;
- double mid;
+ double mid, s1, s2;
+
+ if (rot == 0 || rot == 2) {
+ s1 = selection->x1;
+ s2 = selection->x2;
+ } else {
+ s1 = selection->y1;
+ s2 = selection->y2;
+ }
begin = len;
end = 0;
for (i = 0; i < len; i++) {
mid = (edge[i] + edge[i + 1]) / 2;
- if (selection->x1 < mid || selection->x2 < mid)
- if (i < begin)
- begin = i;
- if (mid < selection->x1 || mid < selection->x2)
- end = i + 1;
+ if (XBetweenAB (mid, s1, s2))
+ {
+ if (i < begin)
+ begin = i;
+
+ end = i + 1;
+ }
}
/* Skip empty selection. */
@@ -4615,30 +4694,41 @@ void TextLine::visitSelection(TextSelectionVisitor *visitor,
TextWord *p, *begin, *end, *current;
int i, edge_begin, edge_end;
PDFRectangle child_selection;
+ double s1, s2, p_min, p_max;
+
+ if (rot == 0 || rot == 2) {
+ s1 = selection->x1;
+ s2 = selection->x2;
+ } else {
+ s1 = selection->y1;
+ s2 = selection->y2;
+ }
begin = nullptr;
end = nullptr;
current = nullptr;
for (p = words; p != nullptr; p = p->next) {
+ if (rot == 0 || rot == 2) {
+ p_min = p->xMin;
+ p_max = p->xMax;
+ } else {
+ p_min = p->yMin;
+ p_max = p->yMax;
- 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);
+ switch (line->rot) {
+ default:
+ case 0:
+ margin = (line->yMax - line->yMin) / 8;
+ x1 = line->edge[edge_begin];
+ x2 = line->edge[edge_end];
+ y1 = line->yMin - margin;
+ y2 = line->yMax + margin;
+ break;
+ case 1:
+ margin = (line->xMax - line->xMin) / 8;
+ x1 = line->xMin - margin;
+ x2 = line->xMax + margin;
+ y1 = line->edge[edge_begin];
+ y2 = line->edge[edge_end];
+ break;
+ case 2:
+ margin = (line->yMax - line->yMin) / 8;
+ x1 = line->edge[edge_end];
+ x2 = line->edge[edge_begin];
+ y1 = line->yMin - margin;
+ y2 = line->yMax + margin;
+ break;
+ case 3:
+ margin = (line->xMax - line->xMin) / 8;
+ x1 = line->xMin - margin;
+ x2 = line->xMax + margin;
+ y1 = line->edge[edge_end];
+ y2 = line->edge[edge_begin];
+ break;
+ }
+
if (blk->page->primaryLR) {
- 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;
+ ctm.transform(x1, y1, &x1, &y1);
+ ctm.transform(x2, y2, &x2, &y2);
- 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 (begin == nullptr)
- begin = p;
+ if (((s1 > p_min) || (s2 > p_min)) && begin == nullptr)
+ begin = p;
- 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);
+ } else {
+ x1 = ceil(x1);
+ x2 = floor(x2);
+ }
- 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,
child_selection = *selection;
if (style == selectionStyleWord) {
- child_selection.x1 = begin ? begin->xMin : xMin;
- if (end && end->xMax != -1) {
- child_selection.x2 = current->xMax;
- x1 = floor(x1);
- y1 = floor(y1);
- x2 = ceil(x2);
- y2 = ceil(y2);
+ if (y1 < y2) {
+ y1 = floor(y1);
+ y2 = ceil(y2);
+ } else {
+ y1 = ceil(y1);
+ y2 = floor(y2);
+ }
ictm.transform(x1, y1, &x1, &y1);
ictm.transform(x2, y2, &x2, &y2);
@@ -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;
+ double mid, s1, s2;
+
+ if (rot == 0 || rot == 2) {
+ child_selection.x1 = begin ? begin->xMin : xMin;
+ if (end && end->xMax != -1) {
+ child_selection.x2 = current->xMax;
+ } else {
+ child_selection.x2 = xMax;
+ }
} else {
- child_selection.x2 = xMax;
+ child_selection.y1 = begin ? begin->yMin : yMin;
+ if (end && end->yMax != -1) {
+ child_selection.y2 = current->yMax;
+ } else {
+ child_selection.y2 = yMax;
+ s1 = selection->x1;
+ s2 = selection->x2;
+ } else {
+ s1 = selection->y1;
+ s2 = selection->y2;
+ }
begin = len;
end = 0;
for (i = 0; i < len; i++) {
mid = (edge[i] + edge[i + 1]) / 2;
- if (selection->x1 < mid || selection->x2 < mid)
- if (i < begin)
- begin = i;
- if (mid < selection->x1 || mid < selection->x2)
- end = i + 1;
+ if (XBetweenAB (mid, s1, s2)) {
+ if (i < begin)
+ begin = i;
+
+ end = i + 1;
+ }
}
}
+ if (rot == 0 || rot == 2) {
+ s1 = child_selection.x1;
+ s2 = child_selection.x2;
+ } else {
+ s1 = child_selection.y1;
+ s2 = child_selection.y2;
+ }
/* Skip empty selection. */
@@ -4615,26 +4694,41 @@ void TextLine::visitSelection(TextSelectionVisitor *visitor,
TextWord *p, *begin, *end, *current;
int i, edge_begin, edge_end;
PDFRectangle child_selection;
+ double s1, s2, p_min, p_max;
+
edge_begin = len;
edge_end = 0;
for (i = 0; i < len; i++) {
double mid = (edge[i] + edge[i + 1]) / 2;
- if (child_selection.x1 < mid || child_selection.x2 < mid)
- if (i < edge_begin)
- edge_begin = i;
- if (mid < child_selection.x2 || mid < child_selection.x1)
- edge_end = i + 1;
+ if (XBetweenAB (mid, s1, s2))
+ {
+ if (i < edge_begin)
+ edge_begin = i;
+
+ edge_end = i + 1;
+ }
}
+ if (rot == 0 || rot == 2) {
+ s1 = selection->x1;
+ s2 = selection->x2;
+ } else {
+ s1 = selection->y1;
+ s2 = selection->y2;
+ }
/* Skip empty selection. */
begin = nullptr;
end = nullptr;
current = nullptr;
for (p = words; p != nullptr; p = p->next) {
+ if (rot == 0 || rot == 2) {
+ p_min = p->xMin;
+ p_max = p->xMax;
+ } else {
+ p_min = p->yMin;
+ p_max = p->yMax;
+ }
+
if (blk->page->primaryLR) {
- 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 (((s1 > p_min) || (s2 > p_min)) && begin != nullptr) {
end = p->next;
current = p;
}
} else {
- 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 (((s1 < p_max) || (s2 < p_max)) && begin != nullptr) {
end = p->next;
current = p;
}
@@ -4650,23 +4740,41 @@ void TextLine::visitSelection(TextSelectionVisitor *visitor,
child_selection = *selection;
if (style == selectionStyleWord) {
- child_selection.x1 = begin ? begin->xMin : xMin;
- if (end && end->xMax != -1) {
- child_selection.x2 = current->xMax;
+ if (rot == 0 || rot == 2) {
+ child_selection.x1 = begin ? begin->xMin : xMin;
+ if (end && end->xMax != -1) {
+ child_selection.x2 = current->xMax;
+ } else {
+ child_selection.x2 = xMax;
+ }
} else {
- child_selection.x2 = xMax;
+ child_selection.y1 = begin ? begin->yMin : yMin;
+ if (end && end->yMax != -1) {
+ child_selection.y2 = current->yMax;
+ } else {
+ child_selection.y2 = yMax;
+ }
}
}
+ if (rot == 0 || rot == 2) {
+ s1 = child_selection.x1;
+ s2 = child_selection.x2;
+ } else {
+ s1 = child_selection.y1;
+ s2 = child_selection.y2;
+ }
+
edge_begin = len;
edge_end = 0;
for (i = 0; i < len; i++) {
double mid = (edge[i] + edge[i + 1]) / 2;
- if (child_selection.x1 < mid || child_selection.x2 < mid)
- if (i < edge_begin)
- edge_begin = i;
- if (mid < child_selection.x2 || mid < child_selection.x1)
- edge_end = i + 1;
+ if (XBetweenAB (mid, s1, s2)) {
+ if (i < edge_begin)
+ edge_begin = i;
+
+ edge_end = i + 1;
+ }
}
/* Skip empty selection. */
--
1.8.4.2

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,386 +1,205 @@
--- poppler/glib/poppler-document.cc
+++ poppler/glib/poppler-document.cc
@@ -2872,6 +2872,7 @@ poppler_document_get_form_field (Poppler
unsigned fieldNum;
FormPageWidgets *widgets;
FormWidget *field;
+ PopplerFormField *formField;
@@ -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
return nullptr;
@@ -3417,8 +3418,14 @@ PopplerFormField *poppler_document_get_f
return nullptr;
field = widgets->getWidget (fieldNum);
- if (field)
- return _poppler_form_field_new (document, field);
+ if (field) {
+ formField = _poppler_form_field_new (document, field);
field = widgets->getWidget(fieldNum);
- if (field)
- return _poppler_form_field_new(document, field);
+ if (field) {
+ formField = _poppler_form_field_new(document, field);
+ delete widgets;
+
+ return formField;
+ }
+
+ delete widgets;
+
+ return formField;
+ }
+
+ delete widgets;
return nullptr;
return nullptr;
}
--- 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
- if (strKind == strJPX && colorSpace)
+ if (strKind == strJPX && colorSpace) {
+ delete colorSpace;
return;
+ }
// colorspace in stream dict may be different from colorspace in jpx
// data
- if (strKind == strJPX && colorSpace)
+ if (strKind == strJPX && colorSpace) {
+ delete colorSpace;
return;
+ }
// 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;
// only embed mime data for gray, rgb, and cmyk colorspaces.
if (colorSpace) {
--- 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) {
- pool->addWord(word);
if (xMin > xMax) {
xMin = word->xMin;
xMax = word->xMax;
@@ -1546,6 +1545,7 @@ void TextBlock::addWord(TextWord *word)
yMax = word->yMax;
void TextBlock::addWord(TextWord *word)
{
- pool->addWord(word);
if (xMin > xMax) {
xMin = word->xMin;
xMax = word->xMax;
@@ -1639,6 +1638,7 @@ void TextBlock::addWord(TextWord *word)
yMax = word->yMax;
}
}
}
+ pool->addWord(word);
+ pool->addWord(word);
}
void TextBlock::coalesce(UnicodeMap *uMap, double fixedPitch) {
@@ -2999,11 +2999,13 @@ void TextPage::coalesce(GBool physLayout
word0 = pool->getPool(startBaseIdx);
pool->setPool(startBaseIdx, word0->next);
word0->next = nullptr;
- blk = new TextBlock(this, rot);
- blk->addWord(word0);
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;
- blk = new TextBlock(this, rot);
- blk->addWord(word0);
fontSize = word0->fontSize;
minBase = maxBase = word0->base;
fontSize = word0->fontSize;
minBase = maxBase = word0->base;
+
+ blk = new TextBlock(this, rot);
+ blk->addWord(word0);
+ blk = new TextBlock(this, rot);
+ blk->addWord(word0);
+
colSpace1 = minColSpacing1 * fontSize;
colSpace2 = minColSpacing2 * fontSize;
lineSpace = maxLineSpacingDelta * fontSize;
@@ -3037,9 +3039,9 @@ void TextPage::coalesce(GBool physLayout
}
word1 = word1->next;
word2->next = nullptr;
+ newMinBase = word2->base;
blk->addWord(word2);
found = gTrue;
- newMinBase = word2->base;
} else {
word0 = word1;
word1 = word1->next;
@@ -3072,9 +3074,9 @@ void TextPage::coalesce(GBool physLayout
}
word1 = word1->next;
word2->next = nullptr;
+ newMaxBase = word2->base;
blk->addWord(word2);
found = gTrue;
- newMaxBase = word2->base;
} else {
word0 = word1;
word1 = word1->next;
@@ -3171,12 +3173,12 @@ void TextPage::coalesce(GBool physLayout
}
word1 = word1->next;
word2->next = nullptr;
- blk->addWord(word2);
if (word2->base < minBase) {
minBase = word2->base;
} else if (word2->base > maxBase) {
maxBase = word2->base;
}
+ blk->addWord(word2);
found = gTrue;
break;
} else {
@@ -3235,12 +3237,12 @@ void TextPage::coalesce(GBool physLayout
}
word1 = word1->next;
word2->next = nullptr;
- blk->addWord(word2);
if (word2->base < minBase) {
minBase = word2->base;
} else if (word2->base > maxBase) {
maxBase = word2->base;
}
+ blk->addWord(word2);
found = gTrue;
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:
colSpace1 = minColSpacing1 * fontSize;
colSpace2 = minColSpacing2 * fontSize;
lineSpace = maxLineSpacingDelta * fontSize;
@@ -3095,9 +3097,9 @@ void TextPage::coalesce(bool physLayout,
}
word1 = word1->next;
word2->next = nullptr;
+ newMinBase = word2->base;
blk->addWord(word2);
found = true;
- newMinBase = word2->base;
} else {
word0 = word1;
word1 = word1->next;
@@ -3123,9 +3125,9 @@ void TextPage::coalesce(bool physLayout,
}
word1 = word1->next;
word2->next = nullptr;
+ newMaxBase = word2->base;
blk->addWord(word2);
found = true;
- newMaxBase = word2->base;
} else {
word0 = word1;
word1 = word1->next;
@@ -3198,12 +3200,12 @@ void TextPage::coalesce(bool physLayout,
}
word1 = word1->next;
word2->next = nullptr;
- blk->addWord(word2);
if (word2->base < minBase) {
minBase = word2->base;
} else if (word2->base > maxBase) {
maxBase = word2->base;
}
+ blk->addWord(word2);
found = true;
break;
} else {
@@ -3246,12 +3248,12 @@ void TextPage::coalesce(bool physLayout,
}
word1 = word1->next;
word2->next = nullptr;
- blk->addWord(word2);
if (word2->base < minBase) {
minBase = word2->base;
} else if (word2->base > maxBase) {
maxBase = word2->base;
}
+ blk->addWord(word2);
found = true;
break;
} else {
--- 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) {
+ entries = nullptr;
return 0;
}
void *p = greallocn_checkoverflow(entries, realNewSize, sizeof(XRefEntry));
if (p == nullptr) {
+ entries = nullptr;
return 0;
}
@@ -877,7 +878,6 @@ GBool XRef::constructXRef(GBool *wasReco
int offset = 0;
@@ -835,7 +836,6 @@ bool XRef::constructXRef(bool *wasRecons
int offset = 0;
resize(0); // free entries properly
- gfree(entries);
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;
}
resize(0); // free entries properly
- gfree(entries);
capacity = 0;
size = 0;
entries = nullptr;
--- 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;
+ 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
// 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);
+ delete fName;
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);
@@ -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);
+ 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();
}
}
return;
--- poppler/utils/pdftotext.cc
+++ poppler/utils/pdftotext.cc
@@ -356,6 +356,7 @@ int main(int argc, char *argv[]) {
fputs("<pre>\n", f);
if (f != stdout) {
fclose(f);
+ f = nullptr;
}
@@ -329,6 +329,7 @@ int main(int argc, char *argv[])
fputs("<pre>\n", f);
if (f != stdout) {
fclose(f);
+ f = nullptr;
}
}
}
}
@@ -372,8 +373,9 @@ int main(int argc, char *argv[]) {
printWordBBox(f, doc, textOut, firstPage, lastPage);
}
@@ -348,8 +349,9 @@ int main(int argc, char *argv[])
printWordBBox(f, doc, textOut, firstPage, lastPage);
}
}
- if (f != stdout) {
+ if (f != stdout && f != nullptr) {
fclose(f);
+ f = nullptr;
}
} else {
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) {
+ if (f != stdout && f != nullptr) {
fclose(f);
}
}
- if (f != stdout) {
+ if (f != stdout && f != nullptr) {
fclose(f);
+ f = nullptr;
}
} else {
textOut = new TextOutputDev(textFileName->getCString(),
@@ -413,7 +415,7 @@ int main(int argc, char *argv[]) {
if (!bbox) fputs("</pre>\n", f);
fputs("</body>\n", f);
fputs("</html>\n", f);
- if (f != stdout) {
+ if (f != stdout && f != nullptr) {
fclose(f);
}
}

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

File diff suppressed because it is too large Load Diff

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: 2%{?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)
@ -112,7 +48,7 @@ BuildRequires: pkgconfig(Qt5Gui)
BuildRequires: pkgconfig(Qt5Test)
BuildRequires: pkgconfig(Qt5Widgets)
BuildRequires: pkgconfig(Qt5Xml)
BuildRequires: %{_bindir}/python3
BuildRequires: python3-devel
Requires: poppler-data
@ -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,15 @@ test "$(pkg-config --modversion poppler-splash)" = "%{version}"
%{_mandir}/man1/*
%changelog
* Tue Dec 8 2020 Marek Kasik <mkasik@redhat.com> - 20.11.0-2
- Improve python3 build dependency
- Resolves: #1896335
* 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