File source-poppler-0.59.1.dif of Package texlive.14236

Dear Werner,

> See attachment for figure_fsteps.pdf ...

Please test attached pdftoepdf.cc and pdftosrc.cc on SUSE.
They are working fine on windows for your example with
the poppler 0.60.1.
Simply replace pdftoepdf.cc and pdftosrc.cc in web2c/pdftexdir
by the attached files.

Thanks,
Akira

---
 texk/web2c/pdftexdir/pdftoepdf.cc |  113 +++++++++++++++++++++++---------------
 texk/web2c/pdftexdir/pdftosrc.cc  |   19 ++++--
 2 files changed, 83 insertions(+), 49 deletions(-)

--- texk/web2c/pdftexdir/pdftoepdf.cc
+++ texk/web2c/pdftexdir/pdftoepdf.cc	2017-11-07 15:57:03.960327000 +0000
@@ -1,5 +1,5 @@
 /*
-Copyright 1996-2016 Han The Thanh, <thanh@pdftex.org>
+Copyright 1996-2017 Han The Thanh, <thanh@pdftex.org>
 
 This file is part of pdfTeX.
 
@@ -17,6 +17,15 @@ You should have received a copy of the G
 with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+/*
+This is based on the patch texlive-poppler-0.59.patch <2017-09-19> at
+https://git.archlinux.org/svntogit/packages.git/plain/texlive-bin/trunk
+by Arch Linux. A little modifications are made to avoid a crash for
+some kind of pdf images, such as figure_missing.pdf in gnuplot.
+The poppler should be 0.59.0 or newer versions.
+POPPLER_VERSION should be defined.
+*/
+
 /* Do this early in order to avoid a conflict between
    MINGW32 <rpcndr.h> defining 'boolean' as 'unsigned char' and
    <kpathsea/types.h> defining Pascal's boolean as 'int'.
@@ -39,10 +48,7 @@ with this program.  If not, see <http://
 #include <goo/gfile.h>
 #define GString GooString
 #else
-#include <aconf.h>
-#include <GString.h>
-#include <gmem.h>
-#include <gfile.h>
+#error POPPLER_VERSION should be defined.
 #endif
 #include <assert.h>
 
@@ -357,10 +363,29 @@ static void copyProcSet(Object * obj)
 
 #define REPLACE_TYPE1C true
 
+static bool embeddableFont(Object * fontdesc)
+{
+    Object fontfile, ffsubtype;
+
+    if (!fontdesc->isDict())
+        return false;
+    fontfile = fontdesc->dictLookup("FontFile");
+    if (fontfile.isStream())
+        return true;
+    if (REPLACE_TYPE1C) {
+        fontfile = fontdesc->dictLookup("FontFile3");
+        if (!fontfile.isStream())
+            return false;
+        ffsubtype = fontfile.streamGetDict()->lookup("Subtype");
+        return ffsubtype.isName() && !strcmp(ffsubtype.getName(), "Type1C");
+    }
+    return false;
+}
+
 static void copyFont(char *tag, Object * fontRef)
 {
     Object fontdict, subtype, basefont, fontdescRef, fontdesc, charset,
-        fontfile, ffsubtype, stemV;
+        stemV;
     GfxFont *gfont;
     fd_entry *fd;
     fm_entry *fontmap;
@@ -377,23 +402,13 @@ static void copyFont(char *tag, Object *
     // Only handle included Type1 (and Type1C) fonts; anything else will be copied.
     // Type1C fonts are replaced by Type1 fonts, if REPLACE_TYPE1C is true.
     fontdict = fontRef->fetch(xref);
+    fontdesc = Object(objNull);
     if (fontdict.isDict()) {
         subtype = fontdict.dictLookup("Subtype");
         basefont = fontdict.dictLookup("BaseFont");
         fontdescRef = fontdict.dictLookupNF("FontDescriptor");
         if (fontdescRef.isRef()) {
             fontdesc = fontdescRef.fetch(xref);
-            if (fontdesc.isDict()) {
-                fontfile = fontdesc.dictLookup("FontFile");
-                if (!fontfile.isStream() && REPLACE_TYPE1C) {
-                    fontfile = fontdesc.dictLookup("FontFile3");
-                    ffsubtype = fontfile.streamGetDict()->lookup("Subtype");
-                    if (!(ffsubtype.isName() && !strcmp(ffsubtype.getName(), "Type1C"))) {
-                        // not a Type1-C font.
-                        fontfile = Object(objNull);
-                    }
-                }
-            }
         }
     }
     if (!fixedinclusioncopyfont && fontdict.isDict()
@@ -402,7 +417,7 @@ static void copyFont(char *tag, Object *
         && basefont.isName()
         && fontdescRef.isRef()
         && fontdesc.isDict()
-        && fontfile.isStream()
+        && embeddableFont(&fontdesc)
         && (fontmap = lookup_fontmap(basefont.getName())) != NULL) {
         // round /StemV value, since the PDF input is a float
         // (see Font Descriptors in PDF reference), but we only store an
@@ -591,9 +606,8 @@ static void copyObject(Object * obj)
         copyDict(obj);
         pdf_puts(">>");
     } else if (obj->isStream()) {
-        obj1 = Object(obj->streamGetDict());
         pdf_puts("<<\n");
-        copyDict(&obj1);
+        copyDict(obj->getStream()->getDictObject());
         pdf_puts(">>\n");
         pdf_puts("stream\n");
         copyStream(obj->getStream()->getUndecodedStream());
@@ -662,7 +676,7 @@ static void writeEncodings()
 #ifdef POPPLER_VERSION
         r->font->decRefCnt();
 #else
-        delete r->font;
+#error POPPLER_VERSION should be defined.
 #endif
         delete r;
     }
@@ -705,7 +719,7 @@ read_pdf_info(char *image_name, char *pa
 #ifdef POPPLER_VERSION
     int pdf_major_version_found, pdf_minor_version_found;
 #else
-    float pdf_version_found, pdf_version_wanted;
+#error POPPLER_VERSION should be defined.
 #endif
     // initialize
     if (!isInit) {
@@ -737,19 +751,7 @@ read_pdf_info(char *image_name, char *pa
         }
     }
 #else
-    pdf_version_found = pdf_doc->doc->getPDFVersion();
-    pdf_version_wanted = 1 + (minor_pdf_version_wanted * 0.1);
-    if (pdf_version_found > pdf_version_wanted + 0.01) {
-        char msg[] =
-            "PDF inclusion: found PDF version <%.1f>, but at most version <%.1f> allowed";
-        if (pdf_inclusion_errorlevel > 0) {
-            pdftex_fail(msg, pdf_version_found, pdf_version_wanted);
-        } else if (pdf_inclusion_errorlevel < 0) {
-            ; /* do nothing */
-        } else { /* = 0, give warning */
-            pdftex_warn(msg, pdf_version_found, pdf_version_wanted);
-        }
-    }
+#error POPPLER_VERSION should be defined.
 #endif
     epdf_num_pages = pdf_doc->doc->getCatalog()->getNumPages();
     if (page_name) {
@@ -931,12 +933,12 @@ void write_epdf(void)
             pdf_printf("/%s ", pageDictKeys[i]);
             copyObject(&dictObj); // preserves indirection
         }
