import poppler-20.11.0-2.el8
This commit is contained in:
parent
4c47de41a9
commit
29376cef82
2
.gitignore
vendored
2
.gitignore
vendored
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
+
|
||||
|
@ -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>
|
||||
#
|
@ -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
|
||||
|
@ -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) {
|
@ -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;
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
@ -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
|
||||
|
@ -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
|
||||
//------------------------------------------------------------------------
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user