From 39704fa7922c08adf6f6cb852971352cbb3813a0 Mon Sep 17 00:00:00 2001 From: Zdenek Dohnal Date: Wed, 26 Feb 2020 15:10:53 +0100 Subject: [PATCH] 1806862 - foomatic-rip handles empty files in bad way --- cups-filters.spec | 7 +- foomatic-rip-fix-empty-output.patch | 193 ++++++++++++++++++++++++++++ 2 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 foomatic-rip-fix-empty-output.patch diff --git a/cups-filters.spec b/cups-filters.spec index dc80e52..81e0c8c 100644 --- a/cups-filters.spec +++ b/cups-filters.spec @@ -4,7 +4,7 @@ Summary: OpenPrinting CUPS filters and backends Name: cups-filters Version: 1.27.1 -Release: 1%{?dist} +Release: 2%{?dist} # For a breakdown of the licensing, see COPYING file # GPLv2: filters: commandto*, imagetoraster, pdftops, rasterto*, @@ -30,6 +30,7 @@ Patch02: cups-browsed.8.patch # crash on uninitialized string # reported upstream https://github.com/OpenPrinting/cups-filters/pull/204 Patch03: cups-filters-abrt.patch +Patch04: foomatic-rip-fix-empty-output.patch Requires: cups-filters-libs%{?_isa} = %{version}-%{release} @@ -142,6 +143,7 @@ This is the development package for OpenPrinting CUPS filters and backends. %patch02 -p1 -b .manpage # crash in cups-browsed %patch03 -p1 -b .abrt +%patch04 -p1 -b .empty-output %build # work-around Rpath @@ -310,6 +312,9 @@ done %{_libdir}/libfontembed.so %changelog +* Tue Feb 25 2020 Zdenek Dohnal - 1.27.1-2 +- 1806862 - foomatic-rip handles empty files in bad way + * Tue Feb 18 2020 Zdenek Dohnal - 1.27.1-1 - 1.27.1 diff --git a/foomatic-rip-fix-empty-output.patch b/foomatic-rip-fix-empty-output.patch new file mode 100644 index 0000000..e9f67bc --- /dev/null +++ b/foomatic-rip-fix-empty-output.patch @@ -0,0 +1,193 @@ +diff --git a/filter/foomatic-rip/foomaticrip.c b/filter/foomatic-rip/foomaticrip.c +index 73ef28c..fb1c253 100644 +--- a/filter/foomatic-rip/foomaticrip.c ++++ b/filter/foomatic-rip/foomaticrip.c +@@ -560,8 +560,10 @@ int print_file(const char *filename, int convert) + { + FILE *file; + char buf[8192]; ++ char tmpfilename[PATH_MAX]; + int type; + int startpos; ++ int pagecount; + size_t n; + int ret; + +@@ -603,7 +605,6 @@ int print_file(const char *filename, int convert) + char pdf2ps_cmd[CMDLINE_MAX]; + FILE *out, *in; + int renderer_pid; +- char tmpfilename[PATH_MAX] = ""; + + _log("Driver does not understand PDF input, " + "converting to PostScript\n"); +@@ -615,7 +616,7 @@ int print_file(const char *filename, int convert) + { + int fd; + FILE *tmpfile; +- ++ + snprintf(tmpfilename, PATH_MAX, "%s/foomatic-XXXXXX", temp_dir()); + fd = mkstemp(tmpfilename); + if (fd < 0) { +@@ -625,7 +626,7 @@ int print_file(const char *filename, int convert) + tmpfile = fdopen(fd, "r+"); + copy_file(tmpfile, stdin, buf, n); + fclose(tmpfile); +- ++ + filename = tmpfilename; + } + +@@ -668,6 +669,16 @@ int print_file(const char *filename, int convert) + "Couldn't dup stdout of pdf-to-ps\n"); + + clearerr(stdin); ++ pagecount = pdf_count_pages(filename); ++ _log("File contains %d pages.\n", pagecount); ++ if (pagecount < 0) { ++ _log("Unexpected page_count\n"); ++ return 0; ++ } ++ if (pagecount == 0) { ++ _log("No pages left, outputting empty file.\n"); ++ return 1; ++ } + ret = print_file("", 0); + + wait_for_process(renderer_pid); +@@ -687,7 +698,75 @@ int print_file(const char *filename, int convert) + case PS_FILE: + _log("Filetype: PostScript\n"); + if (file == stdin) +- return print_ps(stdin, buf, n, filename); ++ { ++ if (convert) ++ { ++ int fd; ++ FILE *tmpfile; ++ ++ snprintf(tmpfilename, PATH_MAX, "%s/foomatic-XXXXXX", temp_dir()); ++ fd = mkstemp(tmpfilename); ++ if (fd < 0) { ++ _log("Could not create temporary file: %s\n", strerror(errno)); ++ return EXIT_PRNERR_NORETRY_BAD_SETTINGS; ++ } ++ ++ /* Copy already read data to the tmp file */ ++ if (write(fd,buf,n) != n) { ++ _log("ERROR: Can't copy already read data to temporary file\n"); ++ close(fd); ++ } ++ /* Copy stdin to the tmp file */ ++ while ((n = read(0,buf,BUFSIZ)) > 0) { ++ if (write(fd,buf,n) != n) { ++ _log("ERROR: Can't copy stdin to temporary file\n"); ++ close(fd); ++ } ++ } ++ /* Rewind tmp file to read it again */ ++ if (lseek(fd,0,SEEK_SET) < 0) { ++ _log("ERROR: Can't rewind temporary file\n"); ++ close(fd); ++ } ++ ++ char gscommand[65536]; ++ char output[31] = ""; ++ int pagecount; ++ size_t bytes; ++ filename = strdup(tmpfilename); ++ snprintf(gscommand, 65536, "%s -q -dNOPAUSE -dBATCH -sDEVICE=bbox %s 2>&1 | grep -c HiResBoundingBox", ++ CUPS_GHOSTSCRIPT, filename); ++ FILE *pd = popen(gscommand, "r"); ++ bytes = fread(output, 1, 31, pd); ++ pclose(pd); ++ ++ if (bytes <= 0 || sscanf(output, "%d", &pagecount) < 1) ++ pagecount = -1; ++ ++ if (pagecount < 0) { ++ _log("Unexpected page_count\n"); ++ return 0; ++ } ++ ++ if (pagecount == 0) { ++ _log("No pages left, outputting empty file.\n"); ++ return 1; ++ } ++ ++ _log("File contains %d pages.\n", pagecount); ++ ++ if ((tmpfile = fdopen(fd,"rb")) == 0) { ++ _log("ERROR: Can't fdopen temporary file\n"); ++ close(fd); ++ } ++ ret = print_ps(tmpfile, NULL, 0, filename); ++ fclose(tmpfile); ++ unlink(tmpfilename); ++ return ret; ++ } ++ else ++ return print_ps(stdin, buf, n, filename); ++ } + else + return print_ps(file, NULL, 0, filename); + +diff --git a/filter/foomatic-rip/pdf.c b/filter/foomatic-rip/pdf.c +index 1631f96..7364a73 100644 +--- a/filter/foomatic-rip/pdf.c ++++ b/filter/foomatic-rip/pdf.c +@@ -39,7 +39,7 @@ + static int wait_for_renderer(); + + +-static int pdf_count_pages(const char *filename) ++int pdf_count_pages(const char *filename) + { + char gscommand[CMDLINE_MAX]; + char output[63] = ""; +diff --git a/filter/foomatic-rip/pdf.h b/filter/foomatic-rip/pdf.h +index c9472a0..07e2f32 100644 +--- a/filter/foomatic-rip/pdf.h ++++ b/filter/foomatic-rip/pdf.h +@@ -25,6 +25,7 @@ + #define pdf_h + + int print_pdf(FILE *s, const char *alreadyread, size_t len, const char *filename, size_t startpos); ++int pdf_count_pages(const char *filemame); + + #endif + +diff --git a/filter/foomatic-rip/postscript.c b/filter/foomatic-rip/postscript.c +index 8b6f0ad..f0ddf01 100644 +--- a/filter/foomatic-rip/postscript.c ++++ b/filter/foomatic-rip/postscript.c +@@ -322,7 +322,6 @@ void _print_ps(stream_t *stream) + pid_t rendererpid = 0; + FILE *rendererhandle = NULL; + +- int empty = 1; + int retval; + + dstr_t *tmp = create_dstr(); +@@ -1010,7 +1009,6 @@ void _print_ps(stream_t *stream) + /* No renderer running, start it */ + dstrcpy(tmp, psheader->data); + dstrcat(tmp, psfifo->data); +- empty = 0; + get_renderer_handle(tmp, &rendererhandle, &rendererpid); + /* psfifo is sent out, flush it */ + dstrclear(psfifo); +@@ -1075,12 +1073,6 @@ void _print_ps(stream_t *stream) + + } while ((maxlines == 0 || linect < maxlines) && more_stuff != 0); + +- if (empty) +- { +- _log("No pages left, outputting empty file.\n"); +- return; +- } +- + /* Some buffer still containing data? Send it out to the renderer */ + if (more_stuff || inheader || !isempty(psfifo->data)) { + /* Flush psfifo and send the remaining data to the renderer, this