-    } 
+    }
 
     // handle page group
     dictObj = pageDict->lookupNF("Group");
     if (!dictObj.isNull()) {
-        if (pdfpagegroupval == 0) { 
+        if (pdfpagegroupval == 0) {
             // another pdf with page group was included earlier on the
             // same page; copy the Group entry as is.  See manual for
             // info on why this is a warning.
@@ -953,7 +955,32 @@ void write_epdf(void)
             if (!dictObj.isDict())
                 pdftex_fail("PDF inclusion: /Group dict missing");
             writeSepGroup = true;
+/*
+This part is only a single line
             groupDict = Object(page->getGroup());
+in the original patch. In this case, however, pdftex crashes at
+"delete pdf_doc->doc" in "delete_document()" for inclusion of some
+kind of pdf images, for example, figure_missing.pdf in gnuplot.
+A change
+            groupDict = Object(page->getGroup()).copy();
+does not improve the situation.
+The changes below seem to work fine.
+*/
+// begin modification
+            groupDict = pageDict->lookup("Group");
+            const Dict& dic1 = page->getGroup();
+            const Dict& dic2 = groupDict.getDict();
+            // replace dic2 in groupDict with dic1
+            l = dic2.getLength();
+            for (i = 0; i < l; i++) {
+                groupDict.dictRemove(dic2.getKey(i));
+            }
+            l = dic1.getLength();
+            for (i = 0; i < l; i++) {
+                groupDict.dictAdd(copyString(dic1.getKey(i)),
+                                  dic1.getValNF(i));
+            }
+// end modification
             pdf_printf("/Group %ld 0 R\n", (long)pdfpagegroupval);
         }
     }
@@ -966,15 +993,15 @@ void write_epdf(void)
         pdftex_warn
             ("PDF inclusion: /Resources missing. 'This practice is not recommended' (PDF Ref)");
     } else {
-        obj1 = Object(page->getResourceDict());
-        if (!obj1.isDict())
+        Object *obj1 = page->getResourceDictObject();
+        if (!obj1->isDict())
             pdftex_fail("PDF inclusion: invalid resources dict type <%s>",
-                        obj1.getTypeName());
+                        obj1->getTypeName());
         pdf_newline();
         pdf_puts("/Resources <<\n");
