diff --git a/.compat-poppler022.metadata b/.compat-poppler022.metadata new file mode 100644 index 0000000..c0139d3 --- /dev/null +++ b/.compat-poppler022.metadata @@ -0,0 +1 @@ +9491bb33788d7f0ee67da572dc4798004f98323a SOURCES/poppler-0.22.5.tar.gz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2e8f6d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/poppler-0.22.5.tar.gz diff --git a/SOURCES/poppler-0.22.5-CVE-2013-4473.patch b/SOURCES/poppler-0.22.5-CVE-2013-4473.patch new file mode 100644 index 0000000..26fd9eb --- /dev/null +++ b/SOURCES/poppler-0.22.5-CVE-2013-4473.patch @@ -0,0 +1,36 @@ +From b8682d868ddf7f741e93b791588af0932893f95c Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Mon, 16 Sep 2013 17:46:55 +0000 +Subject: pdfseparate: improve the path building + +Make use of snprintf to limit the output to the pathName buffer; +while I'm there, expand its size to 4096 (might help longer paths), +although a better fix would be dynamically allocate its length +(and/or using GooString, maybe). +--- +(limited to 'utils/pdfseparate.cc') + +diff --git a/utils/pdfseparate.cc b/utils/pdfseparate.cc +index 35ae020..e41e547 100644 +--- a/utils/pdfseparate.cc ++++ b/utils/pdfseparate.cc +@@ -44,7 +44,7 @@ static const ArgDesc argDesc[] = { + }; + + bool extractPages (const char *srcFileName, const char *destFileName) { +- char pathName[1024]; ++ char pathName[4096]; + GooString *gfileName = new GooString (srcFileName); + PDFDoc *doc = new PDFDoc (gfileName, NULL, NULL, NULL); + +@@ -66,7 +66,7 @@ bool extractPages (const char *srcFileName, const char *destFileName) { + return false; + } + for (int pageNo = firstPage; pageNo <= lastPage; pageNo++) { +- sprintf (pathName, destFileName, pageNo); ++ snprintf (pathName, sizeof (pathName) - 1, destFileName, pageNo); + GooString *gpageName = new GooString (pathName); + int errCode = doc->savePageAs(gpageName, pageNo); + if ( errCode != errNone) { +-- +cgit v0.9.0.2-2-gbebe diff --git a/SOURCES/poppler-0.22.5-CVE-2013-4474.patch b/SOURCES/poppler-0.22.5-CVE-2013-4474.patch new file mode 100644 index 0000000..202b716 --- /dev/null +++ b/SOURCES/poppler-0.22.5-CVE-2013-4474.patch @@ -0,0 +1,64 @@ +From 61f79b8447c3ac8ab5a26e79e0c28053ffdccf75 Mon Sep 17 00:00:00 2001 +From: Albert Astals Cid +Date: Wed, 23 Oct 2013 22:54:56 +0000 +Subject: Allow only one %d in the filename + +Fixes crashes if you had %s and similar in the filename + +Inspired from patch by Pedro Ribeiro + +Bug #69434 +--- +diff --git a/utils/pdfseparate.cc b/utils/pdfseparate.cc +index 1d4901b..6424d20 100644 +--- a/utils/pdfseparate.cc ++++ b/utils/pdfseparate.cc +@@ -20,6 +20,7 @@ + #include "PDFDoc.h" + #include "ErrorCodes.h" + #include "GlobalParams.h" ++#include + + static int firstPage = 0; + static int lastPage = 0; +@@ -63,9 +64,37 @@ bool extractPages (const char *srcFileName, const char *destFileName) { + if (firstPage == 0) + firstPage = 1; + if (firstPage != lastPage && strstr(destFileName, "%d") == NULL) { +- error(errSyntaxError, -1, "'{0:s}' must contain '%%d' if more than one page should be extracted", destFileName); ++ error(errSyntaxError, -1, "'{0:s}' must contain '%d' if more than one page should be extracted", destFileName); + return false; + } ++ ++ // destFileName can have multiple %% and one %d ++ // We use auxDestFileName to replace all the valid % appearances ++ // by 'A' (random char that is not %), if at the end of replacing ++ // any of the valid appearances there is still any % around, the ++ // pattern is wrong ++ char *auxDestFileName = strdup(destFileName); ++ // %% can appear as many times as you want ++ char *p = strstr(auxDestFileName, "%%"); ++ while (p != NULL) { ++ *p = 'A'; ++ *(p + 1) = 'A'; ++ p = strstr(p, "%%"); ++ } ++ // %d can appear only one time ++ p = strstr(auxDestFileName, "%d"); ++ if (p != NULL) { ++ *p = 'A'; ++ } ++ // at this point any other % is wrong ++ p = strstr(auxDestFileName, "%"); ++ if (p != NULL) { ++ error(errSyntaxError, -1, "'{0:s}' can only contain one '%d' pattern", destFileName); ++ free(auxDestFileName); ++ return false; ++ } ++ free(auxDestFileName); ++ + for (int pageNo = firstPage; pageNo <= lastPage; pageNo++) { + snprintf (pathName, sizeof (pathName) - 1, destFileName, pageNo); + GooString *gpageName = new GooString (pathName); +-- +cgit v0.9.0.2-2-gbebe diff --git a/SOURCES/poppler-0.22.5-rotated-words-selection.patch b/SOURCES/poppler-0.22.5-rotated-words-selection.patch new file mode 100644 index 0000000..c4961b6 --- /dev/null +++ b/SOURCES/poppler-0.22.5-rotated-words-selection.patch @@ -0,0 +1,271 @@ +--- poppler-0.22.5/poppler/TextOutputDev.cc ++++ poppler-0.22.5/poppler/TextOutputDev.cc +@@ -171,6 +171,12 @@ + // Max distance between edge of text and edge of link border + #define hyperlinkSlack 2 + ++// 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) ++ + //------------------------------------------------------------------------ + // TextUnderline + //------------------------------------------------------------------------ +@@ -4220,11 +4226,37 @@ void TextSelectionSizer::visitLine (Text + PDFRectangle *rect; + double x1, y1, x2, y2, margin; + +- margin = (line->yMax - line->yMin) / 8; +- x1 = line->edge[edge_begin]; +- y1 = line->yMin - margin; +- x2 = line->edge[edge_end]; +- y2 = line->yMax + margin; ++ switch (line->rot) { ++ default: ++ case 0: ++ margin = (line->yMax - line->yMin) / 8; ++ x1 = line->edge[edge_begin]; ++ x2 = line->edge[edge_end]; ++ y1 = line->yMin - margin; ++ y2 = line->yMax + margin; ++ break; ++ case 1: ++ margin = (line->xMax - line->xMin) / 8; ++ x1 = line->xMin - margin; ++ x2 = line->xMax + margin; ++ y1 = line->edge[edge_begin]; ++ y2 = line->edge[edge_end]; ++ break; ++ case 2: ++ margin = (line->yMax - line->yMin) / 8; ++ x1 = line->edge[edge_end]; ++ x2 = line->edge[edge_begin]; ++ y1 = line->yMin - margin; ++ y2 = line->yMax + margin; ++ break; ++ case 3: ++ margin = (line->xMax - line->xMin) / 8; ++ x1 = line->xMin - margin; ++ x2 = line->xMax + margin; ++ y1 = line->edge[edge_end]; ++ y2 = line->edge[edge_begin]; ++ break; ++ } + + rect = new PDFRectangle (floor (x1 * scale), + floor (y1 * scale), +@@ -4304,22 +4336,59 @@ void TextSelectionPainter::visitLine (Te + state->setFillColor(box_color); + out->updateFillColor(state); + +- 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); +- + state->getCTM (&ctm); +- ctm.transform(line->edge[edge_begin], line->yMin - margin, &x1, &y1); +- ctm.transform(line->edge[edge_end], line->yMax + margin, &x2, &y2); ++ ctm.invertTo (&ictm); + +- x1 = floor (x1); +- y1 = floor (y1); +- x2 = ceil (x2); +- y2 = ceil (y2); ++ switch (line->rot) { ++ case 0: ++ margin = (line->yMax - line->yMin) / 8; ++ x1 = line->edge[edge_begin]; ++ x2 = line->edge[edge_end]; ++ y1 = line->yMin - margin; ++ y2 = line->yMax + margin; ++ break; ++ case 1: ++ margin = (line->xMax - line->xMin) / 8; ++ x1 = line->xMin - margin; ++ x2 = line->xMax + margin; ++ y1 = line->edge[edge_begin]; ++ y2 = line->edge[edge_end]; ++ break; ++ case 2: ++ margin = (line->yMax - line->yMin) / 8; ++ x1 = line->edge[edge_end]; ++ x2 = line->edge[edge_begin]; ++ y1 = line->yMin - margin; ++ y2 = line->yMax + margin; ++ break; ++ case 3: ++ margin = (line->xMax - line->xMin) / 8; ++ x1 = line->xMin - margin; ++ x2 = line->xMax + margin; ++ y1 = line->edge[edge_end]; ++ y2 = line->edge[edge_begin]; ++ break; ++ } ++ ++ ctm.transform(x1, y1, &x1, &y1); ++ ctm.transform(x2, y2, &x2, &y2); ++ ++ if (x1 < x2) { ++ x1 = floor (x1); ++ x2 = ceil (x2); ++ } else { ++ x1 = ceil (x1); ++ x2 = floor (x2); ++ } ++ ++ if (y1 < y2) { ++ y1 = floor (y1); ++ y2 = ceil (y2); ++ } else { ++ y1 = ceil (y1); ++ y2 = floor (y2); ++ } + +- ctm.invertTo (&ictm); + ictm.transform(x1, y1, &x1, &y1); + ictm.transform(x2, y2, &x2, &y2); + +@@ -4376,17 +4445,27 @@ void TextWord::visitSelection(TextSelect + SelectionStyle style) + { + int i, begin, end; +- double mid; ++ double mid, s1, s2; ++ ++ if (rot == 0 || rot == 2) { ++ s1 = selection->x1; ++ s2 = selection->x2; ++ } else { ++ s1 = selection->y1; ++ s2 = selection->y2; ++ } + + begin = len; + end = 0; + for (i = 0; i < len; i++) { + mid = (edge[i] + edge[i + 1]) / 2; +- if (selection->x1 < mid || selection->x2 < mid) +- if (i < begin) +- begin = i; +- if (mid < selection->x1 || mid < selection->x2) +- end = i + 1; ++ if (XBetweenAB (mid, s1, s2)) ++ { ++ if (i < begin) ++ begin = i; ++ ++ end = i + 1; ++ } + } + + /* Skip empty selection. */ +@@ -4402,30 +4481,41 @@ void TextLine::visitSelection(TextSelect + TextWord *p, *begin, *end, *current; + int i, edge_begin, edge_end; + PDFRectangle child_selection; ++ double s1, s2, p_min, p_max; ++ ++ if (rot == 0 || rot == 2) { ++ s1 = selection->x1; ++ s2 = selection->x2; ++ } else { ++ s1 = selection->y1; ++ s2 = selection->y2; ++ } + + begin = NULL; + end = NULL; + current = NULL; + for (p = words; p != NULL; p = p->next) { ++ if (rot == 0 || rot == 2) { ++ p_min = p->xMin; ++ p_max = p->xMax; ++ } else { ++ p_min = p->yMin; ++ p_max = p->yMax; ++ } ++ + if (blk->page->primaryLR) { +- if ((selection->x1 < p->xMax) || +- (selection->x2 < p->xMax)) +- if (begin == NULL) +- begin = p; ++ if (((s1 < p_max) || (s2 < p_max)) && begin == NULL) ++ begin = p; + +- if (((selection->x1 > p->xMin) || +- (selection->x2 > p->xMin)) && (begin != NULL)) { ++ if (((s1 > p_min) || (s2 > p_min)) && begin != NULL) { + end = p->next; + current = p; + } + } else { +- if ((selection->x1 > p->xMin) || +- (selection->x2 > p->xMin)) +- if (begin == NULL) +- begin = p; ++ if (((s1 > p_min) || (s2 > p_min)) && begin == NULL) ++ begin = p; + +- if (((selection->x1 < p->xMax) || +- (selection->x2 < p->xMax)) && (begin != NULL)) { ++ if (((s1 < p_max) || (s2 < p_max)) && begin != NULL) { + end = p->next; + current = p; + } +@@ -4437,23 +4527,42 @@ void TextLine::visitSelection(TextSelect + + child_selection = *selection; + if (style == selectionStyleWord) { +- child_selection.x1 = begin ? begin->xMin : xMin; +- if (end && end->xMax != -1) { +- child_selection.x2 = current->xMax; ++ if (rot == 0 || rot == 2) { ++ child_selection.x1 = begin ? begin->xMin : xMin; ++ if (end && end->xMax != -1) { ++ child_selection.x2 = current->xMax; ++ } else { ++ child_selection.x2 = xMax; ++ } + } else { +- child_selection.x2 = xMax; ++ child_selection.y1 = begin ? begin->yMin : yMin; ++ if (end && end->yMax != -1) { ++ child_selection.y2 = current->yMax; ++ } else { ++ child_selection.y2 = yMax; ++ } + } + } + ++ if (rot == 0 || rot == 2) { ++ s1 = child_selection.x1; ++ s2 = child_selection.x2; ++ } else { ++ s1 = child_selection.y1; ++ s2 = child_selection.y2; ++ } ++ + edge_begin = len; + edge_end = 0; + for (i = 0; i < len; i++) { + double mid = (edge[i] + edge[i + 1]) / 2; +- if (child_selection.x1 < mid || child_selection.x2 < mid) +- if (i < edge_begin) +- edge_begin = i; +- if (mid < child_selection.x2 || mid < child_selection.x1) +- edge_end = i + 1; ++ if (XBetweenAB (mid, s1, s2)) ++ { ++ if (i < edge_begin) ++ edge_begin = i; ++ ++ edge_end = i + 1; ++ } + } + + /* Skip empty selection. */ diff --git a/SPECS/poppler.spec b/SPECS/poppler.spec new file mode 100644 index 0000000..0cd6e47 --- /dev/null +++ b/SPECS/poppler.spec @@ -0,0 +1,159 @@ +Summary: Compat package with poppler 0.22 libraries +Name: compat-poppler022 +Version: 0.22.5 +Release: 4%{?dist} +License: (GPLv2 or GPLv3) and GPLv2+ and LGPLv2+ and MIT +Group: Development/Libraries +URL: http://poppler.freedesktop.org/ +Source0: http://poppler.freedesktop.org/poppler-%{version}.tar.gz + +# https://bugzilla.redhat.com/show_bug.cgi?id=1024753 +Patch0: poppler-0.22.5-CVE-2013-4473.patch + +# https://bugzilla.redhat.com/show_bug.cgi?id=1024762 +Patch1: poppler-0.22.5-CVE-2013-4474.patch + +# https://bugzilla.redhat.com/show_bug.cgi?id=1053616 +Patch2: poppler-0.22.5-rotated-words-selection.patch + +Requires: poppler-data >= 0.4.0 +BuildRequires: automake libtool +BuildRequires: gettext-devel +BuildRequires: libjpeg-devel +BuildRequires: openjpeg-devel >= 1.3-5 +BuildRequires: pkgconfig(cairo) >= 1.10.0 +BuildRequires: pkgconfig(gobject-introspection-1.0) +BuildRequires: pkgconfig(gtk+-3.0) +BuildRequires: pkgconfig(lcms2) +BuildRequires: pkgconfig(QtGui) pkgconfig(QtXml) +BuildRequires: pkgconfig(libtiff-4) + +Conflicts: poppler < 0.24 + +%description +Compatibility package with poppler 0.22 libraries. + + +%package glib +Summary: Glib wrapper for poppler +Group: Development/Libraries +Requires: %{name}%{?_isa} = %{version}-%{release} + +Conflicts: poppler-glib < 0.24 + +%description glib +%{summary}. + + +%package qt +Summary: Qt4 wrapper for poppler +Group: System Environment/Libraries +Requires: %{name}%{?_isa} = %{version}-%{release} +%{?_qt4:Requires: qt4%{?_isa} >= %{_qt4_version}} + +Conflicts: poppler-qt < 0.24 + +%description qt +%{summary}. + + +%package cpp +Summary: Pure C++ wrapper for poppler +Group: Development/Libraries +Requires: %{name}%{?_isa} = %{version}-%{release} + +Conflicts: poppler-cpp < 0.24 + +%description cpp +%{summary}. + + +%prep +%setup -q -n poppler-%{version} +%patch0 -p1 -b .CVE-2013-4473 +%patch1 -p1 -b .CVE-2013-4474 +%patch2 -p1 -b .rotated-word-selection + +# hammer to nuke rpaths, recheck on new releases +autoreconf -i -f + +%build + +# Hack around borkage, http://cgit.freedesktop.org/poppler/poppler/commit/configure.ac?id=9250449aaa279840d789b3a7cef75d06a0fd88e7 +PATH=%{_qt4_bindir}:$PATH; export PATH + +%configure \ + --disable-static \ + --disable-gtk-test \ + --enable-cairo-output \ + --enable-libjpeg \ + --enable-libopenjpeg \ + --enable-poppler-qt4 \ + --enable-xpdf-headers \ + --disable-zlib \ + --enable-introspection=yes + +make %{?_smp_mflags} + +%install +make install DESTDIR=$RPM_BUILD_ROOT + +rm -fv $RPM_BUILD_ROOT%{_libdir}/lib*.la + +rm -rf $RPM_BUILD_ROOT%{_bindir} +rm -rf $RPM_BUILD_ROOT%{_includedir} +rm -rf $RPM_BUILD_ROOT%{_libdir}/girepository-1.0/Poppler-0.18.typelib +rm -rf $RPM_BUILD_ROOT%{_libdir}/libpoppler-cpp.so +rm -rf $RPM_BUILD_ROOT%{_libdir}/libpoppler-glib.so +rm -rf $RPM_BUILD_ROOT%{_libdir}/libpoppler-qt4.so +rm -rf $RPM_BUILD_ROOT%{_libdir}/libpoppler.so +rm -rf $RPM_BUILD_ROOT%{_libdir}/pkgconfig/ +rm -rf $RPM_BUILD_ROOT%{_datadir} + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%post glib -p /sbin/ldconfig + +%postun glib -p /sbin/ldconfig + +%post qt -p /sbin/ldconfig + +%postun qt -p /sbin/ldconfig + +%post cpp -p /sbin/ldconfig + +%postun cpp -p /sbin/ldconfig + + +%files +%doc COPYING +%{_libdir}/libpoppler.so.37* + +%files glib +%{_libdir}/libpoppler-glib.so.8* + +%files qt +%{_libdir}/libpoppler-qt4.so.4* + +%files cpp +%{_libdir}/libpoppler-cpp.so.0* + + +%changelog +* Fri Apr 24 2015 Marek Kasik - 0.22.5-4 +- Add back glib, cpp and qt frontends so that existing applications +- loads correct libpoppler.so.*. +- Resolves: #1184215 + +* Tue Apr 21 2015 Marek Kasik - 0.22.5-3 +- Don't convert utils/pdftohtml.1 to UTF-8, it is already UTF-8 +- Resolves: #1184215 + +* Mon Apr 20 2015 Marek Kasik - 0.22.5-2 +- Initial import of compat-poppler022 package +- Resolves: #1184215 + +* Wed Nov 12 2014 Kalev Lember - 0.22.5-1 +- Poppler 0.22 compat package for el7-gnome-3-14 copr