diff --git a/SOURCES/0001-Bug-701568-Fix-gdevpx.c-RLE-stream-handling.patch b/SOURCES/0001-Bug-701568-Fix-gdevpx.c-RLE-stream-handling.patch new file mode 100644 index 0000000..abc44da --- /dev/null +++ b/SOURCES/0001-Bug-701568-Fix-gdevpx.c-RLE-stream-handling.patch @@ -0,0 +1,64 @@ +From 68c7275d4a580dca6c0ed3798f3717eea3513403 Mon Sep 17 00:00:00 2001 +From: Robin Watts +Date: Thu, 12 Sep 2019 09:35:01 +0100 +Subject: [PATCH] Bug 701568: Fix gdevpx.c RLE stream handling. + +The current code in pclxl_write_image_data_RLE passes +lines of data to the RLE compression routine. It tells +each invocation of that routine that this is the "last" +block of data, when clearly it is not. + +Accordingly, the compression routine inserts the "EOD" byte +into the stream, and returns EOFC. + +Independently of the return value used, having multiple EOD +bytes in the data is clearly wrong. Update the caller to only +pass "last" in for the last block. + +The code still returns EOFC at the end of the data, so update +this final call to accept (indeed, expect) that return value +there. +--- + devices/vector/gdevpx.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/devices/vector/gdevpx.c b/devices/vector/gdevpx.c +index 825e6b4c5..5d2d0edf5 100644 +--- a/devices/vector/gdevpx.c ++++ b/devices/vector/gdevpx.c +@@ -714,6 +714,7 @@ pclxl_write_image_data_RLE(gx_device_pclxl * xdev, const byte * base, + uint num_bytes = ROUND_UP(width_bytes, 4) * height; + bool compress = num_bytes >= 8; + int i; ++ int code; + + /* cannot handle data_bit not multiple of 8, but we don't invoke this routine that way */ + int offset = data_bit >> 3; +@@ -752,19 +753,20 @@ pclxl_write_image_data_RLE(gx_device_pclxl * xdev, const byte * base, + r.ptr = data + i * raster - 1; + r.limit = r.ptr + width_bytes; + if ((*s_RLE_template.process) +- ((stream_state *) & rlstate, &r, &w, true) != 0 || ++ ((stream_state *) & rlstate, &r, &w, false) != 0 || + r.ptr != r.limit) + goto ncfree; + r.ptr = (const byte *)"\000\000\000\000\000"; + r.limit = r.ptr + (-(int)width_bytes & 3); + if ((*s_RLE_template.process) +- ((stream_state *) & rlstate, &r, &w, true) != 0 || ++ ((stream_state *) & rlstate, &r, &w, false) != 0 || + r.ptr != r.limit) + goto ncfree; + } + r.ptr = r.limit; +- if ((*s_RLE_template.process) +- ((stream_state *) & rlstate, &r, &w, true) != 0) ++ code = (*s_RLE_template.process) ++ ((stream_state *) & rlstate, &r, &w, true); ++ if (code != EOFC && code != 0) + goto ncfree; + { + uint count = w.ptr + 1 - buf; +-- +2.46.2 + diff --git a/SOURCES/0001-Bug-701568-followup-Fix-RLE-compressor.patch b/SOURCES/0001-Bug-701568-followup-Fix-RLE-compressor.patch new file mode 100644 index 0000000..51a8604 --- /dev/null +++ b/SOURCES/0001-Bug-701568-followup-Fix-RLE-compressor.patch @@ -0,0 +1,118 @@ +From 3b2ad1f24d2e9705481f9feb6835aa3e851726ac Mon Sep 17 00:00:00 2001 +From: Robin Watts +Date: Thu, 12 Sep 2019 17:09:50 +0100 +Subject: [PATCH] Bug 701568 followup: Fix RLE compressor. + +The previous fix to the RLE compressor reveals an additional +existing issue to do with us not checking whether we have +space in the buffer to write the EOD byte. + +Fixed here. +--- + base/srle.c | 78 ++++++++++++++++++++++++++++++----------------------- + 1 file changed, 45 insertions(+), 33 deletions(-) + +diff --git a/base/srle.c b/base/srle.c +index 50de0d847..0c0186e04 100644 +--- a/base/srle.c ++++ b/base/srle.c +@@ -59,7 +59,13 @@ enum { + state_gt_012, + + /* -n bytes into a repeated run, n0 and n1 read. */ +- state_lt_01 ++ state_lt_01, ++ ++ /* We have reached the end of data, but not written the marker. */ ++ state_eod_unmarked, ++ ++ /* We have reached the end of data, and written the marker. */ ++ state_eod + }; + + #ifdef DEBUG_RLE +@@ -294,43 +300,49 @@ run_len_0_n0_read: + } + } + } +- } +- /* n1 is never valid here */ ++ /* n1 is never valid here */ + +- if (last) { +- if (run_len == 0) { +- /* EOD */ +- if (wlimit - q < 1) { +- ss->state = state_0; +- goto no_output_room; +- } +- } else if (run_len > 0) { +- /* Flush literal run + EOD */ +- if (wlimit - q < run_len+2) { +- ss->state = state_0; +- goto no_output_room; ++ if (last) { ++ if (run_len == 0) { ++ /* EOD */ ++ if (wlimit - q < 1) { ++ ss->state = state_0; ++ goto no_output_room; ++ } ++ } else if (run_len > 0) { ++ /* Flush literal run + EOD */ ++ if (wlimit - q < run_len+2) { ++ ss->state = state_0; ++ goto no_output_room; ++ } ++ *++q = run_len; ++ memcpy(q+1, ss->literals, run_len); ++ q += run_len; ++ *++q = n0; ++ } else if (run_len < 0) { ++ /* Flush repeated run + EOD */ ++ if (wlimit - q < 3) { ++ ss->state = state_0; ++ goto no_output_room; ++ } ++ *++q = 257+run_len; /* Repeated run */ ++ *++q = n0; + } +- *++q = run_len; +- memcpy(q+1, ss->literals, run_len); +- q += run_len; +- *++q = n0; +- } else if (run_len < 0) { +- /* Flush repeated run + EOD */ +- if (wlimit - q < 3) { +- ss->state = state_0; ++ case state_eod_unmarked: ++ if (wlimit - q < 1) { ++ ss->state = state_eod_unmarked; + goto no_output_room; + } +- *++q = 257+run_len; /* Repeated run */ +- *++q = n0; ++ *++q = 128; /* EOD */ ++ case state_eod: ++ ss->run_len = 0; ++ ss->state = state_0; ++ pr->ptr = p; ++ pw->ptr = q; ++ ss->record_left = rlimit - p; ++ debug_ate(pinit, p, qinit, q, EOFC); ++ return EOFC; + } +- *++q = 128; /* EOD */ +- ss->run_len = 0; +- ss->state = state_0; +- pr->ptr = p; +- pw->ptr = q; +- ss->record_left = rlimit - p; +- debug_ate(pinit, p, qinit, q, EOFC); +- return EOFC; + } + + /* Normal exit */ +-- +2.46.2 + diff --git a/SOURCES/0001-Bug-701949-Add-omitEOD-flag-to-RLE-compressor-and-us.patch b/SOURCES/0001-Bug-701949-Add-omitEOD-flag-to-RLE-compressor-and-us.patch new file mode 100644 index 0000000..bbd2591 --- /dev/null +++ b/SOURCES/0001-Bug-701949-Add-omitEOD-flag-to-RLE-compressor-and-us.patch @@ -0,0 +1,101 @@ +From b772aaf901a3cd37baf5c06eb141c689829bf673 Mon Sep 17 00:00:00 2001 +From: Robin Watts +Date: Tue, 26 Nov 2019 14:35:05 +0000 +Subject: [PATCH] Bug 701949: Add 'omitEOD' flag to RLE compressor and use for + PXL. + +It turns out that some printers (Samsung ML-2250 and Canon +ImageRunner iRC2380i at least) object to the EOD byte appearing +in RLE data in PXL streams. + +Ken kindly checked the PXL spec for me, and found that: "The PXL +spec does say a control code of -128 is ignored and not included +in the decompressed data and the byte following a control byte +of 128 (I assume they mean -128 here) is treated as the next +control byte. And PCL only uses RLE data for images, so they do +know how much data they expect." + +Thus, the conclusion we reached is that PCL/PXL don't need +(indeed, really does not want) the EOD byte. + +The Postscript spec clearly defines the EOD byte though. Rather +than break the streams for postscript, we introduce a flag +'omitEOD' that can be set for the encoder when we want to produce +a stream for use with PCL/PXL. +--- + base/srle.c | 10 ++++++---- + base/srlx.h | 3 ++- + devices/vector/gdevpx.c | 1 + + psi/zfilter.c | 1 + + 4 files changed, 10 insertions(+), 5 deletions(-) + +diff --git a/base/srle.c b/base/srle.c +index 0c0186e04..21b729f31 100644 +--- a/base/srle.c ++++ b/base/srle.c +@@ -329,11 +329,13 @@ run_len_0_n0_read: + *++q = n0; + } + case state_eod_unmarked: +- if (wlimit - q < 1) { +- ss->state = state_eod_unmarked; +- goto no_output_room; ++ if (!ss->omitEOD) { ++ if (wlimit - q < 1) { ++ ss->state = state_eod_unmarked; ++ goto no_output_room; ++ } ++ *++q = 128; /* EOD */ + } +- *++q = 128; /* EOD */ + case state_eod: + ss->run_len = 0; + ss->state = state_0; +diff --git a/base/srlx.h b/base/srlx.h +index ebf172064..98309dbdb 100644 +--- a/base/srlx.h ++++ b/base/srlx.h +@@ -32,6 +32,7 @@ typedef struct stream_RLE_state_s { + stream_RL_state_common; + /* The following parameters are set by the client. */ + ulong record_size; ++ bool omitEOD; + /* The following change dynamically. */ + ulong record_left; /* bytes left in current record */ + byte n0; +@@ -47,7 +48,7 @@ typedef struct stream_RLE_state_s { + /* We define the initialization procedure here, so that clients */ + /* can avoid a procedure call. */ + #define s_RLE_set_defaults_inline(ss)\ +- ((ss)->EndOfData = true, (ss)->record_size = 0) ++ ((ss)->EndOfData = true, (ss)->omitEOD = false, (ss)->record_size = 0) + #define s_RLE_init_inline(ss)\ + ((ss)->record_left =\ + ((ss)->record_size == 0 ? ((ss)->record_size = max_uint) :\ +diff --git a/devices/vector/gdevpx.c b/devices/vector/gdevpx.c +index 5d2d0edf5..a1fce1b7c 100644 +--- a/devices/vector/gdevpx.c ++++ b/devices/vector/gdevpx.c +@@ -741,6 +741,7 @@ pclxl_write_image_data_RLE(gx_device_pclxl * xdev, const byte * base, + goto nc; + s_RLE_set_defaults_inline(&rlstate); + rlstate.EndOfData = false; ++ rlstate.omitEOD = true; + s_RLE_init_inline(&rlstate); + w.ptr = buf - 1; + w.limit = w.ptr + num_bytes; +diff --git a/psi/zfilter.c b/psi/zfilter.c +index dfe3a1d5b..3ce7652c6 100644 +--- a/psi/zfilter.c ++++ b/psi/zfilter.c +@@ -109,6 +109,7 @@ zRLE(i_ctx_t *i_ctx_p) + stream_RLE_state state; + int code; + ++ s_RLE_template.set_defaults((stream_state *)&state); + check_op(2); + code = rl_setup(op - 1, &state.EndOfData); + if (code < 0) +-- +2.47.0 + diff --git a/SPECS/ghostscript.spec b/SPECS/ghostscript.spec index 5d1ae4d..dcf52c8 100644 --- a/SPECS/ghostscript.spec +++ b/SPECS/ghostscript.spec @@ -37,7 +37,7 @@ Name: ghostscript Summary: Interpreter for PostScript language & PDF Version: 9.27 -Release: 13%{?dist} +Release: 15%{?dist} License: AGPLv3+ @@ -123,6 +123,13 @@ Patch023: ghostscript-9.27-avoid-divide-by-zero-in-devices.patch # Downside of the fix is if someone depends on unsafe settings of driver for OPVP device # (via Postscript code in command -c, via Postscript code in input file), gs will start to fail. Patch024: gs-cve-2024-33871.patch +# RHEL-61729 Ghostscript is generating PJL of a significantly larger size +# Patches: 0001-Bug-701568-Fix-gdevpx.c-RLE-stream-handling.patch +# 0001-Bug-701568-followup-Fix-RLE-compressor.patch +# 0001-Bug-701949-Add-omitEOD-flag-to-RLE-compressor-and-us.patch +Patch025: 0001-Bug-701568-Fix-gdevpx.c-RLE-stream-handling.patch +Patch026: 0001-Bug-701568-followup-Fix-RLE-compressor.patch +Patch027: 0001-Bug-701949-Add-omitEOD-flag-to-RLE-compressor-and-us.patch # Downstream patches -- these should be always included when doing rebase: @@ -463,6 +470,12 @@ done # ============================================================================= %changelog +* Mon Oct 14 2024 Zdenek Dohnal - 9.27-15 +- fix printing PCL XL on some printers + +* Thu Oct 10 2024 Zdenek Dohnal - 9.27-14 +- RHEL-61729 Ghostscript is generating PJL of a significantly larger size + * Wed Jun 12 2024 Zdenek Dohnal - 9.27-13 - CVE-2024-33871 ghostscript: OPVP device arbitrary code execution via custom Driver library