-        for (i = 0, l = obj1.dictGetLength(); i < l; ++i) {
-            obj2 = obj1.dictGetVal(i);
-            key = obj1.dictGetKey(i);
+        for (i = 0, l = obj1->dictGetLength(); i < l; ++i) {
+            obj2 = obj1->dictGetVal(i);
+            key = obj1->dictGetKey(i);
             if (strcmp("Font", key) == 0)
                 copyFontResources(&obj2);
             else if (strcmp("ProcSet", key) == 0)
--- texk/web2c/pdftexdir/pdftosrc.cc
+++ texk/web2c/pdftexdir/pdftosrc.cc	2017-11-07 15:57:11.068340000 +0000
@@ -1,5 +1,5 @@
 /*
-Copyright 1996-2014 Han The Thanh, <thanh@pdftex.org>
+Copyright 1996-2017 Han The Thanh, <thanh@pdftex.org>
 
 This file is part of pdfTeX.
 
@@ -16,6 +16,14 @@ GNU General Public License for more deta
 You should have received a copy of the GNU General Public License along
 with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
+
+/*
+This is based on the patch texlive-poppler-0.59.patch <2017-09-19> at
+https://git.archlinux.org/svntogit/packages.git/plain/texlive-bin/trunk
+by Arch Linux. The poppler should be 0.59.0 or newer versions.
+POPPLER_VERSION should be defined.
+*/
+
 #include <w2c/config.h>
 
 #include <stdlib.h>
@@ -32,10 +40,7 @@ with this program.  If not, see <http://
 #include <goo/gmem.h>
 #include <goo/gfile.h>
 #else
-#include <aconf.h>
-#include <GString.h>
-#include <gmem.h>
-#include <gfile.h>
+#error POPPLER_VERSION should be defined.
 #endif
 #include <assert.h>
 
@@ -151,6 +156,7 @@ int main(int argc, char *argv[])
                         (e->type == xrefEntryFree ? "f" : "n"));
             else {              // e->offset is the object number of the object stream
                 Stream *str;
+                Lexer *lexer;
                 Parser *parser;
                 Object objStr, obj1, obj2;
                 int nObjects, first, n;
@@ -168,7 +174,8 @@ int main(int argc, char *argv[])
                 // parse the header: object numbers and offsets
                 objStr.streamReset();
                 str = new EmbedStream(objStr.getStream(), Object(objNull), gTrue, first);
-                parser = new Parser(xref, new Lexer(xref, str), gFalse);
+                lexer = new Lexer(xref, str);
+                parser = new Parser(xref, lexer, gFalse);
                 for (n = 0; n < nObjects; ++n) {
                     obj1 = parser->getObj();
                     obj2 = parser->getObj();
openSUSE Build Service is sponsored by