1806862 - foomatic-rip handles empty files in bad way

This commit is contained in:
Zdenek Dohnal 2020-02-26 15:10:53 +01:00
parent 3606bde648
commit 39704fa792
2 changed files with 199 additions and 1 deletions

View File

@ -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 <zdohnal@redhat.com> - 1.27.1-2
- 1806862 - foomatic-rip handles empty files in bad way
* Tue Feb 18 2020 Zdenek Dohnal <zdohnal@redhat.com> - 1.27.1-1
- 1.27.1

View File

@ -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("<STDIN>", 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