Compare commits
	
		
			No commits in common. "c8" and "c9-beta" have entirely different histories.
		
	
	
		
	
		
| @ -1 +1 @@ | |||||||
| f926d2cfb418a7c5d92dce0a9843fa01ee62fe2c SOURCES/ghostscript-9.27.tar.xz | 23cce513d4e80504da0778e4ce6f05db73ae2bee SOURCES/ghostscript-9.54.0.tar.xz | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1 +1 @@ | |||||||
| SOURCES/ghostscript-9.27.tar.xz | SOURCES/ghostscript-9.54.0.tar.xz | ||||||
|  | |||||||
| @ -1,64 +0,0 @@ | |||||||
| From 68c7275d4a580dca6c0ed3798f3717eea3513403 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Robin Watts <Robin.Watts@artifex.com> |  | ||||||
| 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 |  | ||||||
| 
 |  | ||||||
| @ -1,118 +0,0 @@ | |||||||
| From 3b2ad1f24d2e9705481f9feb6835aa3e851726ac Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Robin Watts <Robin.Watts@artifex.com> |  | ||||||
| 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 |  | ||||||
| 
 |  | ||||||
| @ -1,31 +0,0 @@ | |||||||
| From 4f6bc662909ab79e8fbe9822afb36e8a0eafc2b7 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Julian Smith <jules@op59.net> |  | ||||||
| Date: Wed, 6 Nov 2019 12:41:28 +0000 |  | ||||||
| Subject: [PATCH] Bug 701844: fixed output buffer size worst case in |  | ||||||
|  lp8000_print_page(). |  | ||||||
| 
 |  | ||||||
| Fixes: |  | ||||||
|     ./sanbin/gs -dBATCH -dNOPAUSE -dSAFER -dFIXEDMEDIA -sPAPERSIZE=legal -sOutputFile=tmp -sDEVICE=lp8000 ../bug-701844.pdf |  | ||||||
| ---
 |  | ||||||
|  devices/gdevlp8k.c | 5 ++++- |  | ||||||
|  1 file changed, 4 insertions(+), 1 deletion(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/devices/gdevlp8k.c b/devices/gdevlp8k.c
 |  | ||||||
| index 0a9bc03c8..55af94df0 100644
 |  | ||||||
| --- a/devices/gdevlp8k.c
 |  | ||||||
| +++ b/devices/gdevlp8k.c
 |  | ||||||
| @@ -185,7 +185,10 @@ lp8000_print_page(gx_device_printer *pdev, gp_file *prn_stream)
 |  | ||||||
|          unsigned int report_size; |  | ||||||
|   |  | ||||||
|          byte *buf1 = (byte *)gs_malloc(pdev->memory, in_size, 1, "lp8000_print_page(buf1)"); |  | ||||||
| -        byte *buf2 = (byte *)gs_malloc(pdev->memory, in_size, 1, "lp8000_print_page(buf2)");
 |  | ||||||
| +
 |  | ||||||
| +        /* Worst case for rle compression below is 3 bytes for each 2 bytes of
 |  | ||||||
| +        input, with extra final byte. */
 |  | ||||||
| +        byte *buf2 = (byte *)gs_malloc(pdev->memory, in_size * 3 / 2 + 2, 1, "lp8000_print_page(buf2)");
 |  | ||||||
|          byte *in = buf1; |  | ||||||
|          byte *out = buf2; |  | ||||||
|   |  | ||||||
| -- 
 |  | ||||||
| 2.49.0 |  | ||||||
| 
 |  | ||||||
| @ -1,101 +0,0 @@ | |||||||
| From b772aaf901a3cd37baf5c06eb141c689829bf673 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Robin Watts <Robin.Watts@artifex.com> |  | ||||||
| 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 |  | ||||||
| 
 |  | ||||||
| @ -1,239 +0,0 @@ | |||||||
| From 4fcf527584da20538ebf9c3c43c3fda25d97cd18 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Robin Watts <Robin.Watts@artifex.com> |  | ||||||
| Date: Tue, 4 Oct 2022 17:36:56 +0100 |  | ||||||
| Subject: [PATCH] Bug 705911: Fix Ghostscript's encoding/decoding of UTF-8 from |  | ||||||
|  UTF-16. |  | ||||||
| 
 |  | ||||||
| We were not coping with high/low surrogate pairs in UTF-16, |  | ||||||
| meaning that we could encode/decode strings fine for our own |  | ||||||
| purposes, but when we passed them off to other users (such |  | ||||||
| as SmartOffice), it would fail to understand our utf-8 encoded |  | ||||||
| surrogate pairs. |  | ||||||
| 
 |  | ||||||
| Thanks to Pete, Joseph and Fred for their help here, and to Silver |  | ||||||
| for having spotted it! |  | ||||||
| ---
 |  | ||||||
|  base/gp_wutf8.c | 162 +++++++++++++++++++++++++++++++++++++----------- |  | ||||||
|  1 file changed, 127 insertions(+), 35 deletions(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/base/gp_wutf8.c b/base/gp_wutf8.c
 |  | ||||||
| index b7b1d0758..920114cd1 100644
 |  | ||||||
| --- a/base/gp_wutf8.c
 |  | ||||||
| +++ b/base/gp_wutf8.c
 |  | ||||||
| @@ -16,6 +16,56 @@
 |  | ||||||
|   |  | ||||||
|  #include "windows_.h" |  | ||||||
|   |  | ||||||
| +static int
 |  | ||||||
| +decode_utf8(const char **inp, unsigned int i)
 |  | ||||||
| +{
 |  | ||||||
| +    const char *in = *inp;
 |  | ||||||
| +    unsigned char c;
 |  | ||||||
| +
 |  | ||||||
| +    if (i < 0x80) {
 |  | ||||||
| +    } else if ((i & 0xE0) == 0xC0) {
 |  | ||||||
| +        i &= 0x1F;
 |  | ||||||
| +        c = (unsigned char)*in++;
 |  | ||||||
| +        if ((c & 0xC0) != 0x80)
 |  | ||||||
| +            goto fail;
 |  | ||||||
| +        i = (i<<6) | (c & 0x3f);
 |  | ||||||
| +    } else if ((i & 0xF0) == 0xE0) {
 |  | ||||||
| +        i &= 0xF;
 |  | ||||||
| +        c = (unsigned char)*in++;
 |  | ||||||
| +        if ((c & 0xC0) != 0x80)
 |  | ||||||
| +            goto fail;
 |  | ||||||
| +        i = (i<<6) | (c & 0x3f);
 |  | ||||||
| +        c = (unsigned char)*in++;
 |  | ||||||
| +        if ((c & 0xC0) != 0x80)
 |  | ||||||
| +            goto fail;
 |  | ||||||
| +        i = (i<<6) | (c & 0x3f);
 |  | ||||||
| +    } else if ((i & 0xF8) == 0xF0) {
 |  | ||||||
| +        i &= 0x7;
 |  | ||||||
| +        c = (unsigned char)*in++;
 |  | ||||||
| +        if ((c & 0xC0) != 0x80)
 |  | ||||||
| +            goto fail;
 |  | ||||||
| +        i = (i<<6) | (c & 0x3f);
 |  | ||||||
| +        c = (unsigned char)*in++;
 |  | ||||||
| +        if ((c & 0xC0) != 0x80)
 |  | ||||||
| +            goto fail;
 |  | ||||||
| +        i = (i<<6) | (c & 0x3f);
 |  | ||||||
| +        c = (unsigned char)*in++;
 |  | ||||||
| +        if ((c & 0xC0) != 0x80)
 |  | ||||||
| +            goto fail;
 |  | ||||||
| +        i = (i<<6) | (c & 0x3f);
 |  | ||||||
| +    }
 |  | ||||||
| +    if (0)
 |  | ||||||
| +    {
 |  | ||||||
| +        /* If we fail, unread the last one, and return the unicode replacement char. */
 |  | ||||||
| +fail:
 |  | ||||||
| +       in--;
 |  | ||||||
| +       i = 0xfffd;
 |  | ||||||
| +    }
 |  | ||||||
| +    *inp = in;
 |  | ||||||
| +
 |  | ||||||
| +    return i;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
|  int utf8_to_wchar(wchar_t *out, const char *in) |  | ||||||
|  { |  | ||||||
|      unsigned int i; |  | ||||||
| @@ -24,47 +74,37 @@ int utf8_to_wchar(wchar_t *out, const char *in)
 |  | ||||||
|   |  | ||||||
|      if (out) { |  | ||||||
|          while (i = *(unsigned char *)in++) { |  | ||||||
| -            if (i < 0x80) {
 |  | ||||||
| -                *out++ = (wchar_t)i;
 |  | ||||||
| -                len++;
 |  | ||||||
| -            } else if ((i & 0xE0) == 0xC0) {
 |  | ||||||
| -                i &= 0x1F;
 |  | ||||||
| -                c = (unsigned char)*in++;
 |  | ||||||
| -                if ((c & 0xC0) != 0x80)
 |  | ||||||
| -                    return -1;
 |  | ||||||
| -                i = (i<<6) | (c & 0x3f);
 |  | ||||||
| -                *out++ = (wchar_t)i;
 |  | ||||||
| -                len++;
 |  | ||||||
| -            } else if ((i & 0xF0) == 0xE0) {
 |  | ||||||
| -                i &= 0xF;
 |  | ||||||
| -                c = (unsigned char)*in++;
 |  | ||||||
| -                if ((c & 0xC0) != 0x80)
 |  | ||||||
| -                    return -1;
 |  | ||||||
| -                i = (i<<6) | (c & 0x3f);
 |  | ||||||
| -                c = (unsigned char)*in++;
 |  | ||||||
| -                if ((c & 0xC0) != 0x80)
 |  | ||||||
| -                    return -1;
 |  | ||||||
| -                i = (i<<6) | (c & 0x3f);
 |  | ||||||
| -                *out++ = (wchar_t)i;
 |  | ||||||
| +            /* Decode UTF-8 */
 |  | ||||||
| +            i = decode_utf8(&in, i);
 |  | ||||||
| +
 |  | ||||||
| +            /* Encode, allowing for surrogates. */
 |  | ||||||
| +            if (i >= 0x10000 && i <= 0x10ffff)
 |  | ||||||
| +            {
 |  | ||||||
| +                i -= 0x10000;
 |  | ||||||
| +                *out++ = 0xd800 + (i>>10);
 |  | ||||||
| +                *out++ = 0xdc00 + (i & 0x3ff);
 |  | ||||||
|                  len++; |  | ||||||
| -            } else {
 |  | ||||||
| +            }
 |  | ||||||
| +            else if (i > 0x10000)
 |  | ||||||
| +            {
 |  | ||||||
|                  return -1; |  | ||||||
|              } |  | ||||||
| +            else
 |  | ||||||
| +                *out++ = (wchar_t)i;
 |  | ||||||
| +            len++;
 |  | ||||||
|          } |  | ||||||
|          *out = 0; |  | ||||||
|      } else { |  | ||||||
|          while (i = *(unsigned char *)in++) { |  | ||||||
| -            if (i < 0x80) {
 |  | ||||||
| -                len++;
 |  | ||||||
| -            } else if ((i & 0xE0) == 0xC0) {
 |  | ||||||
| -                in++;
 |  | ||||||
| -                len++;
 |  | ||||||
| -            } else if ((i & 0xF0) == 0xE0) {
 |  | ||||||
| -                in+=2;
 |  | ||||||
| +            /* Decode UTF-8 */
 |  | ||||||
| +            i = decode_utf8(&in, i);
 |  | ||||||
| +
 |  | ||||||
| +            /* Encode, allowing for surrogates. */
 |  | ||||||
| +            if (i >= 0x10000 && i <= 0x10ffff)
 |  | ||||||
|                  len++; |  | ||||||
| -            } else {
 |  | ||||||
| +            else if (i > 0x10000)
 |  | ||||||
|                  return -1; |  | ||||||
| -            }
 |  | ||||||
| +            len++;
 |  | ||||||
|          } |  | ||||||
|      } |  | ||||||
|      return len; |  | ||||||
| @@ -74,9 +114,32 @@ int wchar_to_utf8(char *out, const wchar_t *in)
 |  | ||||||
|  { |  | ||||||
|      unsigned int i; |  | ||||||
|      unsigned int len = 1; |  | ||||||
| +    int hi = -1;
 |  | ||||||
|   |  | ||||||
|      if (out) { |  | ||||||
|          while (i = (unsigned int)*in++) { |  | ||||||
| +            /* Decode surrogates */
 |  | ||||||
| +            if (i >= 0xD800 && i <= 0xDBFF)
 |  | ||||||
| +            {
 |  | ||||||
| +                /* High surrogate. Must be followed by a low surrogate, or this is a failure. */
 |  | ||||||
| +                int hi = i & 0x3ff;
 |  | ||||||
| +                int j = (unsigned int)*in++;
 |  | ||||||
| +                if (j == 0 || (j <= 0xDC00 || j >= 0xDFFF))
 |  | ||||||
| +                {
 |  | ||||||
| +                    /* Failure! Unicode replacement char! */
 |  | ||||||
| +                    in--;
 |  | ||||||
| +                    i = 0xfffd;
 |  | ||||||
| +                } else {
 |  | ||||||
| +                    /* Decode surrogates */
 |  | ||||||
| +                    i = 0x10000 + (hi<<10) + (j & 0x3ff);
 |  | ||||||
| +                }
 |  | ||||||
| +            } else if (i >= 0xDC00 && i <= 0xDFFF)
 |  | ||||||
| +            {
 |  | ||||||
| +                /* Lone low surrogate. Failure. Unicode replacement char. */
 |  | ||||||
| +                i = 0xfffd;
 |  | ||||||
| +            }
 |  | ||||||
| +
 |  | ||||||
| +            /* Encode output */
 |  | ||||||
|              if (i < 0x80) { |  | ||||||
|                  *out++ = (char)i; |  | ||||||
|                  len++; |  | ||||||
| @@ -84,22 +147,51 @@ int wchar_to_utf8(char *out, const wchar_t *in)
 |  | ||||||
|                  *out++ = 0xC0 | ( i>> 6        ); |  | ||||||
|                  *out++ = 0x80 | ( i      & 0x3F); |  | ||||||
|                  len+=2; |  | ||||||
| -            } else /* if (i < 0x10000) */ {
 |  | ||||||
| +            } else if (i < 0x10000) {
 |  | ||||||
|                  *out++ = 0xE0 | ( i>>12        ); |  | ||||||
|                  *out++ = 0x80 | ((i>> 6) & 0x3F); |  | ||||||
|                  *out++ = 0x80 | ( i      & 0x3F); |  | ||||||
|                  len+=3; |  | ||||||
| +            } else {
 |  | ||||||
| +                *out++ = 0xF0 | ( i>>18        );
 |  | ||||||
| +                *out++ = 0x80 | ((i>>12) & 0x3F);
 |  | ||||||
| +                *out++ = 0x80 | ((i>> 6) & 0x3F);
 |  | ||||||
| +                *out++ = 0x80 | ( i      & 0x3F);
 |  | ||||||
| +                len+=4;
 |  | ||||||
|              } |  | ||||||
|          } |  | ||||||
|          *out = 0; |  | ||||||
|      } else { |  | ||||||
|          while (i = (unsigned int)*in++) { |  | ||||||
| +            /* Decode surrogates */
 |  | ||||||
| +            if (i >= 0xD800 && i <= 0xDBFF)
 |  | ||||||
| +            {
 |  | ||||||
| +                /* High surrogate. Must be followed by a low surrogate, or this is a failure. */
 |  | ||||||
| +                int hi = i & 0x3ff;
 |  | ||||||
| +                int j = (unsigned int)*in++;
 |  | ||||||
| +                if (j == 0 || (j <= 0xDC00 || j >= 0xDFFF))
 |  | ||||||
| +                {
 |  | ||||||
| +                    /* Failure! Unicode replacement char! */
 |  | ||||||
| +                    in--;
 |  | ||||||
| +                    i = 0xfffd;
 |  | ||||||
| +                } else {
 |  | ||||||
| +                    /* Decode surrogates */
 |  | ||||||
| +                    i = 0x10000 + (hi<<10) + (j & 0x3ff);
 |  | ||||||
| +                }
 |  | ||||||
| +            } else if (i >= 0xDC00 && i <= 0xDFFF)
 |  | ||||||
| +            {
 |  | ||||||
| +                /* Lone low surrogate. Failure. Unicode replacement char. */
 |  | ||||||
| +                i = 0xfffd;
 |  | ||||||
| +            }
 |  | ||||||
| +
 |  | ||||||
|              if (i < 0x80) { |  | ||||||
|                  len++; |  | ||||||
|              } else if (i < 0x800) { |  | ||||||
|                  len += 2; |  | ||||||
| -            } else /* if (i < 0x10000) */ {
 |  | ||||||
| +            } else if (i < 0x10000) {
 |  | ||||||
|                  len += 3; |  | ||||||
| +            } else {
 |  | ||||||
| +                len += 4;
 |  | ||||||
|              } |  | ||||||
|          } |  | ||||||
|      } |  | ||||||
| -- 
 |  | ||||||
| 2.49.0 |  | ||||||
| 
 |  | ||||||
| @ -1,42 +0,0 @@ | |||||||
| diff --git a/base/gp_wutf8.c b/base/gp_wutf8.c
 |  | ||||||
| index 56bedc1..23fcdd1 100644
 |  | ||||||
| --- a/base/gp_wutf8.c
 |  | ||||||
| +++ b/base/gp_wutf8.c
 |  | ||||||
| @@ -25,12 +25,16 @@ decode_utf8(const char **inp, unsigned int i)
 |  | ||||||
|      if (i < 0x80) { |  | ||||||
|      } else if ((i & 0xE0) == 0xC0) { |  | ||||||
|          i &= 0x1F; |  | ||||||
| +        if (i == 0)
 |  | ||||||
| +            goto fail_overlong;
 |  | ||||||
|          c = (unsigned char)*in++; |  | ||||||
|          if ((c & 0xC0) != 0x80) |  | ||||||
|              goto fail; |  | ||||||
|          i = (i<<6) | (c & 0x3f); |  | ||||||
|      } else if ((i & 0xF0) == 0xE0) { |  | ||||||
|          i &= 0xF; |  | ||||||
| +        if (i == 0)
 |  | ||||||
| +            goto fail_overlong;
 |  | ||||||
|          c = (unsigned char)*in++; |  | ||||||
|          if ((c & 0xC0) != 0x80) |  | ||||||
|              goto fail; |  | ||||||
| @@ -41,6 +45,8 @@ decode_utf8(const char **inp, unsigned int i)
 |  | ||||||
|          i = (i<<6) | (c & 0x3f); |  | ||||||
|      } else if ((i & 0xF8) == 0xF0) { |  | ||||||
|          i &= 0x7; |  | ||||||
| +        if (i == 0)
 |  | ||||||
| +            goto fail_overlong;
 |  | ||||||
|          c = (unsigned char)*in++; |  | ||||||
|          if ((c & 0xC0) != 0x80) |  | ||||||
|              goto fail; |  | ||||||
| @@ -59,6 +65,11 @@ decode_utf8(const char **inp, unsigned int i)
 |  | ||||||
|          /* If we fail, unread the last one, and return the unicode replacement char. */ |  | ||||||
|  fail: |  | ||||||
|         in--; |  | ||||||
| +fail_overlong:
 |  | ||||||
| +       /* If we jump to here it's because we've detected an 'overlong' encoding.
 |  | ||||||
| +        * While this seems harmless, it's actually illegal, for good reason;
 |  | ||||||
| +        * this is typically an attempt to sneak stuff past security checks, like
 |  | ||||||
| +        * "../" in paths. Fail this. */
 |  | ||||||
|         i = 0xfffd; |  | ||||||
|      } |  | ||||||
|      *inp = in; |  | ||||||
| @ -1,67 +0,0 @@ | |||||||
| From 1f21a45df0fa3abec4cff12951022b192dda3c00 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Zdenek Hutyra <zhutyra@centrum.cz> |  | ||||||
| Date: Mon, 27 May 2024 13:38:36 +0100 |  | ||||||
| Subject: [PATCH] Bug 707793: Check for overflow validating format string |  | ||||||
| 
 |  | ||||||
| for the output file name |  | ||||||
| 
 |  | ||||||
| CVE-2024-46953 |  | ||||||
| ---
 |  | ||||||
|  base/gsdevice.c | 19 ++++++++++++++----- |  | ||||||
|  1 file changed, 14 insertions(+), 5 deletions(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/base/gsdevice.c b/base/gsdevice.c
 |  | ||||||
| index 90e699ab4..49354d833 100644
 |  | ||||||
| --- a/base/gsdevice.c
 |  | ||||||
| +++ b/base/gsdevice.c
 |  | ||||||
| @@ -1070,7 +1070,7 @@ static int
 |  | ||||||
|  gx_parse_output_format(gs_parsed_file_name_t *pfn, const char **pfmt) |  | ||||||
|  { |  | ||||||
|      bool have_format = false, field; |  | ||||||
| -    int width[2], int_width = sizeof(int) * 3, w = 0;
 |  | ||||||
| +    uint width[2], int_width = sizeof(int) * 3, w = 0;
 |  | ||||||
|      uint i; |  | ||||||
|   |  | ||||||
|      /* Scan the file name for a format string, and validate it if present. */ |  | ||||||
| @@ -1099,6 +1099,8 @@ gx_parse_output_format(gs_parsed_file_name_t *pfn, const char **pfmt)
 |  | ||||||
|                          default: /* width (field = 0) and precision (field = 1) */ |  | ||||||
|                              if (strchr("0123456789", pfn->fname[i])) { |  | ||||||
|                                  width[field] = width[field] * 10 + pfn->fname[i] - '0'; |  | ||||||
| +                                if (width[field] > max_int)
 |  | ||||||
| +	                                return_error(gs_error_undefinedfilename);
 |  | ||||||
|                                  continue; |  | ||||||
|                              } else if (0 == field && '.' == pfn->fname[i]) { |  | ||||||
|                                  field++; |  | ||||||
| @@ -1127,8 +1129,10 @@ gx_parse_output_format(gs_parsed_file_name_t *pfn, const char **pfmt)
 |  | ||||||
|          /* Calculate a conservative maximum width. */ |  | ||||||
|          w = max(width[0], width[1]); |  | ||||||
|          w = max(w, int_width) + 5; |  | ||||||
| +        if (w > max_int)
 |  | ||||||
| +            return_error(gs_error_undefinedfilename);
 |  | ||||||
|      } |  | ||||||
| -    return w;
 |  | ||||||
| +    return (int)w;
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  /* |  | ||||||
| @@ -1181,10 +1185,15 @@ gx_parse_output_file_name(gs_parsed_file_name_t *pfn, const char **pfmt,
 |  | ||||||
|      if (!pfn->fname) |  | ||||||
|          return 0; |  | ||||||
|      code = gx_parse_output_format(pfn, pfmt); |  | ||||||
| -    if (code < 0)
 |  | ||||||
| +    if (code < 0) {
 |  | ||||||
|          return code; |  | ||||||
| -    if (strlen(pfn->iodev->dname) + pfn->len + code >= gp_file_name_sizeof)
 |  | ||||||
| +    }
 |  | ||||||
| +
 |  | ||||||
| +    if (pfn->len >= gp_file_name_sizeof - strlen(pfn->iodev->dname) ||
 |  | ||||||
| +        code >= gp_file_name_sizeof - strlen(pfn->iodev->dname) - pfn->len) {
 |  | ||||||
|          return_error(gs_error_undefinedfilename); |  | ||||||
| +    }
 |  | ||||||
| +
 |  | ||||||
|      return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -- 
 |  | ||||||
| 2.49.0 |  | ||||||
| 
 |  | ||||||
| @ -1,22 +0,0 @@ | |||||||
| diff --git a/contrib/japanese/gdevnpdl.c b/contrib/japanese/gdevnpdl.c
 |  | ||||||
| index 597ecc8..0aa5128 100644
 |  | ||||||
| --- a/contrib/japanese/gdevnpdl.c
 |  | ||||||
| +++ b/contrib/japanese/gdevnpdl.c
 |  | ||||||
| @@ -580,7 +580,7 @@ npdl_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, int num_copi
 |  | ||||||
|      int code; |  | ||||||
|      int maxY = lprn->BlockLine / lprn->nBh * lprn->nBh; |  | ||||||
|   |  | ||||||
| -    if (!(lprn->CompBuf = gs_malloc(pdev->memory->non_gc_memory, line_size * maxY, sizeof(byte), "npdl_print_page_copies(CompBuf)")))
 |  | ||||||
| +    if (!(lprn->CompBuf = gs_malloc(pdev->memory->non_gc_memory, line_size, maxY, "npdl_print_page_copies(CompBuf)")))
 |  | ||||||
|          return_error(gs_error_VMerror); |  | ||||||
|   |  | ||||||
|          /* Initialize printer */ |  | ||||||
| @@ -675,7 +675,7 @@ npdl_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, int num_copi
 |  | ||||||
|      /* Form Feed */ |  | ||||||
|      fputs("\014", prn_stream); |  | ||||||
|   |  | ||||||
| -    gs_free(pdev->memory->non_gc_memory, lprn->CompBuf, line_size * maxY, sizeof(byte), "npdl_print_page_copies(CompBuf)");
 |  | ||||||
| +    gs_free(pdev->memory->non_gc_memory, lprn->CompBuf, line_size, maxY, "npdl_print_page_copies(CompBuf)");
 |  | ||||||
|      return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @ -1,31 +0,0 @@ | |||||||
| From f49812186baa7d1362880673408a6fbe8719b4f8 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Zdenek Hutyra <zhutyra@centrum.cz> |  | ||||||
| Date: Fri, 30 Aug 2024 13:16:39 +0100 |  | ||||||
| Subject: [PATCH] PS interpreter - check the type of the Pattern Implementation |  | ||||||
| 
 |  | ||||||
| Bug #707991 |  | ||||||
| 
 |  | ||||||
| See bug report for details. |  | ||||||
| 
 |  | ||||||
| CVE-2024-46951 |  | ||||||
| ---
 |  | ||||||
|  psi/zcolor.c | 3 +++ |  | ||||||
|  1 file changed, 3 insertions(+) |  | ||||||
| 
 |  | ||||||
| diff --git a/psi/zcolor.c b/psi/zcolor.c
 |  | ||||||
| index d4e7a4438..d3384d75d 100644
 |  | ||||||
| --- a/psi/zcolor.c
 |  | ||||||
| +++ b/psi/zcolor.c
 |  | ||||||
| @@ -5276,6 +5276,9 @@ static int patterncomponent(i_ctx_t * i_ctx_p, ref *space, int *n)
 |  | ||||||
|              code = array_get(imemory, pImpl, 0, &pPatInst); |  | ||||||
|              if (code < 0) |  | ||||||
|                  return code; |  | ||||||
| +
 |  | ||||||
| +            if (!r_is_struct(&pPatInst) || (!r_has_stype(&pPatInst, imemory, st_pattern1_instance) && !r_has_stype(&pPatInst, imemory, st_pattern2_instance)))
 |  | ||||||
| +                return_error(gs_error_typecheck);
 |  | ||||||
|              cc.pattern = r_ptr(&pPatInst, gs_pattern_instance_t); |  | ||||||
|              if (pattern_instance_uses_base_space(cc.pattern)) |  | ||||||
|                  *n = n_comps; |  | ||||||
| -- 
 |  | ||||||
| 2.49.0 |  | ||||||
| 
 |  | ||||||
| @ -1,13 +0,0 @@ | |||||||
| diff --git a/psi/zfile.c b/psi/zfile.c
 |  | ||||||
| index 05b8203..ee40a75 100644
 |  | ||||||
| --- a/psi/zfile.c
 |  | ||||||
| +++ b/psi/zfile.c
 |  | ||||||
| @@ -437,7 +437,7 @@ file_continue(i_ctx_t *i_ctx_p)
 |  | ||||||
|          if (code == ~(uint) 0) {    /* all done */ |  | ||||||
|              esp -= 5;               /* pop proc, pfen, devlen, iodev , mark */ |  | ||||||
|              return o_pop_estack; |  | ||||||
| -        } else if (code > len) {      /* overran string */
 |  | ||||||
| +        } else if (code > len - devlen) {      /* overran string */
 |  | ||||||
|              return_error(gs_error_rangecheck); |  | ||||||
|          } |  | ||||||
|          else if (iodev != iodev_default(imemory) |  | ||||||
| @ -1,22 +0,0 @@ | |||||||
| From 91c9c6d17d445781ee572c281b8b9d75d96f9df8 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "David Kaspar [Dee'Kej]" <dkaspar@redhat.com> |  | ||||||
| Date: Fri, 7 Oct 2016 13:57:01 +0200 |  | ||||||
| Subject: [PATCH] Make sure 'dvipdf' is being run securely |  | ||||||
| 
 |  | ||||||
| ---
 |  | ||||||
|  lib/dvipdf | 2 +- |  | ||||||
|  1 file changed, 1 insertion(+), 1 deletion(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/lib/dvipdf b/lib/dvipdf
 |  | ||||||
| index 802aeab..c92dfb0 100755
 |  | ||||||
| --- a/lib/dvipdf
 |  | ||||||
| +++ b/lib/dvipdf
 |  | ||||||
| @@ -43,4 +43,4 @@ fi
 |  | ||||||
|   |  | ||||||
|  # We have to include the options twice because -I only takes effect if it |  | ||||||
|  # appears before other options. |  | ||||||
| -exec dvips -Ppdf $DVIPSOPTIONS -q -f "$infile" | $GS_EXECUTABLE $OPTIONS -q -P- -dSAFER -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sstdout=%stderr -sOutputFile="$outfile" $OPTIONS -c .setpdfwrite -
 |  | ||||||
| +exec dvips -R -Ppdf $DVIPSOPTIONS -q -f "$infile" | $GS_EXECUTABLE $OPTIONS -q -P- -dSAFER -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sstdout=%stderr -sOutputFile="$outfile" $OPTIONS -c .setpdfwrite -
 |  | ||||||
| -- 
 |  | ||||||
| 2.14.3 |  | ||||||
| 
 |  | ||||||
| @ -1,28 +0,0 @@ | |||||||
| From 2793769ff107d8d22dadd30c6e68cd781b569550 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Julian Smith <jules@op59.net> |  | ||||||
| Date: Mon, 4 Nov 2019 12:30:33 +0000 |  | ||||||
| Subject: [PATCH] Bug 701819: fixed ordering in if expression to avoid |  | ||||||
|  out-of-bounds access. |  | ||||||
| 
 |  | ||||||
| Fixes: |  | ||||||
|     ./sanbin/gs -dBATCH -dNOPAUSE -r965 -sOutputFile=tmp -sDEVICE=pcx16 ../bug-701819.pdf |  | ||||||
| ---
 |  | ||||||
|  devices/gdevpcx.c | 2 +- |  | ||||||
|  1 file changed, 1 insertion(+), 1 deletion(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/devices/gdevpcx.c b/devices/gdevpcx.c
 |  | ||||||
| index 1735851d2..91de4abb6 100644
 |  | ||||||
| --- a/devices/gdevpcx.c
 |  | ||||||
| +++ b/devices/gdevpcx.c
 |  | ||||||
| @@ -442,7 +442,7 @@ pcx_write_rle(const byte * from, const byte * end, int step, gp_file * file)
 |  | ||||||
|          byte data = *from; |  | ||||||
|   |  | ||||||
|          from += step; |  | ||||||
| -        if (data != *from || from == end) {
 |  | ||||||
| +        if (from >= end || data != *from) {
 |  | ||||||
|              if (data >= 0xc0) |  | ||||||
|                  putc(0xc1, file); |  | ||||||
|          } else { |  | ||||||
| -- 
 |  | ||||||
| 2.41.0 |  | ||||||
| 
 |  | ||||||
| @ -1,88 +0,0 @@ | |||||||
| From f70ab2044429fe4b991801476ea3f4b4a5c0cdf4 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Julian Smith <jules@op59.net> |  | ||||||
| Date: Wed, 6 Nov 2019 11:46:10 +0000 |  | ||||||
| Subject: [PATCH 1/2] Bug 701843: avoid divide by zero caused by custom |  | ||||||
|  resolution being too low. |  | ||||||
| 
 |  | ||||||
| Fixes: |  | ||||||
|     ./sanbin/gs -dBATCH -dNOPAUSE -dSAFER -r8 -dNOCIE -dFitPage -sOutputFile=tmp -sDEVICE=eps9mid  ../bug-701843.pdf |  | ||||||
| ---
 |  | ||||||
|  devices/gdevepsn.c | 19 +++++++++++++++---- |  | ||||||
|  1 file changed, 15 insertions(+), 4 deletions(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/devices/gdevepsn.c b/devices/gdevepsn.c
 |  | ||||||
| index 49faaf3d7..3e5388322 100644
 |  | ||||||
| --- a/devices/gdevepsn.c
 |  | ||||||
| +++ b/devices/gdevepsn.c
 |  | ||||||
| @@ -159,10 +159,10 @@ eps_print_page(gx_device_printer *pdev, gp_file *prn_stream, int y_9pin_high,
 |  | ||||||
|          int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev); |  | ||||||
|          /* Note that in_size is a multiple of 8. */ |  | ||||||
|          int in_size = line_size * (8 * in_y_mult); |  | ||||||
| -        byte *buf1 = (byte *)gs_malloc(pdev->memory, in_size, 1, "eps_print_page(buf1)");
 |  | ||||||
| -        byte *buf2 = (byte *)gs_malloc(pdev->memory, in_size, 1, "eps_print_page(buf2)");
 |  | ||||||
| -        byte *in = buf1;
 |  | ||||||
| -        byte *out = buf2;
 |  | ||||||
| +        byte *buf1;
 |  | ||||||
| +        byte *buf2;
 |  | ||||||
| +        byte *in;
 |  | ||||||
| +        byte *out;
 |  | ||||||
|          int out_y_mult = (y_24pin ? 3 : 1); |  | ||||||
|          int x_dpi = (int)pdev->x_pixels_per_inch; |  | ||||||
|          char start_graphics = |  | ||||||
| @@ -174,6 +174,17 @@ eps_print_page(gx_device_printer *pdev, gp_file *prn_stream, int y_9pin_high,
 |  | ||||||
|          int bytes_per_space = dots_per_space * out_y_mult; |  | ||||||
|          int tab_min_pixels = x_dpi * MIN_TAB_10THS / 10; |  | ||||||
|          int skip = 0, lnum = 0, pass, ypass; |  | ||||||
| +
 |  | ||||||
| +        if (bytes_per_space == 0) {
 |  | ||||||
| +            /* This avoids divide by zero later on, bug 701843. */
 |  | ||||||
| +            return_error(gs_error_rangecheck);
 |  | ||||||
| +        }
 |  | ||||||
| +
 |  | ||||||
| +        buf1 = (byte *)gs_malloc(pdev->memory, in_size, 1, "eps_print_page(buf1)");
 |  | ||||||
| +        buf2 = (byte *)gs_malloc(pdev->memory, in_size, 1, "eps_print_page(buf2)");
 |  | ||||||
| +        in = buf1;
 |  | ||||||
| +        out = buf2;
 |  | ||||||
| +
 |  | ||||||
|   |  | ||||||
|          /* Check allocations */ |  | ||||||
|          if ( buf1 == 0 || buf2 == 0 ) |  | ||||||
| 
 |  | ||||||
| diff --git a/devices/gdevepsc.c b/devices/gdevepsc.c
 |  | ||||||
| --- a/devices/gdevepsc.c
 |  | ||||||
| +++ b/devices/gdevepsc.c
 |  | ||||||
| @@ -174,13 +174,7 @@
 |  | ||||||
|      int y_mult = (y_24pin ? 3 : 1); |  | ||||||
|      int line_size = (pdev->width + 7) >> 3;     /* always mono */ |  | ||||||
|      int in_size = line_size * (8 * y_mult); |  | ||||||
| -    byte *in =
 |  | ||||||
| -        (byte *) gs_malloc(pdev->memory, in_size + 1, 1,
 |  | ||||||
| -                           "epsc_print_page(in)");
 |  | ||||||
|      int out_size = ((pdev->width + 7) & -8) * y_mult; |  | ||||||
| -    byte *out =
 |  | ||||||
| -        (byte *) gs_malloc(pdev->memory, out_size + 1, 1,
 |  | ||||||
| -                           "epsc_print_page(out)");
 |  | ||||||
|      int x_dpi = (int)pdev->x_pixels_per_inch; |  | ||||||
|      char start_graphics = (char) |  | ||||||
|          ((y_24pin ? graphics_modes_24 : graphics_modes_9)[x_dpi / 60]); |  | ||||||
| @@ -195,6 +189,20 @@
 |  | ||||||
|      int color_line_size, color_in_size; |  | ||||||
|      int spare_bits = (pdev->width % 8); /* left over bits to go to margin */ |  | ||||||
|      int whole_bits = pdev->width - spare_bits; |  | ||||||
| +    byte *out;
 |  | ||||||
| +    byte *in;
 |  | ||||||
| +
 |  | ||||||
| +    if (bytes_per_space == 0) {
 |  | ||||||
| +        /* This avoids divide by zero later on, bug 701843. */
 |  | ||||||
| +        return_error(gs_error_rangecheck);
 |  | ||||||
| +    }
 |  | ||||||
| +
 |  | ||||||
| +    in =
 |  | ||||||
| +        (byte *) gs_malloc(pdev->memory, in_size + 1, 1,
 |  | ||||||
| +                           "epsc_print_page(in)");
 |  | ||||||
| +    out =
 |  | ||||||
| +        (byte *) gs_malloc(pdev->memory, out_size + 1, 1,
 |  | ||||||
| +                           "epsc_print_page(out)");
 |  | ||||||
|   |  | ||||||
|      /* Check allocations */ |  | ||||||
|      if (in == 0 || out == 0) { |  | ||||||
| @ -1,63 +0,0 @@ | |||||||
| diff -Napur ghostscript-9.27.old/base/fapi_ft.c ghostscript-9.27.new/base/fapi_ft.c
 |  | ||||||
| --- ghostscript-9.27.old/base/fapi_ft.c	2019-04-04 00:43:14.000000000 -0700
 |  | ||||||
| +++ ghostscript-9.27.new/base/fapi_ft.c	2023-03-07 16:41:56.217995052 -0800
 |  | ||||||
| @@ -974,13 +974,19 @@ make_rotation(FT_Matrix * a_transform, c
 |  | ||||||
|   */ |  | ||||||
|  static void |  | ||||||
|  transform_decompose(FT_Matrix * a_transform, FT_UInt * xresp, FT_UInt * yresp, |  | ||||||
| -                    FT_Fixed * a_x_scale, FT_Fixed * a_y_scale)
 |  | ||||||
| +                    FT_Fixed * a_x_scale, FT_Fixed * a_y_scale, int units_per_EM)
 |  | ||||||
|  { |  | ||||||
|      double scalex, scaley, fact = 1.0; |  | ||||||
|      double factx = 1.0, facty = 1.0; |  | ||||||
|      FT_Matrix ftscale_mat; |  | ||||||
|      FT_UInt xres; |  | ||||||
|      FT_UInt yres; |  | ||||||
| +    /* We have to account for units_per_EM as we fiddle with the scaling
 |  | ||||||
| +     * in order to avoid underflow (mostly in the TTF hinting code), but
 |  | ||||||
| +     * we also want to clamp to a lower value (512, admittedly arrived at
 |  | ||||||
| +     * via experimentation) in order to preserve the fidelity of the outlines.
 |  | ||||||
| +     */
 |  | ||||||
| +    double upe = units_per_EM > 512 ? (float)units_per_EM : 512.0;
 |  | ||||||
|   |  | ||||||
|      scalex = hypot((double)a_transform->xx, (double)a_transform->xy); |  | ||||||
|      scaley = hypot((double)a_transform->yx, (double)a_transform->yy); |  | ||||||
| @@ -1067,10 +1073,25 @@ transform_decompose(FT_Matrix * a_transf
 |  | ||||||
|          scalex *= fact; |  | ||||||
|      } |  | ||||||
|   |  | ||||||
| -    ftscale_mat.xx = (FT_Fixed) (65536.0 / scalex);
 |  | ||||||
| -    ftscale_mat.xy = (FT_Fixed) 0;
 |  | ||||||
| -    ftscale_mat.yx = (FT_Fixed) 0;
 |  | ||||||
| -    ftscale_mat.yy = (FT_Fixed) (65536.0 / scaley);
 |  | ||||||
| +    /* see above */
 |  | ||||||
| +    fact = 1.0;
 |  | ||||||
| +    while (scaley * yres > (double)upe * 72.0 && (xres > 0 && yres > 0)
 |  | ||||||
| +           && (scalex > 0.0 && scaley > 0.0)) {
 |  | ||||||
| +        if (scaley < yres) {
 |  | ||||||
| +            xres >>= 1;
 |  | ||||||
| +            yres >>= 1;
 |  | ||||||
| +            fact *= 2.0;
 |  | ||||||
| +        }
 |  | ||||||
| +        else {
 |  | ||||||
| +            scalex /= 1.25;
 |  | ||||||
| +            scaley /= 1.25;
 |  | ||||||
| +        }
 |  | ||||||
| +    }
 |  | ||||||
| +
 |  | ||||||
| +    ftscale_mat.xx = (FT_Fixed) ((65536.0 / scalex) * fact);
 |  | ||||||
| +    ftscale_mat.xy = 0;
 |  | ||||||
| +    ftscale_mat.yx = 0;
 |  | ||||||
| +    ftscale_mat.yy = (FT_Fixed) ((65536.0 / scaley) * fact);
 |  | ||||||
|   |  | ||||||
|      FT_Matrix_Multiply(a_transform, &ftscale_mat); |  | ||||||
|      memcpy(a_transform, &ftscale_mat, sizeof(FT_Matrix)); |  | ||||||
| @@ -1315,7 +1336,7 @@ gs_fapi_ft_get_scaled_font(gs_fapi_serve
 |  | ||||||
|           * transform. |  | ||||||
|           */ |  | ||||||
|          transform_decompose(&face->ft_transform, &face->horz_res, |  | ||||||
| -                            &face->vert_res, &face->width, &face->height);
 |  | ||||||
| +                            &face->vert_res, &face->width, &face->height, face->ft_face->units_per_EM);
 |  | ||||||
|   |  | ||||||
|          ft_error = FT_Set_Char_Size(face->ft_face, face->width, face->height, |  | ||||||
|                                      face->horz_res, face->vert_res); |  | ||||||
| @ -1,16 +0,0 @@ | |||||||
| diff -Napur '--exclude=.git' ghostscript-9.27.old/devices/vector/opdfread.ps ghostscript-9.27.new/devices/vector/opdfread.ps
 |  | ||||||
| --- ghostscript-9.27.old/devices/vector/opdfread.ps	2019-04-04 00:43:14.000000000 -0700
 |  | ||||||
| +++ ghostscript-9.27.new/devices/vector/opdfread.ps	2022-06-14 17:44:27.963033829 -0700
 |  | ||||||
| @@ -998,10 +998,10 @@ currentdict end readonly def
 |  | ||||||
|    } if                                                  % id obj node |  | ||||||
|    1 index exch /Context exch put                        % id obj |  | ||||||
|    dup /ImmediateExec true put |  | ||||||
| -  dup /IsPage true put
 |  | ||||||
| -  SetPageSize {dup /Context get //SetupPageView exec} if
 |  | ||||||
|    % This gets restored at the end of ExecuteStream if IsPage is true. |  | ||||||
|    /pagesave save def |  | ||||||
| +  dup /IsPage true put
 |  | ||||||
| +  SetPageSize {dup /Context get //SetupPageView exec} if
 |  | ||||||
|  } bind def |  | ||||||
|   |  | ||||||
|  /FontFileDaemon % <id> <obj> <font_descriptor> FontFileDaemon <id> <obj> |  | ||||||
							
								
								
									
										142
									
								
								SOURCES/ghostscript-9.54.0-CVE-2023-36664.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								SOURCES/ghostscript-9.54.0-CVE-2023-36664.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,142 @@ | |||||||
|  | From 505eab7782b429017eb434b2b95120855f2b0e3c Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Chris Liddell <chris.liddell@artifex.com> | ||||||
|  | Date: Wed, 7 Jun 2023 10:23:06 +0100 | ||||||
|  | Subject: [PATCH] Bug 706761: Don't "reduce" %pipe% file names for permission | ||||||
|  |  validation | ||||||
|  | 
 | ||||||
|  | For regular file names, we try to simplfy relative paths before we use them. | ||||||
|  | 
 | ||||||
|  | Because the %pipe% device can, effectively, accept command line calls, we | ||||||
|  | shouldn't be simplifying that string, because the command line syntax can end | ||||||
|  | up confusing the path simplifying code. That can result in permitting a pipe | ||||||
|  | command which does not match what was originally permitted. | ||||||
|  | 
 | ||||||
|  | Special case "%pipe" in the validation code so we always deal with the entire | ||||||
|  | string. | ||||||
|  | ---
 | ||||||
|  |  base/gpmisc.c   | 31 +++++++++++++++++++-------- | ||||||
|  |  base/gslibctx.c | 56 ++++++++++++++++++++++++++++++++++++------------- | ||||||
|  |  2 files changed, 64 insertions(+), 23 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/base/gpmisc.c b/base/gpmisc.c
 | ||||||
|  | index 5f39ebba7..2fb87f769 100644
 | ||||||
|  | --- a/base/gpmisc.c
 | ||||||
|  | +++ b/base/gpmisc.c
 | ||||||
|  | @@ -1076,16 +1076,29 @@ gp_validate_path_len(const gs_memory_t *mem,
 | ||||||
|  |               && !memcmp(path + cdirstrl, dirsepstr, dirsepstrl)) { | ||||||
|  |            prefix_len = 0; | ||||||
|  |      } | ||||||
|  | -    rlen = len+1;
 | ||||||
|  | -    bufferfull = (char *)gs_alloc_bytes(mem->thread_safe_memory, rlen + prefix_len, "gp_validate_path");
 | ||||||
|  | -    if (bufferfull == NULL)
 | ||||||
|  | -        return gs_error_VMerror;
 | ||||||
|  | -
 | ||||||
|  | -    buffer = bufferfull + prefix_len;
 | ||||||
|  | -    if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success)
 | ||||||
|  | -        return gs_error_invalidfileaccess;
 | ||||||
|  | -    buffer[rlen] = 0;
 | ||||||
|  |   | ||||||
|  | +    /* "%pipe%" do not follow the normal rules for path definitions, so we
 | ||||||
|  | +       don't "reduce" them to avoid unexpected results
 | ||||||
|  | +     */
 | ||||||
|  | +    if (path[0] == '|' || (len > 5 && memcmp(path, "%pipe", 5) == 0)) {
 | ||||||
|  | +        bufferfull = buffer = (char *)gs_alloc_bytes(mem->thread_safe_memory, len + 1, "gp_validate_path");
 | ||||||
|  | +        if (buffer == NULL)
 | ||||||
|  | +            return gs_error_VMerror;
 | ||||||
|  | +        memcpy(buffer, path, len);
 | ||||||
|  | +        buffer[len] = 0;
 | ||||||
|  | +        rlen = len;
 | ||||||
|  | +    }
 | ||||||
|  | +    else {
 | ||||||
|  | +        rlen = len+1;
 | ||||||
|  | +        bufferfull = (char *)gs_alloc_bytes(mem->thread_safe_memory, rlen + prefix_len, "gp_validate_path");
 | ||||||
|  | +        if (bufferfull == NULL)
 | ||||||
|  | +            return gs_error_VMerror;
 | ||||||
|  | +
 | ||||||
|  | +        buffer = bufferfull + prefix_len;
 | ||||||
|  | +        if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success)
 | ||||||
|  | +            return gs_error_invalidfileaccess;
 | ||||||
|  | +        buffer[rlen] = 0;
 | ||||||
|  | +    }
 | ||||||
|  |      while (1) { | ||||||
|  |          switch (mode[0]) | ||||||
|  |          { | ||||||
|  | diff --git a/base/gslibctx.c b/base/gslibctx.c
 | ||||||
|  | index eb566ed06..d2a1aa91d 100644
 | ||||||
|  | --- a/base/gslibctx.c
 | ||||||
|  | +++ b/base/gslibctx.c
 | ||||||
|  | @@ -740,14 +740,28 @@ gs_add_control_path_len_flags(const gs_memory_t *mem, gs_path_control_t type, co
 | ||||||
|  |              return gs_error_rangecheck; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  | -    rlen = len+1;
 | ||||||
|  | -    buffer = (char *)gs_alloc_bytes(core->memory, rlen, "gp_validate_path");
 | ||||||
|  | -    if (buffer == NULL)
 | ||||||
|  | -        return gs_error_VMerror;
 | ||||||
|  | +    /* "%pipe%" do not follow the normal rules for path definitions, so we
 | ||||||
|  | +       don't "reduce" them to avoid unexpected results
 | ||||||
|  | +     */
 | ||||||
|  | +    if (path[0] == '|' || (len > 5 && memcmp(path, "%pipe", 5) == 0)) {
 | ||||||
|  | +        buffer = (char *)gs_alloc_bytes(core->memory, len + 1, "gs_add_control_path_len");
 | ||||||
|  | +        if (buffer == NULL)
 | ||||||
|  | +            return gs_error_VMerror;
 | ||||||
|  | +        memcpy(buffer, path, len);
 | ||||||
|  | +        buffer[len] = 0;
 | ||||||
|  | +        rlen = len;
 | ||||||
|  | +    }
 | ||||||
|  | +    else {
 | ||||||
|  | +        rlen = len + 1;
 | ||||||
|  |   | ||||||
|  | -    if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success)
 | ||||||
|  | -        return gs_error_invalidfileaccess;
 | ||||||
|  | -    buffer[rlen] = 0;
 | ||||||
|  | +        buffer = (char *)gs_alloc_bytes(core->memory, rlen, "gs_add_control_path_len");
 | ||||||
|  | +        if (buffer == NULL)
 | ||||||
|  | +            return gs_error_VMerror;
 | ||||||
|  | +
 | ||||||
|  | +        if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success)
 | ||||||
|  | +            return gs_error_invalidfileaccess;
 | ||||||
|  | +        buffer[rlen] = 0;
 | ||||||
|  | +    }
 | ||||||
|  |   | ||||||
|  |      n = control->num; | ||||||
|  |      for (i = 0; i < n; i++) | ||||||
|  | @@ -833,14 +847,28 @@ gs_remove_control_path_len_flags(const gs_memory_t *mem, gs_path_control_t type,
 | ||||||
|  |              return gs_error_rangecheck; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  | -    rlen = len+1;
 | ||||||
|  | -    buffer = (char *)gs_alloc_bytes(core->memory, rlen, "gp_validate_path");
 | ||||||
|  | -    if (buffer == NULL)
 | ||||||
|  | -        return gs_error_VMerror;
 | ||||||
|  | +    /* "%pipe%" do not follow the normal rules for path definitions, so we
 | ||||||
|  | +       don't "reduce" them to avoid unexpected results
 | ||||||
|  | +     */
 | ||||||
|  | +    if (path[0] == '|' || (len > 5 && memcmp(path, "%pipe", 5) == 0)) {
 | ||||||
|  | +        buffer = (char *)gs_alloc_bytes(core->memory, len + 1, "gs_remove_control_path_len");
 | ||||||
|  | +        if (buffer == NULL)
 | ||||||
|  | +            return gs_error_VMerror;
 | ||||||
|  | +        memcpy(buffer, path, len);
 | ||||||
|  | +        buffer[len] = 0;
 | ||||||
|  | +        rlen = len;
 | ||||||
|  | +    }
 | ||||||
|  | +    else {
 | ||||||
|  | +        rlen = len+1;
 | ||||||
|  |   | ||||||
|  | -    if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success)
 | ||||||
|  | -        return gs_error_invalidfileaccess;
 | ||||||
|  | -    buffer[rlen] = 0;
 | ||||||
|  | +        buffer = (char *)gs_alloc_bytes(core->memory, rlen, "gs_remove_control_path_len");
 | ||||||
|  | +        if (buffer == NULL)
 | ||||||
|  | +            return gs_error_VMerror;
 | ||||||
|  | +
 | ||||||
|  | +        if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success)
 | ||||||
|  | +            return gs_error_invalidfileaccess;
 | ||||||
|  | +        buffer[rlen] = 0;
 | ||||||
|  | +    }
 | ||||||
|  |   | ||||||
|  |      n = control->num; | ||||||
|  |      for (i = 0; i < n; i++) { | ||||||
|  | -- 
 | ||||||
|  | 2.41.0 | ||||||
|  | 
 | ||||||
| @ -20,7 +20,7 @@ index 7b14d9c71..6351fb77a 100644 | |||||||
| -        if (data != *from || from == end) {
 | -        if (data != *from || from == end) {
 | ||||||
| +        if (from >= end || data != *from) {
 | +        if (from >= end || data != *from) {
 | ||||||
|              if (data >= 0xc0) |              if (data >= 0xc0) | ||||||
|                  putc(0xc1, file); |                  gp_fputc(0xc1, file); | ||||||
|          } else { |          } else { | ||||||
| -- 
 | -- 
 | ||||||
| 2.41.0 | 2.41.0 | ||||||
| @ -21,7 +21,7 @@ index 870a2e11c..fa050ed7a 100644 | |||||||
| --- a/Resource/Init/gs_cidfn.ps
 | --- a/Resource/Init/gs_cidfn.ps
 | ||||||
| +++ b/Resource/Init/gs_cidfn.ps
 | +++ b/Resource/Init/gs_cidfn.ps
 | ||||||
| @@ -1,4 +1,4 @@
 | @@ -1,4 +1,4 @@
 | ||||||
| -% Copyright (C) 2001-2019 Artifex Software, Inc.
 | -% Copyright (C) 2001-2021 Artifex Software, Inc.
 | ||||||
| +% Copyright (C) 2001-2022 Artifex Software, Inc.
 | +% Copyright (C) 2001-2022 Artifex Software, Inc.
 | ||||||
|  % All Rights Reserved. |  % All Rights Reserved. | ||||||
|  % |  % | ||||||
| @ -1,17 +1,17 @@ | |||||||
| diff -x .git -Napur ghostscript-9.27.old/contrib/japanese/gdevespg.c ghostscript-9.27.new/contrib/japanese/gdevespg.c
 | diff -x .git -Napur ghostscript-9.27.old/contrib/japanese/gdevespg.c ghostscript-9.27.new/contrib/japanese/gdevespg.c
 | ||||||
| --- ghostscript-9.27.old/contrib/japanese/gdevespg.c	2019-04-04 00:43:14.000000000 -0700
 | --- ghostscript-9.27.old/contrib/japanese/gdevespg.c	2019-04-04 00:43:14.000000000 -0700
 | ||||||
| +++ ghostscript-9.27.new/contrib/japanese/gdevespg.c	2023-01-24 11:25:32.588189093 -0800
 | +++ ghostscript-9.27.new/contrib/japanese/gdevespg.c	2023-01-24 11:25:32.588189093 -0800
 | ||||||
| @@ -273,6 +273,9 @@ escpage_paper_set(gx_device_printer * pd
 | @@ -273,6 +273,9 @@
 | ||||||
|      int width, height, w, h, wp, hp, bLandscape; |      int width, height, w, h, wp, hp, bLandscape; | ||||||
|      EpagPaperTable *pt; |      EpagPaperTable *pt; | ||||||
|   |   | ||||||
| +    /* Page size match tolerance in points */
 | +    /* Page size match tolerance in points */
 | ||||||
| +    #define TOL 5
 | +    #define TOL 5
 | ||||||
| +
 | +
 | ||||||
|      width = pdev->MediaSize[0]; |      width = (int)pdev->MediaSize[0]; | ||||||
|      height = pdev->MediaSize[1]; |      height = (int)pdev->MediaSize[1]; | ||||||
|   |   | ||||||
| @@ -291,7 +294,7 @@ escpage_paper_set(gx_device_printer * pd
 | @@ -291,7 +294,7 @@
 | ||||||
|      } |      } | ||||||
|   |   | ||||||
|      for (pt = epagPaperTable; pt->escpage > 0; pt++) |      for (pt = epagPaperTable; pt->escpage > 0; pt++) | ||||||
| @ -19,4 +19,4 @@ diff -x .git -Napur ghostscript-9.27.old/contrib/japanese/gdevespg.c ghostscript | |||||||
| +      if (abs(w - pt->width) <= TOL && abs(h - pt->height) <= TOL)
 | +      if (abs(w - pt->width) <= TOL && abs(h - pt->height) <= TOL)
 | ||||||
|              break; |              break; | ||||||
|   |   | ||||||
|      fprintf(fp, "%c%d", GS, pt->escpage); |      gp_fprintf(fp, "%c%d", GS, pt->escpage); | ||||||
| @ -0,0 +1,64 @@ | |||||||
|  | From 2a3129365d3bc0d4a41f107ef175920d1505d1f7 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Chris Liddell <chris.liddell@artifex.com> | ||||||
|  | Date: Tue, 1 Jun 2021 19:57:16 +0100 | ||||||
|  | Subject: [PATCH] Bug 703902: Fix op stack management in | ||||||
|  |  sampled_data_continue() | ||||||
|  | 
 | ||||||
|  | Replace pop() (which does no checking, and doesn't handle stack extension | ||||||
|  | blocks) with ref_stack_pop() which does do all that. | ||||||
|  | 
 | ||||||
|  | We still use pop() in one case (it's faster), but we have to later use | ||||||
|  | ref_stack_pop() before calling sampled_data_sample() which also accesses the | ||||||
|  | op stack. | ||||||
|  | 
 | ||||||
|  | Fixes: | ||||||
|  | https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=34675 | ||||||
|  | ---
 | ||||||
|  |  psi/zfsample.c | 16 ++++++++++------ | ||||||
|  |  1 file changed, 10 insertions(+), 6 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/psi/zfsample.c b/psi/zfsample.c
 | ||||||
|  | index 0e8e4bc8d..00cd0cfdd 100644
 | ||||||
|  | --- a/psi/zfsample.c
 | ||||||
|  | +++ b/psi/zfsample.c
 | ||||||
|  | @@ -533,15 +533,19 @@ sampled_data_continue(i_ctx_t *i_ctx_p)
 | ||||||
|  |          for (j = 0; j < bps; j++) | ||||||
|  |              data_ptr[bps * i + j] = (byte)(cv >> ((bps - 1 - j) * 8));	/* MSB first */ | ||||||
|  |      } | ||||||
|  | -    pop(num_out);		    /* Move op to base of result values */
 | ||||||
|  |   | ||||||
|  | -    /* Check if we are done collecting data. */
 | ||||||
|  | +    pop(num_out); /* Move op to base of result values */
 | ||||||
|  |   | ||||||
|  | +    /* From here on, we have to use ref_stack_pop() rather than pop()
 | ||||||
|  | +       so that it handles stack extension blocks properly, before calling
 | ||||||
|  | +       sampled_data_sample() which also uses the op stack.
 | ||||||
|  | +     */
 | ||||||
|  | +    /* Check if we are done collecting data. */
 | ||||||
|  |      if (increment_cube_indexes(params, penum->indexes)) { | ||||||
|  |          if (stack_depth_adjust == 0) | ||||||
|  | -            pop(O_STACK_PAD);	    /* Remove spare stack space */
 | ||||||
|  | +            ref_stack_pop(&o_stack, O_STACK_PAD);	    /* Remove spare stack space */
 | ||||||
|  |          else | ||||||
|  | -            pop(stack_depth_adjust - num_out);
 | ||||||
|  | +            ref_stack_pop(&o_stack, stack_depth_adjust - num_out);
 | ||||||
|  |          /* Execute the closing procedure, if given */ | ||||||
|  |          code = 0; | ||||||
|  |          if (esp_finish_proc != 0) | ||||||
|  | @@ -554,11 +558,11 @@ sampled_data_continue(i_ctx_t *i_ctx_p)
 | ||||||
|  |              if ((O_STACK_PAD - stack_depth_adjust) < 0) { | ||||||
|  |                  stack_depth_adjust = -(O_STACK_PAD - stack_depth_adjust); | ||||||
|  |                  check_op(stack_depth_adjust); | ||||||
|  | -                pop(stack_depth_adjust);
 | ||||||
|  | +                ref_stack_pop(&o_stack, stack_depth_adjust);
 | ||||||
|  |              } | ||||||
|  |              else { | ||||||
|  |                  check_ostack(O_STACK_PAD - stack_depth_adjust); | ||||||
|  | -                push(O_STACK_PAD - stack_depth_adjust);
 | ||||||
|  | +                ref_stack_push(&o_stack, O_STACK_PAD - stack_depth_adjust);
 | ||||||
|  |                  for (i=0;i<O_STACK_PAD - stack_depth_adjust;i++) | ||||||
|  |                      make_null(op - i); | ||||||
|  |              } | ||||||
|  | -- 
 | ||||||
|  | 2.35.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										98
									
								
								SOURCES/ghostscript-9.54.0-covscan-fixes.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								SOURCES/ghostscript-9.54.0-covscan-fixes.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,98 @@ | |||||||
|  | diff -ur ghostscript-9.54.0/base/gdevvec.c ghostscript-9.54.0-patched/base/gdevvec.c
 | ||||||
|  | --- ghostscript-9.54.0/base/gdevvec.c
 | ||||||
|  | +++ ghostscript-9.54.0-patched/base/gdevvec.c
 | ||||||
|  | @@ -643,7 +643,7 @@
 | ||||||
|  |   */ | ||||||
|  |  int | ||||||
|  |  gdev_vector_dopath_segment(gdev_vector_dopath_state_t *state, int pe_op, | ||||||
|  | -                           gs_fixed_point vs[3])
 | ||||||
|  | +                           gs_fixed_point *vs)
 | ||||||
|  |  { | ||||||
|  |      gx_device_vector *vdev = state->vdev; | ||||||
|  |      const gs_matrix *const pmat = &state->scale_mat; | ||||||
|  | diff -ur ghostscript-9.54.0/base/gdevvec.h ghostscript-9.54.0-patched/base/gdevvec.h
 | ||||||
|  | --- ghostscript-9.54.0/base/gdevvec.h
 | ||||||
|  | +++ ghostscript-9.54.0-patched/base/gdevvec.h
 | ||||||
|  | @@ -306,7 +306,7 @@
 | ||||||
|  |   | ||||||
|  |  /* Write a segment of a path using the default implementation. */ | ||||||
|  |  int gdev_vector_dopath_segment(gdev_vector_dopath_state_t *state, int pe_op, | ||||||
|  | -                               gs_fixed_point vs[3]);
 | ||||||
|  | +                               gs_fixed_point *vs);
 | ||||||
|  |   | ||||||
|  |  typedef struct gdev_vector_path_seg_record_s { | ||||||
|  |      int op; | ||||||
|  | diff -ur ghostscript-9.54.0/base/gxclpath.c ghostscript-9.54.0-patched/base/gxclpath.c
 | ||||||
|  | --- ghostscript-9.54.0/base/gxclpath.c	2021-03-30 09:40:28.000000000 +0200
 | ||||||
|  | +++ ghostscript-9.54.0-patched/base/gxclpath.c	2021-11-23 11:06:14.670137576 +0100
 | ||||||
|  | @@ -715,10 +715,10 @@
 | ||||||
|  |          } else { | ||||||
|  |              code = set_cmd_put_op(&dp, cldev, pcls, cmd_opv_set_color_space, | ||||||
|  |                  2 + sizeof(clist_icc_color_t)); | ||||||
|  | -            memcpy(dp + 2, &(cldev->color_space.icc_info),
 | ||||||
|  | -                   sizeof(clist_icc_color_t));
 | ||||||
|  |              if (code < 0) | ||||||
|  |                  return code; | ||||||
|  | +            memcpy(dp + 2, &(cldev->color_space.icc_info),
 | ||||||
|  | +                   sizeof(clist_icc_color_t));
 | ||||||
|  |          } | ||||||
|  |          dp[1] = cldev->color_space.byte1; | ||||||
|  |          pcls->known |= color_space_known; | ||||||
|  | diff -ur ghostscript-9.54.0/extract/src/mem.c ghostscript-9.54.0-patched/extract/src/mem.c
 | ||||||
|  | --- ghostscript-9.54.0/extract/src/mem.c	2021-03-30 09:40:28.000000000 +0200
 | ||||||
|  | +++ ghostscript-9.54.0-patched/extract/src/mem.c	2021-11-23 11:11:37.293082828 +0100
 | ||||||
|  | @@ -19,14 +19,24 @@
 | ||||||
|  |  int extract_vasprintf(extract_alloc_t* alloc, char** out, const char* format, va_list va) | ||||||
|  |  { | ||||||
|  |      int n; | ||||||
|  | -    int n2;
 | ||||||
|  | +    int ret;
 | ||||||
|  |      va_list va2; | ||||||
|  |      va_copy(va2, va); | ||||||
|  |      n = vsnprintf(NULL, 0, format, va); | ||||||
|  | -    if (n < 0) return n;
 | ||||||
|  | -    if (extract_malloc(alloc, out, n + 1)) return -1;
 | ||||||
|  | -    n2 = vsnprintf(*out, n + 1, format, va2);
 | ||||||
|  | +    if (n < 0)
 | ||||||
|  | +    {
 | ||||||
|  | +        ret = n;
 | ||||||
|  | +        goto end;
 | ||||||
|  | +    }
 | ||||||
|  | +    if (extract_malloc(alloc, out, n + 1))
 | ||||||
|  | +    {
 | ||||||
|  | +        ret = -1;
 | ||||||
|  | +        goto end;
 | ||||||
|  | +    }
 | ||||||
|  | +    vsnprintf(*out, n + 1, format, va2);
 | ||||||
|  | +    ret = 0;
 | ||||||
|  | +
 | ||||||
|  | +    end:
 | ||||||
|  |      va_end(va2); | ||||||
|  | -    assert(n2 == n);
 | ||||||
|  | -    return n2;
 | ||||||
|  | +    return ret;
 | ||||||
|  |  } | ||||||
|  | diff -ur ghostscript-9.54.0/psi/icie.h ghostscript-9.54.0-patched/psi/icie.h
 | ||||||
|  | --- ghostscript-9.54.0/psi/icie.h	2021-03-30 09:40:28.000000000 +0200
 | ||||||
|  | +++ ghostscript-9.54.0-patched/psi/icie.h	2021-10-29 12:48:43.405814563 +0200
 | ||||||
|  | @@ -53,7 +53,7 @@
 | ||||||
|  |   | ||||||
|  |  /* Get 3 procedures from a dictionary. */ | ||||||
|  |  int dict_proc3_param(const gs_memory_t *mem, const ref *pdref, | ||||||
|  | -                     const char *kstr, ref proc3[3]);
 | ||||||
|  | +                     const char *kstr, ref *proc3);
 | ||||||
|  |   | ||||||
|  |  /* Get WhitePoint and BlackPoint values. */ | ||||||
|  |  int cie_points_param(const gs_memory_t *mem, | ||||||
|  | diff -ur ghostscript-9.54.0/psi/zcie.c ghostscript-9.54.0-patched/psi/zcie.c
 | ||||||
|  | --- ghostscript-9.54.0/psi/zcie.c	2021-03-30 09:40:28.000000000 +0200
 | ||||||
|  | +++ ghostscript-9.54.0-patched/psi/zcie.c	2021-11-02 14:36:28.463448728 +0100
 | ||||||
|  | @@ -144,7 +144,7 @@
 | ||||||
|  |   | ||||||
|  |  /* Get 3 procedures from a dictionary. */ | ||||||
|  |  int | ||||||
|  | -dict_proc3_param(const gs_memory_t *mem, const ref *pdref, const char *kstr, ref proc3[3])
 | ||||||
|  | +dict_proc3_param(const gs_memory_t *mem, const ref *pdref, const char *kstr, ref *proc3)
 | ||||||
|  |  { | ||||||
|  |      return dict_proc_array_param(mem, pdref, kstr, 3, proc3); | ||||||
|  |  } | ||||||
							
								
								
									
										46
									
								
								SOURCES/ghostscript-9.54.0-gdevtxtw-null-also-pointers.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								SOURCES/ghostscript-9.54.0-gdevtxtw-null-also-pointers.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | |||||||
|  | diff --git a/devices/vector/gdevtxtw.c b/devices/vector/gdevtxtw.c
 | ||||||
|  | index c6b95ed5b..f103d598b 100644
 | ||||||
|  | --- a/devices/vector/gdevtxtw.c
 | ||||||
|  | +++ b/devices/vector/gdevtxtw.c
 | ||||||
|  | @@ -1982,16 +1982,26 @@ textw_text_release(gs_text_enum_t *pte, client_name_t cname)
 | ||||||
|  |      gx_device_txtwrite_t *const tdev = (gx_device_txtwrite_t *) pte->dev; | ||||||
|  |   | ||||||
|  |      /* Free the working buffer where the Unicode was assembled from the enumerated text */ | ||||||
|  | -    if (penum->TextBuffer)
 | ||||||
|  | +    if (penum->TextBuffer) {
 | ||||||
|  |          gs_free(tdev->memory, penum->TextBuffer, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer"); | ||||||
|  | -    if (penum->Widths)
 | ||||||
|  | +        penum->TextBuffer = NULL;
 | ||||||
|  | +    }
 | ||||||
|  | +    if (penum->Widths) {
 | ||||||
|  |          gs_free(tdev->memory, penum->Widths, sizeof(float), pte->text.size, "txtwrite free temporary widths array"); | ||||||
|  | -    if (penum->Advs)
 | ||||||
|  | +        penum->Widths = NULL;
 | ||||||
|  | +    }
 | ||||||
|  | +    if (penum->Advs) {
 | ||||||
|  |          gs_free(tdev->memory, penum->Advs, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer"); | ||||||
|  | -    if (penum->GlyphWidths)
 | ||||||
|  | +        penum->Advs = NULL;
 | ||||||
|  | +    }
 | ||||||
|  | +    if (penum->GlyphWidths) {
 | ||||||
|  |          gs_free(tdev->memory, penum->GlyphWidths, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer"); | ||||||
|  | -    if (penum->SpanDeltaX)
 | ||||||
|  | +        penum->GlyphWidths = NULL;
 | ||||||
|  | +    }
 | ||||||
|  | +    if (penum->SpanDeltaX) {
 | ||||||
|  |          gs_free(tdev->memory, penum->SpanDeltaX, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer"); | ||||||
|  | +        penum->SpanDeltaX = NULL;
 | ||||||
|  | +    }
 | ||||||
|  |      /* If this is copied away when we complete the text enumeration succesfully, then | ||||||
|  |       * we set the pointer to NULL, if we get here with it non-NULL , then there was | ||||||
|  |       * an error. | ||||||
|  | @@ -2008,6 +2018,7 @@ textw_text_release(gs_text_enum_t *pte, client_name_t cname)
 | ||||||
|  |          if (penum->text_state->FontName) | ||||||
|  |              gs_free(tdev->memory, penum->text_state->FontName, 1, penum->TextBufferIndex, "txtwrite free temporary font name copy"); | ||||||
|  |          gs_free(tdev->memory, penum->text_state, 1, sizeof(penum->text_state), "txtwrite free text state"); | ||||||
|  | +        penum->text_state = NULL;
 | ||||||
|  |      } | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.17.1 | ||||||
| @ -0,0 +1,208 @@ | |||||||
|  | diff --git a/base/gdevpipe.c b/base/gdevpipe.c
 | ||||||
|  | index 96d71f5d81..752a2f1d94 100644
 | ||||||
|  | --- a/base/gdevpipe.c
 | ||||||
|  | +++ b/base/gdevpipe.c
 | ||||||
|  | @@ -72,8 +72,28 @@ pipe_fopen(gx_io_device * iodev, const char *fname, const char *access,
 | ||||||
|  |  #else | ||||||
|  |      gs_lib_ctx_t *ctx = mem->gs_lib_ctx; | ||||||
|  |      gs_fs_list_t *fs = ctx->core->fs; | ||||||
|  | +    /* The pipe device can be reached in two ways, explicltly with %pipe%
 | ||||||
|  | +       or implicitly with "|", so we have to check for both
 | ||||||
|  | +     */
 | ||||||
|  | +    char f[gp_file_name_sizeof];
 | ||||||
|  | +    const char *pipestr = "|";
 | ||||||
|  | +    const size_t pipestrlen = strlen(pipestr);
 | ||||||
|  | +    int code1;
 | ||||||
|  | +    const size_t preflen = strlen(iodev->dname);
 | ||||||
|  | +    const size_t nlen = strlen(fname);
 | ||||||
|  | +
 | ||||||
|  | +    if (preflen + nlen >= gp_file_name_sizeof)
 | ||||||
|  | +        return_error(gs_error_invalidaccess);
 | ||||||
|  | +
 | ||||||
|  | +    memcpy(f, iodev->dname, preflen);
 | ||||||
|  | +    memcpy(f + preflen, fname, nlen + 1);
 | ||||||
|  | +
 | ||||||
|  | +    code1 = gp_validate_path(mem, f, access);
 | ||||||
|  | +
 | ||||||
|  | +    memcpy(f, pipestr, pipestrlen);
 | ||||||
|  | +    memcpy(f + pipestrlen, fname, nlen + 1);
 | ||||||
|  |   | ||||||
|  | -    if (gp_validate_path(mem, fname, access) != 0)
 | ||||||
|  | +    if (code1 != 0 && gp_validate_path(mem, f, access) != 0 )
 | ||||||
|  |          return gs_error_invalidfileaccess; | ||||||
|  |   | ||||||
|  |      /* | ||||||
|  | diff --git a/base/gp_mshdl.c b/base/gp_mshdl.c
 | ||||||
|  | index 2b964ed749..8d87ceadc0 100644
 | ||||||
|  | --- a/base/gp_mshdl.c
 | ||||||
|  | +++ b/base/gp_mshdl.c
 | ||||||
|  | @@ -95,8 +95,17 @@ mswin_handle_fopen(gx_io_device * iodev, const char *fname, const char *access,
 | ||||||
|  |      long hfile;	/* Correct for Win32, may be wrong for Win64 */ | ||||||
|  |      gs_lib_ctx_t *ctx = mem->gs_lib_ctx; | ||||||
|  |      gs_fs_list_t *fs = ctx->core->fs; | ||||||
|  | +    char f[gp_file_name_sizeof];
 | ||||||
|  | +    const size_t preflen = strlen(iodev->dname);
 | ||||||
|  | +    const size_t nlen = strlen(fname);
 | ||||||
|  |   | ||||||
|  | -    if (gp_validate_path(mem, fname, access) != 0)
 | ||||||
|  | +    if (preflen + nlen >= gp_file_name_sizeof)
 | ||||||
|  | +        return_error(gs_error_invalidaccess);
 | ||||||
|  | +
 | ||||||
|  | +    memcpy(f, iodev->dname, preflen);
 | ||||||
|  | +    memcpy(f + preflen, fname, nlen + 1);
 | ||||||
|  | +
 | ||||||
|  | +    if (gp_validate_path(mem, f, access) != 0)
 | ||||||
|  |          return gs_error_invalidfileaccess; | ||||||
|  |   | ||||||
|  |      /* First we try the open_handle method. */ | ||||||
|  | diff --git a/base/gp_msprn.c b/base/gp_msprn.c
 | ||||||
|  | index ed48279685..746a974f78 100644
 | ||||||
|  | --- a/base/gp_msprn.c
 | ||||||
|  | +++ b/base/gp_msprn.c
 | ||||||
|  | @@ -168,8 +168,16 @@ mswin_printer_fopen(gx_io_device * iodev, const char *fname, const char *access,
 | ||||||
|  |      uintptr_t *ptid = &((tid_t *)(iodev->state))->tid; | ||||||
|  |      gs_lib_ctx_t *ctx = mem->gs_lib_ctx; | ||||||
|  |      gs_fs_list_t *fs = ctx->core->fs; | ||||||
|  | +    const size_t preflen = strlen(iodev->dname);
 | ||||||
|  | +    const size_t nlen = strlen(fname);
 | ||||||
|  |   | ||||||
|  | -    if (gp_validate_path(mem, fname, access) != 0)
 | ||||||
|  | +    if (preflen + nlen >= gp_file_name_sizeof)
 | ||||||
|  | +        return_error(gs_error_invalidaccess);
 | ||||||
|  | +
 | ||||||
|  | +    memcpy(pname, iodev->dname, preflen);
 | ||||||
|  | +    memcpy(pname + preflen, fname, nlen + 1);
 | ||||||
|  | +
 | ||||||
|  | +    if (gp_validate_path(mem, pname, access) != 0)
 | ||||||
|  |          return gs_error_invalidfileaccess; | ||||||
|  |   | ||||||
|  |      /* First we try the open_printer method. */ | ||||||
|  | diff --git a/base/gp_os2pr.c b/base/gp_os2pr.c
 | ||||||
|  | index f852c71fc8..ba54cde66f 100644
 | ||||||
|  | --- a/base/gp_os2pr.c
 | ||||||
|  | +++ b/base/gp_os2pr.c
 | ||||||
|  | @@ -107,9 +107,20 @@ os2_printer_fopen(gx_io_device * iodev, const char *fname, const char *access,
 | ||||||
|  |             FILE ** pfile, char *rfname, uint rnamelen) | ||||||
|  |  { | ||||||
|  |      os2_printer_t *pr = (os2_printer_t *)iodev->state; | ||||||
|  | -    char driver_name[256];
 | ||||||
|  | +    char driver_name[gp_file_name_sizeof];
 | ||||||
|  |      gs_lib_ctx_t *ctx = mem->gs_lib_ctx; | ||||||
|  |      gs_fs_list_t *fs = ctx->core->fs; | ||||||
|  | +    const size_t preflen = strlen(iodev->dname);
 | ||||||
|  | +    const int size_t = strlen(fname);
 | ||||||
|  | +
 | ||||||
|  | +    if (preflen + nlen >= gp_file_name_sizeof)
 | ||||||
|  | +        return_error(gs_error_invalidaccess);
 | ||||||
|  | +
 | ||||||
|  | +    memcpy(driver_name, iodev->dname, preflen);
 | ||||||
|  | +    memcpy(driver_name + preflen, fname, nlen + 1);
 | ||||||
|  | +
 | ||||||
|  | +    if (gp_validate_path(mem, driver_name, access) != 0)
 | ||||||
|  | +        return gs_error_invalidfileaccess;
 | ||||||
|  |   | ||||||
|  |      /* First we try the open_printer method. */ | ||||||
|  |      /* Note that the loop condition here ensures we don't | ||||||
|  | diff --git a/base/gslibctx.c b/base/gslibctx.c
 | ||||||
|  | index 6dfed6cd5a..318039fad0 100644
 | ||||||
|  | --- a/base/gslibctx.c
 | ||||||
|  | +++ b/base/gslibctx.c
 | ||||||
|  | @@ -655,82 +655,39 @@ rewrite_percent_specifiers(char *s)
 | ||||||
|  |  int | ||||||
|  |  gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname) | ||||||
|  |  { | ||||||
|  | -    char *fp, f[gp_file_name_sizeof];
 | ||||||
|  | -    const int pipe = 124; /* ASCII code for '|' */
 | ||||||
|  | -    const int len = strlen(fname);
 | ||||||
|  | -    int i, code;
 | ||||||
|  | +    char f[gp_file_name_sizeof];
 | ||||||
|  | +    int code;
 | ||||||
|  |   | ||||||
|  |      /* Be sure the string copy will fit */ | ||||||
|  | -    if (len >= gp_file_name_sizeof)
 | ||||||
|  | +    if (strlen(fname) >= gp_file_name_sizeof)
 | ||||||
|  |          return gs_error_rangecheck; | ||||||
|  |      strcpy(f, fname); | ||||||
|  | -    fp = f;
 | ||||||
|  |      /* Try to rewrite any %d (or similar) in the string */ | ||||||
|  |      rewrite_percent_specifiers(f); | ||||||
|  | -    for (i = 0; i < len; i++) {
 | ||||||
|  | -        if (f[i] == pipe) {
 | ||||||
|  | -           fp = &f[i + 1];
 | ||||||
|  | -           /* Because we potentially have to check file permissions at two levels
 | ||||||
|  | -              for the output file (gx_device_open_output_file and the low level
 | ||||||
|  | -              fopen API, if we're using a pipe, we have to add both the full string,
 | ||||||
|  | -              (including the '|', and just the command to which we pipe - since at
 | ||||||
|  | -              the pipe_fopen(), the leading '|' has been stripped.
 | ||||||
|  | -            */
 | ||||||
|  | -           code = gs_add_control_path(mem, gs_permit_file_writing, f);
 | ||||||
|  | -           if (code < 0)
 | ||||||
|  | -               return code;
 | ||||||
|  | -           code = gs_add_control_path(mem, gs_permit_file_control, f);
 | ||||||
|  | -           if (code < 0)
 | ||||||
|  | -               return code;
 | ||||||
|  | -           break;
 | ||||||
|  | -        }
 | ||||||
|  | -        if (!IS_WHITESPACE(f[i]))
 | ||||||
|  | -            break;
 | ||||||
|  | -    }
 | ||||||
|  | -    code = gs_add_control_path(mem, gs_permit_file_control, fp);
 | ||||||
|  | +
 | ||||||
|  | +    code = gs_add_control_path(mem, gs_permit_file_control, f);
 | ||||||
|  |      if (code < 0) | ||||||
|  |          return code; | ||||||
|  | -    return gs_add_control_path(mem, gs_permit_file_writing, fp);
 | ||||||
|  | +    return gs_add_control_path(mem, gs_permit_file_writing, f);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  int | ||||||
|  |  gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname) | ||||||
|  |  { | ||||||
|  | -    char *fp, f[gp_file_name_sizeof];
 | ||||||
|  | -    const int pipe = 124; /* ASCII code for '|' */
 | ||||||
|  | -    const int len = strlen(fname);
 | ||||||
|  | -    int i, code;
 | ||||||
|  | +    char f[gp_file_name_sizeof];
 | ||||||
|  | +    int code;
 | ||||||
|  |   | ||||||
|  |      /* Be sure the string copy will fit */ | ||||||
|  | -    if (len >= gp_file_name_sizeof)
 | ||||||
|  | +    if (strlen(fname) >= gp_file_name_sizeof)
 | ||||||
|  |          return gs_error_rangecheck; | ||||||
|  |      strcpy(f, fname); | ||||||
|  | -    fp = f;
 | ||||||
|  |      /* Try to rewrite any %d (or similar) in the string */ | ||||||
|  | -    for (i = 0; i < len; i++) {
 | ||||||
|  | -        if (f[i] == pipe) {
 | ||||||
|  | -           fp = &f[i + 1];
 | ||||||
|  | -           /* Because we potentially have to check file permissions at two levels
 | ||||||
|  | -              for the output file (gx_device_open_output_file and the low level
 | ||||||
|  | -              fopen API, if we're using a pipe, we have to add both the full string,
 | ||||||
|  | -              (including the '|', and just the command to which we pipe - since at
 | ||||||
|  | -              the pipe_fopen(), the leading '|' has been stripped.
 | ||||||
|  | -            */
 | ||||||
|  | -           code = gs_remove_control_path(mem, gs_permit_file_writing, f);
 | ||||||
|  | -           if (code < 0)
 | ||||||
|  | -               return code;
 | ||||||
|  | -           code = gs_remove_control_path(mem, gs_permit_file_control, f);
 | ||||||
|  | -           if (code < 0)
 | ||||||
|  | -               return code;
 | ||||||
|  | -           break;
 | ||||||
|  | -        }
 | ||||||
|  | -        if (!IS_WHITESPACE(f[i]))
 | ||||||
|  | -            break;
 | ||||||
|  | -    }
 | ||||||
|  | -    code = gs_remove_control_path(mem, gs_permit_file_control, fp);
 | ||||||
|  | +    rewrite_percent_specifiers(f);
 | ||||||
|  | +
 | ||||||
|  | +    code = gs_remove_control_path(mem, gs_permit_file_control, f);
 | ||||||
|  |      if (code < 0) | ||||||
|  |          return code; | ||||||
|  | -    return gs_remove_control_path(mem, gs_permit_file_writing, fp);
 | ||||||
|  | +    return gs_remove_control_path(mem, gs_permit_file_writing, f);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  int | ||||||
|  | -- 
 | ||||||
|  | 2.17.1 | ||||||
|  | 
 | ||||||
| @ -1,43 +0,0 @@ | |||||||
| From 5b85ddd19a8420a1bd2d5529325be35d78e94234 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Chris Liddell <chris.liddell@artifex.com> |  | ||||||
| Date: Fri, 2 Aug 2019 15:18:26 +0100 |  | ||||||
| Subject: Bug 701394: protect use of .forceput with executeonly |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| diff --git a/Resource/Init/gs_type1.ps b/Resource/Init/gs_type1.ps
 |  | ||||||
| index 6c7735bc0c..a039ccee35 100644
 |  | ||||||
| --- a/Resource/Init/gs_type1.ps
 |  | ||||||
| +++ b/Resource/Init/gs_type1.ps
 |  | ||||||
| @@ -118,25 +118,25 @@
 |  | ||||||
|                           ( to be the same as glyph: ) print 1 index //== exec } if |  | ||||||
|                     3 index exch 3 index .forceput |  | ||||||
|                                                                   % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname |  | ||||||
| -                 }
 |  | ||||||
| +                 }executeonly
 |  | ||||||
|                   {pop} ifelse |  | ||||||
| -               } forall
 |  | ||||||
| +               } executeonly forall
 |  | ||||||
|                 pop pop |  | ||||||
| -             }
 |  | ||||||
| +             } executeonly
 |  | ||||||
|               { |  | ||||||
|                 pop pop pop |  | ||||||
|               } ifelse |  | ||||||
| -           }
 |  | ||||||
| +           } executeonly
 |  | ||||||
|             { |  | ||||||
|                                                                 % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname |  | ||||||
|               pop pop |  | ||||||
|             } ifelse |  | ||||||
| -         } forall
 |  | ||||||
| +         } executeonly forall
 |  | ||||||
|           3 1 roll pop pop |  | ||||||
| -     } if
 |  | ||||||
| +     } executeonly if
 |  | ||||||
|       pop |  | ||||||
|       dup /.AGLprocessed~GS //true .forceput |  | ||||||
| -   } if
 |  | ||||||
| +   } executeonly if
 |  | ||||||
|   |  | ||||||
|     %% We need to excute the C .buildfont1 in a stopped context so that, if there |  | ||||||
|     %% are errors we can put the stack back sanely and exit. Otherwise callers won't |  | ||||||
| @ -1,56 +0,0 @@ | |||||||
| From 885444fcbe10dc42787ecb76686c8ee4dd33bf33 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ken Sharp <ken.sharp@artifex.com> |  | ||||||
| Date: Tue, 20 Aug 2019 10:10:28 +0100 |  | ||||||
| Subject: make .forceput inaccessible |  | ||||||
| 
 |  | ||||||
| Bug #701343, #701344, #701345 |  | ||||||
| 
 |  | ||||||
| More defensive programming. We don't want people to access .forecput |  | ||||||
| even though it is no longer sufficient to bypass SAFER. The exploit |  | ||||||
| in #701343 didn't work anyway because of earlier work to stop the error |  | ||||||
| handler being used, but nevertheless, prevent access to .forceput from |  | ||||||
| .setuserparams2. |  | ||||||
| 
 |  | ||||||
| diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps
 |  | ||||||
| index 4cc7f820f..0fd416465 100644
 |  | ||||||
| --- a/Resource/Init/gs_lev2.ps
 |  | ||||||
| +++ b/Resource/Init/gs_lev2.ps
 |  | ||||||
| @@ -158,7 +158,7 @@ end
 |  | ||||||
|      { |  | ||||||
|        pop pop |  | ||||||
|      } ifelse |  | ||||||
| -  } forall
 |  | ||||||
| +  } executeonly forall
 |  | ||||||
|          % A context switch might have occurred during the above loop, |  | ||||||
|          % causing the interpreter-level parameters to be reset. |  | ||||||
|          % Set them again to the new values.  From here on, we are safe, |  | ||||||
| @@ -229,9 +229,9 @@ end
 |  | ||||||
|         { pop pop |  | ||||||
|         } |  | ||||||
|        ifelse |  | ||||||
| -    }
 |  | ||||||
| +    } executeonly
 |  | ||||||
|     forall pop |  | ||||||
| -} .bind odef
 |  | ||||||
| +} .bind executeonly odef
 |  | ||||||
|   |  | ||||||
|  % Initialize the passwords. |  | ||||||
|  % NOTE: the names StartJobPassword and SystemParamsPassword are known to |  | ||||||
| diff --git a/Resource/Init/gs_pdfwr.ps b/Resource/Init/gs_pdfwr.ps
 |  | ||||||
| index c158a8faf..422e66e1a 100644
 |  | ||||||
| --- a/Resource/Init/gs_pdfwr.ps
 |  | ||||||
| +++ b/Resource/Init/gs_pdfwr.ps
 |  | ||||||
| @@ -658,11 +658,11 @@ currentdict /.pdfmarkparams .undef
 |  | ||||||
|            systemdict /.pdf_hooked_DSC_Creator //true .forceput |  | ||||||
|          } executeonly if |  | ||||||
|          pop |  | ||||||
| -      } if
 |  | ||||||
| +      } executeonly if
 |  | ||||||
|      } { |  | ||||||
|        pop |  | ||||||
|      } ifelse |  | ||||||
| -  }
 |  | ||||||
| +  } executeonly
 |  | ||||||
|    { |  | ||||||
|      pop |  | ||||||
|    } ifelse |  | ||||||
| @ -1,189 +0,0 @@ | |||||||
| diff --git a/Resource/Init/pdf_base.ps b/Resource/Init/pdf_base.ps
 |  | ||||||
| index 1a218f4..cffde5c 100644
 |  | ||||||
| --- a/Resource/Init/pdf_base.ps
 |  | ||||||
| +++ b/Resource/Init/pdf_base.ps
 |  | ||||||
| @@ -157,7 +157,7 @@ currentdict /num-chars-dict .undef
 |  | ||||||
|      { |  | ||||||
|        dup ==only () = flush |  | ||||||
|      } ifelse % PDFSTEP |  | ||||||
| -  } if % PDFDEBUG
 |  | ||||||
| +  } executeonly if % PDFDEBUG
 |  | ||||||
|    2 copy .knownget { |  | ||||||
|      exch pop exch pop exch pop exec |  | ||||||
|    } { |  | ||||||
| diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps
 |  | ||||||
| index e18a7c2..0a3924c 100644
 |  | ||||||
| --- a/Resource/Init/pdf_draw.ps
 |  | ||||||
| +++ b/Resource/Init/pdf_draw.ps
 |  | ||||||
| @@ -501,8 +501,8 @@ end
 |  | ||||||
|        (        Output may be incorrect.\n) pdfformaterror |  | ||||||
|        //pdfdict /.gs_warning_issued //true .forceput |  | ||||||
|        PDFSTOPONERROR { /gs /undefined signalerror } if |  | ||||||
| -    } if
 |  | ||||||
| -  }
 |  | ||||||
| +    } executeonly if
 |  | ||||||
| +  } executeonly
 |  | ||||||
|    ifelse |  | ||||||
|  } bind executeonly def |  | ||||||
|   |  | ||||||
| @@ -1142,7 +1142,7 @@ currentdict end readonly def
 |  | ||||||
|            .setglobal |  | ||||||
|            pdfformaterror |  | ||||||
|          } executeonly ifelse |  | ||||||
| -      }
 |  | ||||||
| +      } executeonly
 |  | ||||||
|        { |  | ||||||
|          currentglobal //pdfdict gcheck .setglobal |  | ||||||
|          //pdfdict /.Qqwarning_issued //true .forceput |  | ||||||
| @@ -1150,8 +1150,8 @@ currentdict end readonly def
 |  | ||||||
|          pdfformaterror |  | ||||||
|        } executeonly ifelse |  | ||||||
|        end |  | ||||||
| -    } ifelse
 |  | ||||||
| -  } loop
 |  | ||||||
| +    } executeonly ifelse
 |  | ||||||
| +  } executeonly loop
 |  | ||||||
|    { |  | ||||||
|      (\n   **** Error: File has unbalanced q/Q operators \(too many q's\)\n               Output may be incorrect.\n) |  | ||||||
|      //pdfdict /.Qqwarning_issued .knownget |  | ||||||
| @@ -1165,14 +1165,14 @@ currentdict end readonly def
 |  | ||||||
|          .setglobal |  | ||||||
|          pdfformaterror |  | ||||||
|        } executeonly ifelse |  | ||||||
| -    }
 |  | ||||||
| +    } executeonly
 |  | ||||||
|      { |  | ||||||
|        currentglobal //pdfdict gcheck .setglobal |  | ||||||
|        //pdfdict /.Qqwarning_issued //true .forceput |  | ||||||
|        .setglobal |  | ||||||
|        pdfformaterror |  | ||||||
|      } executeonly ifelse |  | ||||||
| -  } if
 |  | ||||||
| +  } executeonly if
 |  | ||||||
|    pop |  | ||||||
|   |  | ||||||
|    % restore pdfemptycount |  | ||||||
| diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps
 |  | ||||||
| index 9fb85f6..357ba30 100644
 |  | ||||||
| --- a/Resource/Init/pdf_font.ps
 |  | ||||||
| +++ b/Resource/Init/pdf_font.ps
 |  | ||||||
| @@ -677,7 +677,7 @@ currentdict end readonly def
 |  | ||||||
|                  currentglobal 2 index dup gcheck setglobal |  | ||||||
|                  /FontInfo 5 dict dup 5 1 roll .forceput |  | ||||||
|                  setglobal |  | ||||||
| -              } if
 |  | ||||||
| +              } executeonly if
 |  | ||||||
|                dup /GlyphNames2Unicode .knownget not { |  | ||||||
|                  //true                        % No existing G2U, make one |  | ||||||
|                } { |  | ||||||
| @@ -701,9 +701,9 @@ currentdict end readonly def
 |  | ||||||
|          } if |  | ||||||
|          PDFDEBUG { |  | ||||||
|            (.processToUnicode end) = |  | ||||||
| -        } if
 |  | ||||||
| -      } if
 |  | ||||||
| -    } stopped
 |  | ||||||
| +        } executeonly if
 |  | ||||||
| +      } executeonly if
 |  | ||||||
| +    } executeonly stopped
 |  | ||||||
|      { |  | ||||||
|        .dstackdepth 1 countdictstack 1 sub |  | ||||||
|        {pop end} for |  | ||||||
| @@ -1233,19 +1233,20 @@ currentdict /eexec_pdf_param_dict .undef
 |  | ||||||
|                  //pdfdict /.Qqwarning_issued //true .forceput |  | ||||||
|                } executeonly if |  | ||||||
|                Q |  | ||||||
| -            } repeat
 |  | ||||||
| +            } executeonly repeat
 |  | ||||||
|              Q |  | ||||||
| -          } PDFfile fileposition 2 .execn % Keep pdfcount valid.
 |  | ||||||
| +          } executeonly PDFfile fileposition 2 .execn % Keep pdfcount valid.
 |  | ||||||
|            PDFfile exch setfileposition |  | ||||||
| -        } ifelse
 |  | ||||||
| -      } {
 |  | ||||||
| +        } executeonly ifelse
 |  | ||||||
| +      } executeonly
 |  | ||||||
| +      {
 |  | ||||||
|          % PDF Type 3 fonts don't use .notdef |  | ||||||
|          % d1 implementation adjusts the width as needed |  | ||||||
|          0 0 0 0 0 0 |  | ||||||
|          pdfopdict /d1 get exec |  | ||||||
|        } ifelse |  | ||||||
|        end end |  | ||||||
| -    } bdef
 |  | ||||||
| +    } executeonly bdef
 |  | ||||||
|      dup currentdict Encoding .processToUnicode |  | ||||||
|      currentdict end .completefont exch pop |  | ||||||
|  } bind executeonly odef |  | ||||||
| @@ -2045,9 +2046,9 @@ currentdict /CMap_read_dict undef
 |  | ||||||
|            (Will continue, but content may be missing.) = flush |  | ||||||
|          } ifelse |  | ||||||
|        } if |  | ||||||
| -    } if
 |  | ||||||
| +    } executeonly if
 |  | ||||||
|      /findresource cvx /undefined signalerror |  | ||||||
| -  } loop
 |  | ||||||
| +  } executeonly loop
 |  | ||||||
|  } bind executeonly odef |  | ||||||
|   |  | ||||||
|  /buildCIDType0 {	% <CIDFontType0-font-resource> buildCIDType0 <font> |  | ||||||
| diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps
 |  | ||||||
| index 5305ea6..a59e63c 100644
 |  | ||||||
| --- a/Resource/Init/pdf_main.ps
 |  | ||||||
| +++ b/Resource/Init/pdf_main.ps
 |  | ||||||
| @@ -2749,15 +2749,15 @@ currentdict /PDF2PS_matrix_key undef
 |  | ||||||
|            .setglobal |  | ||||||
|            pdfformaterror |  | ||||||
|          } executeonly ifelse |  | ||||||
| -      }
 |  | ||||||
| +      } executeonly
 |  | ||||||
|        { |  | ||||||
|          currentglobal //pdfdict gcheck .setglobal |  | ||||||
|          //pdfdict /.Qqwarning_issued //true .forceput |  | ||||||
|          .setglobal |  | ||||||
|          pdfformaterror |  | ||||||
|        } executeonly ifelse |  | ||||||
| -    } if
 |  | ||||||
| -  } if
 |  | ||||||
| +    } executeonly if
 |  | ||||||
| +  } executeonly if
 |  | ||||||
|    pop |  | ||||||
|    count PDFexecstackcount sub { pop } repeat |  | ||||||
|    (after exec) VMDEBUG |  | ||||||
| diff --git a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps
 |  | ||||||
| index 285e582..6c1f100 100644
 |  | ||||||
| --- a/Resource/Init/pdf_ops.ps
 |  | ||||||
| +++ b/Resource/Init/pdf_ops.ps
 |  | ||||||
| @@ -186,14 +186,14 @@ currentdict /gput_always_allow .undef
 |  | ||||||
|          .setglobal |  | ||||||
|          pdfformaterror |  | ||||||
|        } executeonly ifelse |  | ||||||
| -    }
 |  | ||||||
| +    } executeonly
 |  | ||||||
|      { |  | ||||||
|        currentglobal //pdfdict gcheck .setglobal |  | ||||||
|        //pdfdict /.Qqwarning_issued //true .forceput |  | ||||||
|        .setglobal |  | ||||||
|        pdfformaterror |  | ||||||
|      } executeonly ifelse |  | ||||||
| -  } if
 |  | ||||||
| +  } executeonly if
 |  | ||||||
|  } bind executeonly odef |  | ||||||
|   |  | ||||||
|  % Save PDF gstate |  | ||||||
| @@ -440,11 +440,12 @@ currentdict /gput_always_allow .undef
 |  | ||||||
|    dup type /booleantype eq { |  | ||||||
|      .currentSMask type /dicttype eq { |  | ||||||
|        .currentSMask /Processed 2 index .forceput |  | ||||||
| +    } executeonly
 |  | ||||||
| +    {
 |  | ||||||
| +      .setSMask
 |  | ||||||
| +    }ifelse
 |  | ||||||
|    } executeonly |  | ||||||
|    { |  | ||||||
| -      .setSMask
 |  | ||||||
| -  }ifelse
 |  | ||||||
| -  }{
 |  | ||||||
|    .setSMask |  | ||||||
|    }ifelse |  | ||||||
|   |  | ||||||
| @ -1,18 +0,0 @@ | |||||||
| diff --git a/devices/gdev3852.c b/devices/gdev3852.c
 |  | ||||||
| index e21b403..2bee8ec 100644
 |  | ||||||
| --- a/devices/gdev3852.c
 |  | ||||||
| +++ b/devices/gdev3852.c
 |  | ||||||
| @@ -76,6 +76,13 @@ jetp3852_print_page(gx_device_printer *pdev, FILE *prn_stream)
 |  | ||||||
|             {	int lnum; |  | ||||||
|                  int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev); |  | ||||||
|                  int num_blank_lines = 0; |  | ||||||
| +
 |  | ||||||
| +                if (line_size > DATA_SIZE) {
 |  | ||||||
| +                  emprintf2(pdev->memory, "invalid resolution and/or width gives line_size = %d, max. is %d\n",
 |  | ||||||
| +                            line_size, DATA_SIZE);
 |  | ||||||
| +                  return_error(gs_error_rangecheck);
 |  | ||||||
| +               }
 |  | ||||||
| +                
 |  | ||||||
|                  for ( lnum = 0; lnum < pdev->height; lnum++ ) |  | ||||||
|                     {	byte *end_data = data + line_size; |  | ||||||
|                          gdev_prn_copy_scan_lines(pdev, lnum, |  | ||||||
| @ -1,257 +0,0 @@ | |||||||
| diff --git a/contrib/gdevdj9.c b/contrib/gdevdj9.c
 |  | ||||||
| index eec1c77..a4e8e9c 100644
 |  | ||||||
| --- a/contrib/gdevdj9.c
 |  | ||||||
| +++ b/contrib/gdevdj9.c
 |  | ||||||
| @@ -575,26 +575,55 @@ static int cdj_set_bpp(gx_device *, int, int);
 |  | ||||||
|  static int |  | ||||||
|  hp_colour_open(gx_device * pdev) |  | ||||||
|  { |  | ||||||
| -    int retCode;
 |  | ||||||
| +    int retCode = 0;
 |  | ||||||
| +
 |  | ||||||
| +    /* Change the margins if necessary. */
 |  | ||||||
| +    static const float dj_a4[4] = {
 |  | ||||||
| +        DESKJET_MARGINS_A4
 |  | ||||||
| +    };
 |  | ||||||
| +
 |  | ||||||
| +    static const float dj_letter[4] = {
 |  | ||||||
| +        DESKJET_MARGINS_LETTER
 |  | ||||||
| +    };
 |  | ||||||
| +    const float *m = (float *)0;
 |  | ||||||
|   |  | ||||||
|      cdj970->PageCtr = 0; |  | ||||||
|   |  | ||||||
| +    /* quality setup */
 |  | ||||||
| +    if (cdj970->quality == DRAFT) {
 |  | ||||||
| +        gx_device_set_resolution((gx_device *) pdev, 300.0, 300.0);
 |  | ||||||
| +        cdj970->xscal = 0;
 |  | ||||||
| +        cdj970->yscal = 0;
 |  | ||||||
| +        cdj970->intensities = 2;
 |  | ||||||
| +    } else if (cdj970->quality == NORMAL) {
 |  | ||||||
| +        gx_device_set_resolution((gx_device *) pdev, 600.0, 600.0);
 |  | ||||||
| +        cdj970->xscal = 1;
 |  | ||||||
| +        cdj970->yscal = 1;
 |  | ||||||
| +        /* intensities = 4 from initialization */
 |  | ||||||
| +    } else {                    /* quality == PRESENTATION */
 |  | ||||||
| +        gx_device_set_resolution((gx_device *) pdev, 600.0, 600.0);
 |  | ||||||
| +        cdj970->xscal = 0;
 |  | ||||||
| +        cdj970->yscal = 0;
 |  | ||||||
| +        /* intensities = 4 from initialization */
 |  | ||||||
| +    }
 |  | ||||||
| +
 |  | ||||||
| +    m = (gdev_pcl_paper_size((gx_device *) pdev) ==
 |  | ||||||
| +         PAPER_SIZE_A4 ? dj_a4 : dj_letter);
 |  | ||||||
| +
 |  | ||||||
| +    gx_device_set_margins((gx_device *) pdev, m, true);
 |  | ||||||
| +
 |  | ||||||
|      /* Set up colour params if put_params has not already done so */ |  | ||||||
|      if (pdev->color_info.num_components == 0) { |  | ||||||
| -        int code = cdj_set_bpp(pdev, pdev->color_info.depth,
 |  | ||||||
| +        retCode = cdj_set_bpp(pdev, pdev->color_info.depth,
 |  | ||||||
|                                 pdev->color_info.num_components); |  | ||||||
|   |  | ||||||
| -        if (code < 0)
 |  | ||||||
| -            return code;
 |  | ||||||
| +        if (retCode < 0)
 |  | ||||||
| +            return retCode;
 |  | ||||||
|      } |  | ||||||
|   |  | ||||||
|      retCode = gdev_prn_open(pdev); |  | ||||||
| -    if (retCode < 0)
 |  | ||||||
| -        return (retCode);
 |  | ||||||
| -    else {
 |  | ||||||
| +    if (retCode >= 0) {
 |  | ||||||
|          retCode = gdev_prn_open_printer(pdev, true); |  | ||||||
| -        if (retCode < 0)
 |  | ||||||
| -            return (retCode);
 |  | ||||||
|      } |  | ||||||
|   |  | ||||||
|      return 0; |  | ||||||
| @@ -648,26 +677,25 @@ cdj970_put_params(gx_device * pdev, gs_param_list * plist)
 |  | ||||||
|      int bpp = 0; |  | ||||||
|      int code = 0; |  | ||||||
|   |  | ||||||
| -    code = cdj_put_param_int(plist, "BitsPerPixel", &bpp, 1, 32, code);
 |  | ||||||
| -    code = cdj_put_param_int(plist, "Quality", &quality, 0, 2, code);
 |  | ||||||
| -    code = cdj_put_param_int(plist, "Papertype", &papertype, 0, 4, code);
 |  | ||||||
| -    code = cdj_put_param_int(plist, "Duplex", &duplex, 0, 2, code);
 |  | ||||||
| -    code =
 |  | ||||||
| -        cdj_put_param_float(plist, "MasterGamma", &mastergamma, 0.1, 9.0,
 |  | ||||||
| -                            code);
 |  | ||||||
| -    code =
 |  | ||||||
| -        cdj_put_param_float(plist, "GammaValC", &gammavalc, 0.0, 9.0, code);
 |  | ||||||
| -    code =
 |  | ||||||
| -        cdj_put_param_float(plist, "GammaValM", &gammavalm, 0.0, 9.0, code);
 |  | ||||||
| -    code =
 |  | ||||||
| -        cdj_put_param_float(plist, "GammaValY", &gammavaly, 0.0, 9.0, code);
 |  | ||||||
| -    code =
 |  | ||||||
| -        cdj_put_param_float(plist, "GammaValK", &gammavalk, 0.0, 9.0, code);
 |  | ||||||
| -    code =
 |  | ||||||
| -        cdj_put_param_float(plist, "BlackCorrect", &blackcorrect, 0.0, 9.0,
 |  | ||||||
| -                            code);
 |  | ||||||
| -
 |  | ||||||
| -    if (code < 0)
 |  | ||||||
| +    if ((code = cdj_put_param_int(plist, "BitsPerPixel", &bpp, 1, 32, code)) < 0)
 |  | ||||||
| +        return code;
 |  | ||||||
| +    if ((code = cdj_put_param_int(plist, "Quality", &quality, 0, 2, code)) < 0)
 |  | ||||||
| +        return code;
 |  | ||||||
| +    if ((code = cdj_put_param_int(plist, "Papertype", &papertype, 0, 4, code)) < 0)
 |  | ||||||
| +        return code;
 |  | ||||||
| +    if ((code = cdj_put_param_int(plist, "Duplex", &duplex, 0, 2, code)) < 0)
 |  | ||||||
| +        return code;
 |  | ||||||
| +    if ((code = cdj_put_param_float(plist, "MasterGamma", &mastergamma, 0.1, 9.0, code)) < 0)
 |  | ||||||
| +        return code;
 |  | ||||||
| +    if ((code = cdj_put_param_float(plist, "GammaValC", &gammavalc, 0.0, 9.0, code)) < 0)
 |  | ||||||
| +        return code;
 |  | ||||||
| +    if ((code = cdj_put_param_float(plist, "GammaValM", &gammavalm, 0.0, 9.0, code)) < 0)
 |  | ||||||
| +        return code;
 |  | ||||||
| +    if ((code = cdj_put_param_float(plist, "GammaValY", &gammavaly, 0.0, 9.0, code)) < 0)
 |  | ||||||
| +        return code;
 |  | ||||||
| +    if ((code = cdj_put_param_float(plist, "GammaValK", &gammavalk, 0.0, 9.0, code)) < 0)
 |  | ||||||
| +        return code;
 |  | ||||||
| +    if ((code = cdj_put_param_float(plist, "BlackCorrect", &blackcorrect, 0.0, 9.0, code)) < 0)
 |  | ||||||
|          return code; |  | ||||||
|   |  | ||||||
|      code = cdj_put_param_bpp(pdev, plist, bpp, bpp, 0); |  | ||||||
| @@ -676,6 +704,12 @@ cdj970_put_params(gx_device * pdev, gs_param_list * plist)
 |  | ||||||
|          return code; |  | ||||||
|   |  | ||||||
|      cdj970->quality = quality; |  | ||||||
| +    if (cdj970->quality != quality) {
 |  | ||||||
| +        if (pdev->is_open)
 |  | ||||||
| +            gs_closedevice(pdev);      /* quality can change resolution, force re-open */
 |  | ||||||
| +        cdj970->quality = quality;
 |  | ||||||
| +    }
 |  | ||||||
| +
 |  | ||||||
|      cdj970->papertype = papertype; |  | ||||||
|      cdj970->duplex = duplex; |  | ||||||
|      cdj970->mastergamma = mastergamma; |  | ||||||
| @@ -685,7 +719,7 @@ cdj970_put_params(gx_device * pdev, gs_param_list * plist)
 |  | ||||||
|      cdj970->gammavalk = gammavalk; |  | ||||||
|      cdj970->blackcorrect = blackcorrect; |  | ||||||
|   |  | ||||||
| -    return 0;
 |  | ||||||
| +    return code;
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  /**********************************************************************************/ |  | ||||||
| @@ -784,47 +818,6 @@ cdj970_terminate_page(gx_device_printer * pdev, FILE * prn_stream)
 |  | ||||||
|      fputs("\033*rC\f\033&l-2H", prn_stream);    /* End Graphics, Reset */ |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -/* cdj970_one_time_initialisation:
 |  | ||||||
| -----------------------------------------------------------------------------------*/
 |  | ||||||
| -static void
 |  | ||||||
| -cdj970_one_time_initialisation(gx_device_printer * pdev)
 |  | ||||||
| -{
 |  | ||||||
| -    /* Change the margins if necessary. */
 |  | ||||||
| -    static const float dj_a4[4] = {
 |  | ||||||
| -        DESKJET_MARGINS_A4
 |  | ||||||
| -    };
 |  | ||||||
| -
 |  | ||||||
| -    static const float dj_letter[4] = {
 |  | ||||||
| -        DESKJET_MARGINS_LETTER
 |  | ||||||
| -    };
 |  | ||||||
| -    const float *m = (float *)0;
 |  | ||||||
| -
 |  | ||||||
| -    /* quality setup */
 |  | ||||||
| -    if (cdj970->quality == DRAFT) {
 |  | ||||||
| -        gx_device_set_resolution((gx_device *) pdev, 300.0, 300.0);
 |  | ||||||
| -        cdj970->xscal = 0;
 |  | ||||||
| -        cdj970->yscal = 0;
 |  | ||||||
| -        cdj970->intensities = 2;
 |  | ||||||
| -    } else if (cdj970->quality == NORMAL) {
 |  | ||||||
| -        gx_device_set_resolution((gx_device *) pdev, 600.0, 600.0);
 |  | ||||||
| -        cdj970->xscal = 1;
 |  | ||||||
| -        cdj970->yscal = 1;
 |  | ||||||
| -        /* intensities = 4 from initialization */
 |  | ||||||
| -    } else {                    /* quality == PRESENTATION */
 |  | ||||||
| -        gx_device_set_resolution((gx_device *) pdev, 600.0, 600.0);
 |  | ||||||
| -        cdj970->xscal = 0;
 |  | ||||||
| -        cdj970->yscal = 0;
 |  | ||||||
| -        /* intensities = 4 from initialization */
 |  | ||||||
| -    }
 |  | ||||||
| -
 |  | ||||||
| -    m = (gdev_pcl_paper_size((gx_device *) pdev) ==
 |  | ||||||
| -         PAPER_SIZE_A4 ? dj_a4 : dj_letter);
 |  | ||||||
| -
 |  | ||||||
| -    gx_device_set_margins((gx_device *) pdev, m, true);
 |  | ||||||
| -
 |  | ||||||
| -    cdj970_write_header((gx_device *) pdev, pdev->file);
 |  | ||||||
| -}
 |  | ||||||
| -
 |  | ||||||
|  /* cdj970_print_page: Here comes the hp970 output routine |  | ||||||
|  ----------------------------------------------------------------------------------*/ |  | ||||||
|  static int |  | ||||||
| @@ -837,7 +830,7 @@ cdj970_print_page(gx_device_printer * pdev, FILE * prn_stream)
 |  | ||||||
|      Gamma gamma; |  | ||||||
|   |  | ||||||
|      if (cdj970->PageCtr == 0 && cdj970->ptype == DJ970C) { |  | ||||||
| -        cdj970_one_time_initialisation(pdev);
 |  | ||||||
| +        cdj970_write_header((gx_device *)pdev, prn_stream);
 |  | ||||||
|      } |  | ||||||
|   |  | ||||||
|      /* make a local writable copy of the Gamma tables */ |  | ||||||
| @@ -2280,6 +2273,11 @@ cdj_set_bpp(gx_device * pdev, int bpp, int ccomps)
 |  | ||||||
|          ci->dither_colors = (bpp >= 8 ? 5 : bpp > 1 ? 2 : 0); |  | ||||||
|      } |  | ||||||
|   |  | ||||||
| +    if (ci->depth != ((bpp > 1) && (bpp < 8) ? 8 : bpp)) {
 |  | ||||||
| +        if (pdev->is_open)
 |  | ||||||
| +            gs_closedevice(pdev);  /* depth changed, make sure we re-open */
 |  | ||||||
| +    }
 |  | ||||||
| +
 |  | ||||||
|      ci->depth = ((bpp > 1) && (bpp < 8) ? 8 : bpp); |  | ||||||
|   |  | ||||||
|      return (0); |  | ||||||
| @@ -2598,16 +2596,15 @@ cdj_put_param_bpp(gx_device * pdev,
 |  | ||||||
|                    gs_param_list * plist, |  | ||||||
|                    int new_bpp, int real_bpp, int ccomps) |  | ||||||
|  { |  | ||||||
| -    if (new_bpp == 0 && ccomps == 0)
 |  | ||||||
| -        return gdev_prn_put_params(pdev, plist);
 |  | ||||||
| -    else {
 |  | ||||||
| -        gx_device_color_info save_info;
 |  | ||||||
| -        int save_bpp;
 |  | ||||||
| -        int code;
 |  | ||||||
| -
 |  | ||||||
| -        save_info = pdev->color_info;
 |  | ||||||
| -        save_bpp = save_info.depth;
 |  | ||||||
| +    int code = 0;
 |  | ||||||
| +    int save_bpp;
 |  | ||||||
| +    gx_device_color_info save_info;
 |  | ||||||
| +    save_info = pdev->color_info;
 |  | ||||||
| +    save_bpp = save_info.depth;
 |  | ||||||
|   |  | ||||||
| +    if (new_bpp == 0 && ccomps == 0) {
 |  | ||||||
| +       code = gdev_prn_put_params(pdev, plist);
 |  | ||||||
| +    } else {
 |  | ||||||
|          if (save_bpp == 8 && save_ccomps == 3 && !cprn_device->cmyk) |  | ||||||
|              save_bpp = 3; |  | ||||||
|   |  | ||||||
| @@ -2631,12 +2628,22 @@ cdj_put_param_bpp(gx_device * pdev,
 |  | ||||||
|          if ((cdj970->color_info.depth != save_bpp |  | ||||||
|               || (ccomps != 0 && ccomps != save_ccomps)) |  | ||||||
|              && pdev->is_open) |  | ||||||
| -            return (gs_closedevice(pdev));
 |  | ||||||
| +            gs_closedevice(pdev);
 |  | ||||||
| +    }
 |  | ||||||
| +
 |  | ||||||
| +    /* check for valid resolutions */
 |  | ||||||
| +    if (pdev->HWResolution[0] != pdev->HWResolution[1] ||
 |  | ||||||
| +        (pdev->HWResolution[0] != 300.0 && pdev->HWResolution[0] != 600.0) ) {
 |  | ||||||
| +        param_signal_error(plist, "HWResolution", gs_error_rangecheck);
 |  | ||||||
| +        emprintf1(pdev->memory, "\ncdj970: Invalid resolution: '%f'. Only 300 or 600 supported.\n\n",
 |  | ||||||
| +                  pdev->HWResolution[0]);
 |  | ||||||
| +        cdj_set_bpp(pdev, save_bpp, save_ccomps);
 |  | ||||||
| +        return gs_error_rangecheck;
 |  | ||||||
| +    }
 |  | ||||||
| +    return code;
 |  | ||||||
|   |  | ||||||
| -        return (0);
 |  | ||||||
|   |  | ||||||
|  #undef save_ccomps |  | ||||||
| -    }
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  /* cdj970_write_header: |  | ||||||
| @ -1,13 +0,0 @@ | |||||||
| diff --git a/base/gxblend.c b/base/gxblend.c
 |  | ||||||
| index 7c3d55b..55215d6 100644
 |  | ||||||
| --- a/base/gxblend.c
 |  | ||||||
| +++ b/base/gxblend.c
 |  | ||||||
| @@ -2174,7 +2174,7 @@ pdf14_compose_group(pdf14_buf *tos, pdf14_buf *nos, pdf14_buf *maskbuf,
 |  | ||||||
|               overprint == 0) { |  | ||||||
|               /* Additive vs Subtractive makes no difference in normal blend mode with no spots */ |  | ||||||
|          if (tos_isolated) { |  | ||||||
| -            if (has_mask || maskbuf) {/* 7% */
 |  | ||||||
| +            if (has_mask && maskbuf) {/* 7% */
 |  | ||||||
|                  /* AirPrint test case hits this */ |  | ||||||
|                  if (maskbuf && maskbuf->rect.p.x <= x0 && maskbuf->rect.p.y <= y0 && |  | ||||||
|                      maskbuf->rect.q.x >= x1 && maskbuf->rect.q.y >= y1) |  | ||||||
| @ -1,13 +0,0 @@ | |||||||
| diff --git a/devices/gdevclj.c b/devices/gdevclj.c
 |  | ||||||
| index bed13bc..fe17ece 100644
 |  | ||||||
| --- a/devices/gdevclj.c
 |  | ||||||
| +++ b/devices/gdevclj.c
 |  | ||||||
| @@ -254,7 +254,7 @@ clj_media_size(float mediasize[2], gs_param_list *plist)
 |  | ||||||
|      gs_param_int_array hwsize; |  | ||||||
|      int have_pagesize = 0; |  | ||||||
|   |  | ||||||
| -    if ( (param_read_float_array(plist, "HWResolution", &fres) == 0) &&
 |  | ||||||
| +    if ( param_read_float_array(plist, "HWResolution", &fres) != 0 ||
 |  | ||||||
|            !is_supported_resolution(fres.data) ) |  | ||||||
|          return_error(gs_error_rangecheck); |  | ||||||
|   |  | ||||||
| @ -1,58 +0,0 @@ | |||||||
| diff --git a/contrib/japanese/gdev10v.c b/contrib/japanese/gdev10v.c
 |  | ||||||
| index 5c8b7fb..53da0ec 100644
 |  | ||||||
| --- a/contrib/japanese/gdev10v.c
 |  | ||||||
| +++ b/contrib/japanese/gdev10v.c
 |  | ||||||
| @@ -73,8 +73,20 @@ gx_device_procs prn_bj10v_procs =
 |  | ||||||
|    prn_matrix_procs(gdev_prn_open, bj10v_get_initial_matrix, |  | ||||||
|      gdev_prn_output_page, gdev_prn_close); |  | ||||||
|  #endif |  | ||||||
| +
 |  | ||||||
| +static int
 |  | ||||||
| +bj10v_open(gx_device * pdev)
 |  | ||||||
| +{
 |  | ||||||
| +    if (pdev->HWResolution[0] < 180 ||
 |  | ||||||
| +        pdev->HWResolution[1] < 180)
 |  | ||||||
| +    {
 |  | ||||||
| +        emprintf(pdev->memory, "device requires a resolution of at least 180dpi\n");
 |  | ||||||
| +        return_error(gs_error_rangecheck);
 |  | ||||||
| +    }
 |  | ||||||
| +    return gdev_prn_open(pdev);
 |  | ||||||
| +}
 |  | ||||||
|  gx_device_procs prn_bj10v_procs = |  | ||||||
| -  prn_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close);
 |  | ||||||
| +  prn_procs(bj10v_open, gdev_prn_output_page, gdev_prn_close);
 |  | ||||||
|   |  | ||||||
|  gx_device_printer gs_bj10v_device = |  | ||||||
|    prn_device(prn_bj10v_procs, "bj10v", |  | ||||||
| diff --git a/contrib/japanese/gdevalps.c b/contrib/japanese/gdevalps.c
 |  | ||||||
| index f29aeb1..d4de619 100644
 |  | ||||||
| --- a/contrib/japanese/gdevalps.c
 |  | ||||||
| +++ b/contrib/japanese/gdevalps.c
 |  | ||||||
| @@ -155,13 +155,20 @@ static const char end_md[] = {
 |  | ||||||
|  static int |  | ||||||
|  md_open(gx_device *pdev) |  | ||||||
|  { |  | ||||||
| -        static const float md_margins[4] =
 |  | ||||||
| -         {	MD_SIDE_MARGIN, MD_BOTTOM_MARGIN,
 |  | ||||||
| -                MD_SIDE_MARGIN, MD_TOP_MARGIN
 |  | ||||||
| -         };
 |  | ||||||
| -
 |  | ||||||
| -        gx_device_set_margins(pdev, md_margins, true);
 |  | ||||||
| -        return gdev_prn_open(pdev);
 |  | ||||||
| +  static const float md_margins[4] =
 |  | ||||||
| +    {
 |  | ||||||
| +        MD_SIDE_MARGIN, MD_BOTTOM_MARGIN,
 |  | ||||||
| +        MD_SIDE_MARGIN, MD_TOP_MARGIN
 |  | ||||||
| +    };
 |  | ||||||
| +
 |  | ||||||
| +    if (pdev->HWResolution[0] != 600)
 |  | ||||||
| +    {
 |  | ||||||
| +        emprintf(pdev->memory, "device must have an X resolution of 600dpi\n");
 |  | ||||||
| +        return_error(gs_error_rangecheck);
 |  | ||||||
| +    }
 |  | ||||||
| +
 |  | ||||||
| +    gx_device_set_margins(pdev, md_margins, true);
 |  | ||||||
| +    return gdev_prn_open(pdev);
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  /* MD5000 monochrome mode entrance. */ |  | ||||||
| @ -1,75 +0,0 @@ | |||||||
| From f54414c8b15b2c27d1dcadd92cfe84f6d15f18dc Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Julian Smith <jules@op59.net> |  | ||||||
| Date: Thu, 31 Oct 2019 13:12:47 +0000 |  | ||||||
| Subject: [PATCH] Bug 701808: return error from okiibm_print_page1() if x_dpi |  | ||||||
|  too high. |  | ||||||
| 
 |  | ||||||
| Avoids asan error in: |  | ||||||
|     ./sanbin/gs -dBATCH -dNOPAUSE -dSAFER -r599 -sOutputFile=tmp -sDEVICE=okiibm ../bug-701808.pdf |  | ||||||
| ---
 |  | ||||||
|  devices/gdevokii.c | 46 ++++++++++++++++++++++++++++++++-------------- |  | ||||||
|  1 file changed, 32 insertions(+), 14 deletions(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/devices/gdevokii.c b/devices/gdevokii.c
 |  | ||||||
| index d8929a22c..97a1c3b88 100644
 |  | ||||||
| --- a/devices/gdevokii.c
 |  | ||||||
| +++ b/devices/gdevokii.c
 |  | ||||||
| @@ -96,23 +96,41 @@ okiibm_print_page1(gx_device_printer *pdev, gp_file *prn_stream, int y_9pin_high
 |  | ||||||
|          -1, 0 /*60*/, 1 /*120*/, -1, 3 /*240*/ |  | ||||||
|          }; |  | ||||||
|   |  | ||||||
| -        int in_y_mult = (y_9pin_high ? 2 : 1);
 |  | ||||||
| -        int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
 |  | ||||||
| -        /* Note that in_size is a multiple of 8. */
 |  | ||||||
| -        int in_size = line_size * (8 * in_y_mult);
 |  | ||||||
| -        byte *buf1 = (byte *)gs_malloc(pdev->memory, in_size, 1, "okiibm_print_page(buf1)");
 |  | ||||||
| -        byte *buf2 = (byte *)gs_malloc(pdev->memory, in_size, 1, "okiibm_print_page(buf2)");
 |  | ||||||
| -        byte *in = buf1;
 |  | ||||||
| -        byte *out = buf2;
 |  | ||||||
| -        int out_y_mult = 1;
 |  | ||||||
| -        int x_dpi = pdev->x_pixels_per_inch;
 |  | ||||||
| -        char start_graphics = graphics_modes_9[x_dpi / 60];
 |  | ||||||
| -        int first_pass = (start_graphics == 3 ? 1 : 0);
 |  | ||||||
| -        int last_pass = first_pass * 2;
 |  | ||||||
| -        int y_passes = (y_9pin_high ? 2 : 1);
 |  | ||||||
| +        int in_y_mult;
 |  | ||||||
| +        int line_size;
 |  | ||||||
| +        int in_size;
 |  | ||||||
| +        byte *buf1;
 |  | ||||||
| +        byte *buf2;
 |  | ||||||
| +        byte *in;
 |  | ||||||
| +        byte *out;
 |  | ||||||
| +        int out_y_mult;
 |  | ||||||
| +        int x_dpi;
 |  | ||||||
| +        char start_graphics;
 |  | ||||||
| +        int first_pass;
 |  | ||||||
| +        int last_pass;
 |  | ||||||
| +        int y_passes;
 |  | ||||||
|          int skip = 0, lnum = 0, pass, ypass; |  | ||||||
|          int y_step = 0; |  | ||||||
|   |  | ||||||
| +        x_dpi = pdev->x_pixels_per_inch;
 |  | ||||||
| +        if (x_dpi / 60 >= sizeof(graphics_modes_9)/sizeof(graphics_modes_9[0])) {
 |  | ||||||
| +            return_error(gs_error_rangecheck);
 |  | ||||||
| +        }
 |  | ||||||
| +        in_y_mult = (y_9pin_high ? 2 : 1);
 |  | ||||||
| +        line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
 |  | ||||||
| +        /* Note that in_size is a multiple of 8. */
 |  | ||||||
| +        in_size = line_size * (8 * in_y_mult);
 |  | ||||||
| +        buf1 = (byte *)gs_malloc(pdev->memory, in_size, 1, "okiibm_print_page(buf1)");
 |  | ||||||
| +        buf2 = (byte *)gs_malloc(pdev->memory, in_size, 1, "okiibm_print_page(buf2)");
 |  | ||||||
| +        in = buf1;
 |  | ||||||
| +        out = buf2;
 |  | ||||||
| +        out_y_mult = 1;
 |  | ||||||
| +        start_graphics = graphics_modes_9[x_dpi / 60];
 |  | ||||||
| +        first_pass = (start_graphics == 3 ? 1 : 0);
 |  | ||||||
| +        last_pass = first_pass * 2;
 |  | ||||||
| +        y_passes = (y_9pin_high ? 2 : 1);
 |  | ||||||
| +        y_step = 0;
 |  | ||||||
| +
 |  | ||||||
|          /* Check allocations */ |  | ||||||
|          if ( buf1 == 0 || buf2 == 0 ) |  | ||||||
|          {	if ( buf1 ) |  | ||||||
| -- 
 |  | ||||||
| 2.35.3 |  | ||||||
| 
 |  | ||||||
| @ -1,228 +0,0 @@ | |||||||
| diff --git a/devices/gdev3852.c b/devices/gdev3852.c
 |  | ||||||
| index 2bee8ec..9d99068 100644
 |  | ||||||
| --- a/devices/gdev3852.c
 |  | ||||||
| +++ b/devices/gdev3852.c
 |  | ||||||
| @@ -62,116 +62,117 @@ jetp3852_print_page(gx_device_printer *pdev, FILE *prn_stream)
 |  | ||||||
|  #define DATA_SIZE (LINE_SIZE * 8) |  | ||||||
|   |  | ||||||
|     unsigned int cnt_2prn; |  | ||||||
| -        unsigned int count,tempcnt;
 |  | ||||||
| -        unsigned char vtp,cntc1,cntc2;
 |  | ||||||
| -        int line_size_color_plane;
 |  | ||||||
| -
 |  | ||||||
| -        byte data[DATA_SIZE];
 |  | ||||||
| -        byte plane_data[LINE_SIZE * 3];
 |  | ||||||
| -
 |  | ||||||
| -        /* Set initial condition for printer */
 |  | ||||||
| -        fputs("\033@",prn_stream);
 |  | ||||||
| -
 |  | ||||||
| -        /* Send each scan line in turn */
 |  | ||||||
| -           {	int lnum;
 |  | ||||||
| -                int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
 |  | ||||||
| -                int num_blank_lines = 0;
 |  | ||||||
| -
 |  | ||||||
| -                if (line_size > DATA_SIZE) {
 |  | ||||||
| -                  emprintf2(pdev->memory, "invalid resolution and/or width gives line_size = %d, max. is %d\n",
 |  | ||||||
| -                            line_size, DATA_SIZE);
 |  | ||||||
| -                  return_error(gs_error_rangecheck);
 |  | ||||||
| -               }
 |  | ||||||
| -                
 |  | ||||||
| -                for ( lnum = 0; lnum < pdev->height; lnum++ )
 |  | ||||||
| -                   {	byte *end_data = data + line_size;
 |  | ||||||
| -                        gdev_prn_copy_scan_lines(pdev, lnum,
 |  | ||||||
| -                                                 (byte *)data, line_size);
 |  | ||||||
| -                        /* Remove trailing 0s. */
 |  | ||||||
| -                        while ( end_data > data && end_data[-1] == 0 )
 |  | ||||||
| -                                end_data--;
 |  | ||||||
| -                        if ( end_data == data )
 |  | ||||||
| -                           {	/* Blank line */
 |  | ||||||
| -                                num_blank_lines++;
 |  | ||||||
| -                           }
 |  | ||||||
| -                        else
 |  | ||||||
| -                           {	int i;
 |  | ||||||
| -                                byte *odp;
 |  | ||||||
| -                                byte *row;
 |  | ||||||
| -
 |  | ||||||
| -                                /* Pad with 0s to fill out the last */
 |  | ||||||
| -                                /* block of 8 bytes. */
 |  | ||||||
| -                                memset(end_data, 0, 7);
 |  | ||||||
| -
 |  | ||||||
| -                                /* Transpose the data to get pixel planes. */
 |  | ||||||
| -                                for ( i = 0, odp = plane_data; i < DATA_SIZE;
 |  | ||||||
| -                                      i += 8, odp++
 |  | ||||||
| -                                    )
 |  | ||||||
| -                                 { /* The following is for 16-bit machines */
 |  | ||||||
| +   unsigned int count,tempcnt;
 |  | ||||||
| +   unsigned char vtp,cntc1,cntc2;
 |  | ||||||
| +   int line_size_color_plane;
 |  | ||||||
| +
 |  | ||||||
| +   byte data[DATA_SIZE];
 |  | ||||||
| +   byte plane_data[LINE_SIZE * 3];
 |  | ||||||
| +
 |  | ||||||
| +   /* Initialise data to zeros, otherwise later on, uninitialised bytes in
 |  | ||||||
| +   dp[] can be greater than 7, which breaks spr8[dp[]]. */
 |  | ||||||
| +   memset(data, 0x00, DATA_SIZE);
 |  | ||||||
| +
 |  | ||||||
| +
 |  | ||||||
| +   /* Set initial condition for printer */
 |  | ||||||
| +   fputs("\033@",prn_stream);
 |  | ||||||
| +
 |  | ||||||
| +   /* Send each scan line in turn */
 |  | ||||||
| +   {	int lnum;
 |  | ||||||
| +        int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
 |  | ||||||
| +        int num_blank_lines = 0;
 |  | ||||||
| +
 |  | ||||||
| +        if (line_size > DATA_SIZE) {
 |  | ||||||
| +          emprintf2(pdev->memory, "invalid resolution and/or width gives line_size = %d, max. is %d\n",
 |  | ||||||
| +                    line_size, DATA_SIZE);
 |  | ||||||
| +          return_error(gs_error_rangecheck);
 |  | ||||||
| +       }
 |  | ||||||
| +
 |  | ||||||
| +        for ( lnum = 0; lnum < pdev->height; lnum++ )
 |  | ||||||
| +           {	byte *end_data = data + line_size;
 |  | ||||||
| +                gdev_prn_copy_scan_lines(pdev, lnum,
 |  | ||||||
| +                                         (byte *)data, line_size);
 |  | ||||||
| +                /* Remove trailing 0s. */
 |  | ||||||
| +                while ( end_data > data && end_data[-1] == 0 )
 |  | ||||||
| +                        end_data--;
 |  | ||||||
| +                if ( end_data == data )
 |  | ||||||
| +                   {	/* Blank line */
 |  | ||||||
| +                        num_blank_lines++;
 |  | ||||||
| +                   }
 |  | ||||||
| +                else
 |  | ||||||
| +                   {	int i;
 |  | ||||||
| +                        byte *odp;
 |  | ||||||
| +                        byte *row;
 |  | ||||||
| +
 |  | ||||||
| +                        /* Transpose the data to get pixel planes. */
 |  | ||||||
| +                        for ( i = 0, odp = plane_data; i < DATA_SIZE;
 |  | ||||||
| +                              i += 8, odp++
 |  | ||||||
| +                            )
 |  | ||||||
| +                        { /* The following is for 16-bit machines */
 |  | ||||||
|  #define spread3(c)\ |  | ||||||
|   { 0, c, c*0x100, c*0x101, c*0x10000L, c*0x10001L, c*0x10100L, c*0x10101L } |  | ||||||
| -                                   static ulong spr40[8] = spread3(0x40);
 |  | ||||||
| -                                   static ulong spr8[8] = spread3(8);
 |  | ||||||
| -                                   static ulong spr2[8] = spread3(2);
 |  | ||||||
| -                                   register byte *dp = data + i;
 |  | ||||||
| -                                   register ulong pword =
 |  | ||||||
| -                                     (spr40[dp[0]] << 1) +
 |  | ||||||
| -                                     (spr40[dp[1]]) +
 |  | ||||||
| -                                     (spr40[dp[2]] >> 1) +
 |  | ||||||
| -                                     (spr8[dp[3]] << 1) +
 |  | ||||||
| -                                     (spr8[dp[4]]) +
 |  | ||||||
| -                                     (spr8[dp[5]] >> 1) +
 |  | ||||||
| -                                     (spr2[dp[6]]) +
 |  | ||||||
| -                                     (spr2[dp[7]] >> 1);
 |  | ||||||
| -                                   odp[0] = (byte)(pword >> 16);
 |  | ||||||
| -                                   odp[LINE_SIZE] = (byte)(pword >> 8);
 |  | ||||||
| -                                   odp[LINE_SIZE*2] = (byte)(pword);
 |  | ||||||
| -                                 }
 |  | ||||||
| -                                /* Skip blank lines if any */
 |  | ||||||
| -                                if ( num_blank_lines > 0 )
 |  | ||||||
| -                                   {
 |  | ||||||
| -                                        /* Do "dot skips" */
 |  | ||||||
| -                                        while(num_blank_lines > 255)
 |  | ||||||
| -                                          {
 |  | ||||||
| -                                          fputs("\033e\377",prn_stream);
 |  | ||||||
| -                                          num_blank_lines -= 255;
 |  | ||||||
| -                                          }
 |  | ||||||
| -                                        vtp = num_blank_lines;
 |  | ||||||
| -                                        fprintf(prn_stream,"\033e%c",vtp);
 |  | ||||||
| -                                        num_blank_lines = 0;
 |  | ||||||
| -                                   }
 |  | ||||||
| -
 |  | ||||||
| -                                /* Transfer raster graphics in the order R, G, B. */
 |  | ||||||
| -                                /* Apparently it is stored in B, G, R */
 |  | ||||||
| -                                /* Calculate the amount of data to send by what */
 |  | ||||||
| -                                /* Ghostscript tells us the scan line_size in (bytes) */
 |  | ||||||
| -
 |  | ||||||
| -                                count = line_size / 3;
 |  | ||||||
| -                                line_size_color_plane = count / 3;
 |  | ||||||
| -                           cnt_2prn = line_size_color_plane * 3 + 5;
 |  | ||||||
| -                                tempcnt = cnt_2prn;
 |  | ||||||
| -                                cntc1 = (tempcnt & 0xFF00) >> 8;
 |  | ||||||
| -                                cntc2 = (tempcnt & 0x00FF);
 |  | ||||||
| -                                fprintf(prn_stream, "\033[O%c%c\200\037",cntc2,cntc1);
 |  | ||||||
| -                                fputc('\000',prn_stream);
 |  | ||||||
| +                           static ulong spr40[8] = spread3(0x40);
 |  | ||||||
| +                           static ulong spr8[8] = spread3(8);
 |  | ||||||
| +                           static ulong spr2[8] = spread3(2);
 |  | ||||||
| +                           register byte *dp = data + i;
 |  | ||||||
| +                           register ulong pword =
 |  | ||||||
| +                             (spr40[dp[0]] << 1) +
 |  | ||||||
| +                             (spr40[dp[1]]) +
 |  | ||||||
| +                             (spr40[dp[2]] >> 1) +
 |  | ||||||
| +                             (spr8[dp[3]] << 1) +
 |  | ||||||
| +                             (spr8[dp[4]]) +
 |  | ||||||
| +                             (spr8[dp[5]] >> 1) +
 |  | ||||||
| +                             (spr2[dp[6]]) +
 |  | ||||||
| +                             (spr2[dp[7]] >> 1);
 |  | ||||||
| +                           odp[0] = (byte)(pword >> 16);
 |  | ||||||
| +                           odp[LINE_SIZE] = (byte)(pword >> 8);
 |  | ||||||
| +                           odp[LINE_SIZE*2] = (byte)(pword);
 |  | ||||||
| +                        }
 |  | ||||||
| +                        /* Skip blank lines if any */
 |  | ||||||
| +                        if ( num_blank_lines > 0 )
 |  | ||||||
| +                           {
 |  | ||||||
| +                                /* Do "dot skips" */
 |  | ||||||
| +                                while(num_blank_lines > 255)
 |  | ||||||
| +                                  {
 |  | ||||||
| +                                  fputs("\033e\377",prn_stream);
 |  | ||||||
| +                                  num_blank_lines -= 255;
 |  | ||||||
| +                                  }
 |  | ||||||
| +                                vtp = num_blank_lines;
 |  | ||||||
| +                                fprintf(prn_stream,"\033e%c",vtp);
 |  | ||||||
| +                                num_blank_lines = 0;
 |  | ||||||
| +                           }
 |  | ||||||
| +
 |  | ||||||
| +                        /* Transfer raster graphics in the order R, G, B. */
 |  | ||||||
| +                        /* Apparently it is stored in B, G, R */
 |  | ||||||
| +                        /* Calculate the amount of data to send by what */
 |  | ||||||
| +                        /* Ghostscript tells us the scan line_size in (bytes) */
 |  | ||||||
| +
 |  | ||||||
| +                        count = line_size / 3;
 |  | ||||||
| +                        line_size_color_plane = count / 3;
 |  | ||||||
| +                        cnt_2prn = line_size_color_plane * 3 + 5;
 |  | ||||||
| +                        tempcnt = cnt_2prn;
 |  | ||||||
| +                        cntc1 = (tempcnt & 0xFF00) >> 8;
 |  | ||||||
| +                        cntc2 = (tempcnt & 0x00FF);
 |  | ||||||
| +                        fprintf(prn_stream, "\033[O%c%c\200\037",cntc2,cntc1);
 |  | ||||||
| +                        fputc('\000',prn_stream);
 |  | ||||||
|                          fputs("\124\124",prn_stream); |  | ||||||
|   |  | ||||||
| -                                for ( row = plane_data + LINE_SIZE * 2, i = 0;
 |  | ||||||
| -                                      i < 3; row -= LINE_SIZE, i++ )
 |  | ||||||
| -                                {	int jj;
 |  | ||||||
| -                                   byte ctemp;
 |  | ||||||
| -                                   odp = row;
 |  | ||||||
| -                                        /* Complement bytes */
 |  | ||||||
| -                                        for (jj=0; jj< line_size_color_plane; jj++)
 |  | ||||||
| -                                          { ctemp = *odp;
 |  | ||||||
| -                                            *odp++ = ~ctemp;
 |  | ||||||
| -                                                 }
 |  | ||||||
| -                                        fwrite(row, sizeof(byte),
 |  | ||||||
| -                                            line_size_color_plane, prn_stream);
 |  | ||||||
| -                                        }
 |  | ||||||
| -                           }
 |  | ||||||
| -                   }
 |  | ||||||
| -           }
 |  | ||||||
| +                        for ( row = plane_data + LINE_SIZE * 2, i = 0;
 |  | ||||||
| +                              i < 3; row -= LINE_SIZE, i++ )
 |  | ||||||
| +                        {  int jj;
 |  | ||||||
| +                           byte ctemp;
 |  | ||||||
| +                           odp = row;
 |  | ||||||
| +                              /* Complement bytes */
 |  | ||||||
| +                              for (jj=0; jj< line_size_color_plane; jj++)
 |  | ||||||
| +                              { ctemp = *odp;
 |  | ||||||
| +                                *odp++ = ~ctemp;
 |  | ||||||
| +                              }
 |  | ||||||
| +                           fwrite(row, sizeof(byte),
 |  | ||||||
| +                           line_size_color_plane, prn_stream);
 |  | ||||||
| +                        }
 |  | ||||||
| +                  }
 |  | ||||||
| +            }
 |  | ||||||
| +   }
 |  | ||||||
|   |  | ||||||
|          /* eject page */ |  | ||||||
|          fputs("\014", prn_stream); |  | ||||||
| @ -1,77 +0,0 @@ | |||||||
| diff --git a/base/gxicolor.c b/base/gxicolor.c
 |  | ||||||
| index 34cfaa4..585bd81 100644
 |  | ||||||
| --- a/base/gxicolor.c
 |  | ||||||
| +++ b/base/gxicolor.c
 |  | ||||||
| @@ -644,16 +644,16 @@ image_render_color_thresh(gx_image_enum *penum_orig, const byte *buffer, int dat
 |  | ||||||
|                                      *(devc_contone_gray+1) = *psrc_temp; |  | ||||||
|                              } |  | ||||||
|                          } else { |  | ||||||
| -                        /* Mono case, forward */
 |  | ||||||
| -                        psrc_temp = psrc_cm;
 |  | ||||||
| -                        for (k=0; k<src_size; k++) {
 |  | ||||||
| -                            dda_next(dda_ht);
 |  | ||||||
| -                            xn = fixed2int_var_rounded(dda_current(dda_ht));
 |  | ||||||
| -                            while (xr < xn) {
 |  | ||||||
| -                                *devc_contone_gray++ = *psrc_temp;
 |  | ||||||
| -                                xr++;
 |  | ||||||
| -                            }           /* at loop exit xn will be >= xr */
 |  | ||||||
| -                            psrc_temp++;
 |  | ||||||
| +                            /* Mono case, forward */
 |  | ||||||
| +                            psrc_temp = psrc_cm;
 |  | ||||||
| +                            for (k=0; k<src_size; k++) {
 |  | ||||||
| +                                dda_next(dda_ht);
 |  | ||||||
| +                                xn = fixed2int_var_rounded(dda_current(dda_ht));
 |  | ||||||
| +                                while (xr < xn) {
 |  | ||||||
| +                                    *devc_contone_gray++ = *psrc_temp;
 |  | ||||||
| +                                    xr++;
 |  | ||||||
| +                                }           /* at loop exit xn will be >= xr */
 |  | ||||||
| +                                psrc_temp++;
 |  | ||||||
|                              } |  | ||||||
|                          } |  | ||||||
|                      } else { |  | ||||||
| @@ -668,7 +668,7 @@ image_render_color_thresh(gx_image_enum *penum_orig, const byte *buffer, int dat
 |  | ||||||
|                                  xr--; |  | ||||||
|                              }           /* at loop exit xn will be >= xr */ |  | ||||||
|                              psrc_temp++; |  | ||||||
| -                            }
 |  | ||||||
| +                        }
 |  | ||||||
|                      } |  | ||||||
|                      break; |  | ||||||
|                  /* Monochrome landscape */ |  | ||||||
| @@ -811,10 +811,9 @@ image_render_color_thresh(gx_image_enum *penum_orig, const byte *buffer, int dat
 |  | ||||||
|                              dda_next(dda_ht); |  | ||||||
|                              xn = fixed2int_var_rounded(dda_current(dda_ht)); |  | ||||||
|                              while (xr > xn) { |  | ||||||
| -                                for (j = 0; j < spp_out; j++) {
 |  | ||||||
| +                                for (j = 0; j < spp_out; j++)
 |  | ||||||
|                                      *(devc_contone[j] + position) = (psrc_plane[j])[i]; |  | ||||||
| -                                    position -= LAND_BITS;
 |  | ||||||
| -                                }
 |  | ||||||
| +                                position -= LAND_BITS;
 |  | ||||||
|                                  xr--; |  | ||||||
|                              }           /* at loop exit xn will be <= xr */ |  | ||||||
|                              i++; |  | ||||||
| @@ -825,9 +824,8 @@ image_render_color_thresh(gx_image_enum *penum_orig, const byte *buffer, int dat
 |  | ||||||
|                             and 2x scaling which we will run into in 300 and |  | ||||||
|                             600dpi devices and content */ |  | ||||||
|                          /* Apply initial offset */ |  | ||||||
| -                        for (k = 0; k < spp_out; k++) {
 |  | ||||||
| +                        for (k = 0; k < spp_out; k++)
 |  | ||||||
|                              devc_contone[k] = devc_contone[k] + position; |  | ||||||
| -                        }
 |  | ||||||
|                          if (src_size == dest_height) { |  | ||||||
|                              for (k = 0; k < data_length; k++) { |  | ||||||
|                                  /* Is it better to unwind this?  We know it is 4 */ |  | ||||||
| @@ -853,10 +851,9 @@ image_render_color_thresh(gx_image_enum *penum_orig, const byte *buffer, int dat
 |  | ||||||
|                                  dda_next(dda_ht); |  | ||||||
|                                  xn = fixed2int_var_rounded(dda_current(dda_ht)); |  | ||||||
|                                  while (xr > xn) { |  | ||||||
| -                                    for (j = 0; j < spp_out; j++) {
 |  | ||||||
| +                                    for (j = 0; j < spp_out; j++)
 |  | ||||||
|                                          *(devc_contone[j] + position) = (psrc_plane[j])[i]; |  | ||||||
| -                                        position -= LAND_BITS;
 |  | ||||||
| -                                    }
 |  | ||||||
| +                                    position -= LAND_BITS;
 |  | ||||||
|                                      xr--; |  | ||||||
|                                  }           /* at loop exit xn will be <= xr */ |  | ||||||
|                                  i++; |  | ||||||
| @ -1,20 +0,0 @@ | |||||||
| diff --git a/devices/gdevtsep.c b/devices/gdevtsep.c
 |  | ||||||
| index 6a50a4a..471fcb5 100644
 |  | ||||||
| --- a/devices/gdevtsep.c
 |  | ||||||
| +++ b/devices/gdevtsep.c
 |  | ||||||
| @@ -2332,6 +2332,7 @@ tiffsep_print_page(gx_device_printer * pdev, FILE * file)
 |  | ||||||
|                  "\nUse of the %%d format is required to output more than one page to tiffsep.\n" |  | ||||||
|                  "See doc/Devices.htm#TIFF for details.\n\n"); |  | ||||||
|         code = gs_note_error(gs_error_ioerror); |  | ||||||
| +       goto done;
 |  | ||||||
|      } |  | ||||||
|      /* Write the page directory for the CMYK equivalent file. */ |  | ||||||
|      if (!tfdev->comp_file) { |  | ||||||
| @@ -2685,6 +2686,7 @@ tiffsep1_print_page(gx_device_printer * pdev, FILE * file)
 |  | ||||||
|                  "\nUse of the %%d format is required to output more than one page to tiffsep1.\n" |  | ||||||
|                  "See doc/Devices.htm#TIFF for details.\n\n"); |  | ||||||
|         code = gs_note_error(gs_error_ioerror); |  | ||||||
| +       goto done;
 |  | ||||||
|      } |  | ||||||
|      /* If the output file is on disk and the name contains a page #, */ |  | ||||||
|      /* then delete the previous file. */ |  | ||||||
| @ -1,205 +0,0 @@ | |||||||
| diff --git a/devices/vector/gdevtxtw.c b/devices/vector/gdevtxtw.c
 |  | ||||||
| index b958027..7f02608 100644
 |  | ||||||
| --- a/devices/vector/gdevtxtw.c
 |  | ||||||
| +++ b/devices/vector/gdevtxtw.c
 |  | ||||||
| @@ -1693,97 +1693,100 @@ static int get_unicode(textw_text_enum_t *penum, gs_font *font, gs_glyph glyph,
 |  | ||||||
|   |  | ||||||
|      length = font->procs.decode_glyph((gs_font *)font, glyph, ch, NULL, 0); |  | ||||||
|      if (length == 0) { |  | ||||||
| -        code = font->procs.glyph_name(font, glyph, &gnstr);
 |  | ||||||
| -        if (code >= 0 && gnstr.size == 7) {
 |  | ||||||
| -            if (!memcmp(gnstr.data, "uni", 3)) {
 |  | ||||||
| -                static const char *hexdigits = "0123456789ABCDEF";
 |  | ||||||
| -                char *d0 = strchr(hexdigits, gnstr.data[3]);
 |  | ||||||
| -                char *d1 = strchr(hexdigits, gnstr.data[4]);
 |  | ||||||
| -                char *d2 = strchr(hexdigits, gnstr.data[5]);
 |  | ||||||
| -                char *d3 = strchr(hexdigits, gnstr.data[6]);
 |  | ||||||
| -
 |  | ||||||
| -                if (d0 != NULL && d1 != NULL && d2 != NULL && d3 != NULL) {
 |  | ||||||
| -                    *Buffer++ = ((d0 - hexdigits) << 12) + ((d1 - hexdigits) << 8) + ((d2 - hexdigits) << 4) + (d3 - hexdigits);
 |  | ||||||
| -                    return 1;
 |  | ||||||
| -                }
 |  | ||||||
| -            }
 |  | ||||||
| -        }
 |  | ||||||
| -        if (length == 0) {
 |  | ||||||
| -            single_glyph_list_t *sentry = (single_glyph_list_t *)&SingleGlyphList;
 |  | ||||||
| -            double_glyph_list_t *dentry = (double_glyph_list_t *)&DoubleGlyphList;
 |  | ||||||
| -            treble_glyph_list_t *tentry = (treble_glyph_list_t *)&TrebleGlyphList;
 |  | ||||||
| -            quad_glyph_list_t *qentry = (quad_glyph_list_t *)&QuadGlyphList;
 |  | ||||||
| -
 |  | ||||||
| -            /* Search glyph to single Unicode value table */
 |  | ||||||
| -            while (sentry->Glyph != 0) {
 |  | ||||||
| -                if (sentry->Glyph[0] < gnstr.data[0]) {
 |  | ||||||
| -                    sentry++;
 |  | ||||||
| -                    continue;
 |  | ||||||
| -                }
 |  | ||||||
| -                if (sentry->Glyph[0] > gnstr.data[0]){
 |  | ||||||
| -                    break;
 |  | ||||||
| -                }
 |  | ||||||
| -                if (strlen(sentry->Glyph) == gnstr.size) {
 |  | ||||||
| -                    if(memcmp(gnstr.data, sentry->Glyph, gnstr.size) == 0) {
 |  | ||||||
| -                        *Buffer = sentry->Unicode;
 |  | ||||||
| +        if (glyph != GS_NO_GLYPH) {
 |  | ||||||
| +            code = font->procs.glyph_name(font, glyph, &gnstr);
 |  | ||||||
| +            if (code >= 0 && gnstr.size == 7) {
 |  | ||||||
| +                if (!memcmp(gnstr.data, "uni", 3)) {
 |  | ||||||
| +                    static const char *hexdigits = "0123456789ABCDEF";
 |  | ||||||
| +                    char *d0 = strchr(hexdigits, gnstr.data[3]);
 |  | ||||||
| +                    char *d1 = strchr(hexdigits, gnstr.data[4]);
 |  | ||||||
| +                    char *d2 = strchr(hexdigits, gnstr.data[5]);
 |  | ||||||
| +                    char *d3 = strchr(hexdigits, gnstr.data[6]);
 |  | ||||||
| +
 |  | ||||||
| +                    if (d0 != NULL && d1 != NULL && d2 != NULL && d3 != NULL) {
 |  | ||||||
| +                        *Buffer++ = ((d0 - hexdigits) << 12) + ((d1 - hexdigits) << 8) + ((d2 - hexdigits) << 4) + (d3 - hexdigits);
 |  | ||||||
|                          return 1; |  | ||||||
|                      } |  | ||||||
|                  } |  | ||||||
| -                sentry++;
 |  | ||||||
|              } |  | ||||||
|   |  | ||||||
| -            /* Search glyph to double Unicode value table */
 |  | ||||||
| -            while (dentry->Glyph != 0) {
 |  | ||||||
| -                if (dentry->Glyph[0] < gnstr.data[0]) {
 |  | ||||||
| -                    dentry++;
 |  | ||||||
| -                    continue;
 |  | ||||||
| -                }
 |  | ||||||
| -                if (dentry->Glyph[0] > gnstr.data[0]){
 |  | ||||||
| -                    break;
 |  | ||||||
| -                }
 |  | ||||||
| -                if (strlen(dentry->Glyph) == gnstr.size) {
 |  | ||||||
| -                    if(memcmp(gnstr.data, dentry->Glyph, gnstr.size) == 0) {
 |  | ||||||
| -                        memcpy(Buffer, dentry->Unicode, 2);
 |  | ||||||
| -                        return 2;
 |  | ||||||
| +            if (length == 0) {
 |  | ||||||
| +                single_glyph_list_t *sentry = (single_glyph_list_t *)&SingleGlyphList;
 |  | ||||||
| +                double_glyph_list_t *dentry = (double_glyph_list_t *)&DoubleGlyphList;
 |  | ||||||
| +                treble_glyph_list_t *tentry = (treble_glyph_list_t *)&TrebleGlyphList;
 |  | ||||||
| +                quad_glyph_list_t *qentry = (quad_glyph_list_t *)&QuadGlyphList;
 |  | ||||||
| +
 |  | ||||||
| +                /* Search glyph to single Unicode value table */
 |  | ||||||
| +                while (sentry->Glyph != 0) {
 |  | ||||||
| +                    if (sentry->Glyph[0] < gnstr.data[0]) {
 |  | ||||||
| +                        sentry++;
 |  | ||||||
| +                        continue;
 |  | ||||||
| +                    }
 |  | ||||||
| +                    if (sentry->Glyph[0] > gnstr.data[0]){
 |  | ||||||
| +                        break;
 |  | ||||||
| +                    }
 |  | ||||||
| +                    if (strlen(sentry->Glyph) == gnstr.size) {
 |  | ||||||
| +                        if(memcmp(gnstr.data, sentry->Glyph, gnstr.size) == 0) {
 |  | ||||||
| +                            *Buffer = sentry->Unicode;
 |  | ||||||
| +                            return 1;
 |  | ||||||
| +                        }
 |  | ||||||
|                      } |  | ||||||
| +                    sentry++;
 |  | ||||||
|                  } |  | ||||||
| -                dentry++;
 |  | ||||||
| -            }
 |  | ||||||
|   |  | ||||||
| -            /* Search glyph to triple Unicode value table */
 |  | ||||||
| -            while (tentry->Glyph != 0) {
 |  | ||||||
| -                if (tentry->Glyph[0] < gnstr.data[0]) {
 |  | ||||||
| -                    tentry++;
 |  | ||||||
| -                    continue;
 |  | ||||||
| -                }
 |  | ||||||
| -                if (tentry->Glyph[0] > gnstr.data[0]){
 |  | ||||||
| -                    break;
 |  | ||||||
| -                }
 |  | ||||||
| -                if (strlen(tentry->Glyph) == gnstr.size) {
 |  | ||||||
| -                    if(memcmp(gnstr.data, tentry->Glyph, gnstr.size) == 0) {
 |  | ||||||
| -                        memcpy(Buffer, tentry->Unicode, 3);
 |  | ||||||
| -                        return 3;
 |  | ||||||
| +                /* Search glyph to double Unicode value table */
 |  | ||||||
| +                while (dentry->Glyph != 0) {
 |  | ||||||
| +                    if (dentry->Glyph[0] < gnstr.data[0]) {
 |  | ||||||
| +                        dentry++;
 |  | ||||||
| +                        continue;
 |  | ||||||
|                      } |  | ||||||
| +                    if (dentry->Glyph[0] > gnstr.data[0]){
 |  | ||||||
| +                        break;
 |  | ||||||
| +                    }
 |  | ||||||
| +                    if (strlen(dentry->Glyph) == gnstr.size) {
 |  | ||||||
| +                        if(memcmp(gnstr.data, dentry->Glyph, gnstr.size) == 0) {
 |  | ||||||
| +                            memcpy(Buffer, dentry->Unicode, 2);
 |  | ||||||
| +                            return 2;
 |  | ||||||
| +                        }
 |  | ||||||
| +                    }
 |  | ||||||
| +                    dentry++;
 |  | ||||||
|                  } |  | ||||||
| -                tentry++;
 |  | ||||||
| -            }
 |  | ||||||
|   |  | ||||||
| -            /* Search glyph to quadruple Unicode value table */
 |  | ||||||
| -            while (qentry->Glyph != 0) {
 |  | ||||||
| -                if (qentry->Glyph[0] < gnstr.data[0]) {
 |  | ||||||
| -                    qentry++;
 |  | ||||||
| -                    continue;
 |  | ||||||
| -                }
 |  | ||||||
| -                if (qentry->Glyph[0] > gnstr.data[0]){
 |  | ||||||
| -                    break;
 |  | ||||||
| +                /* Search glyph to triple Unicode value table */
 |  | ||||||
| +                while (tentry->Glyph != 0) {
 |  | ||||||
| +                    if (tentry->Glyph[0] < gnstr.data[0]) {
 |  | ||||||
| +                        tentry++;
 |  | ||||||
| +                        continue;
 |  | ||||||
| +                    }
 |  | ||||||
| +                    if (tentry->Glyph[0] > gnstr.data[0]){
 |  | ||||||
| +                        break;
 |  | ||||||
| +                    }
 |  | ||||||
| +                    if (strlen(tentry->Glyph) == gnstr.size) {
 |  | ||||||
| +                        if(memcmp(gnstr.data, tentry->Glyph, gnstr.size) == 0) {
 |  | ||||||
| +                            memcpy(Buffer, tentry->Unicode, 3);
 |  | ||||||
| +                            return 3;
 |  | ||||||
| +                        }
 |  | ||||||
| +                    }
 |  | ||||||
| +                    tentry++;
 |  | ||||||
|                  } |  | ||||||
| -                if (strlen(qentry->Glyph) == gnstr.size) {
 |  | ||||||
| -                    if(memcmp(gnstr.data, qentry->Glyph, gnstr.size) == 0) {
 |  | ||||||
| -                        memcpy(Buffer, qentry->Unicode, 4);
 |  | ||||||
| -                        return 4;
 |  | ||||||
| +
 |  | ||||||
| +                /* Search glyph to quadruple Unicode value table */
 |  | ||||||
| +                while (qentry->Glyph != 0) {
 |  | ||||||
| +                    if (qentry->Glyph[0] < gnstr.data[0]) {
 |  | ||||||
| +                        qentry++;
 |  | ||||||
| +                        continue;
 |  | ||||||
| +                    }
 |  | ||||||
| +                    if (qentry->Glyph[0] > gnstr.data[0]){
 |  | ||||||
| +                        break;
 |  | ||||||
|                      } |  | ||||||
| +                    if (strlen(qentry->Glyph) == gnstr.size) {
 |  | ||||||
| +                        if(memcmp(gnstr.data, qentry->Glyph, gnstr.size) == 0) {
 |  | ||||||
| +                            memcpy(Buffer, qentry->Unicode, 4);
 |  | ||||||
| +                            return 4;
 |  | ||||||
| +                        }
 |  | ||||||
| +                    }
 |  | ||||||
| +                    qentry++;
 |  | ||||||
|                  } |  | ||||||
| -                qentry++;
 |  | ||||||
|              } |  | ||||||
|          } |  | ||||||
|          *Buffer = fallback; |  | ||||||
| @@ -1890,8 +1893,8 @@ txtwrite_process_cmap_text(gs_text_enum_t *pte)
 |  | ||||||
|                  pte->returned.total_width.x += dpt.x; |  | ||||||
|                  pte->returned.total_width.y += dpt.y; |  | ||||||
|   |  | ||||||
| -                penum->TextBufferIndex += get_unicode(penum, (gs_font *)pte->orig_font, glyph, chr, &penum->TextBuffer[penum->TextBufferIndex]);
 |  | ||||||
|                  penum->Widths[penum->TextBufferIndex] += dpt.x; |  | ||||||
| +                penum->TextBufferIndex += get_unicode(penum, (gs_font *)pte->orig_font, glyph, chr, &penum->TextBuffer[penum->TextBufferIndex]);
 |  | ||||||
|                  break; |  | ||||||
|              case 2:		/* end of string */ |  | ||||||
|                  return 0; |  | ||||||
| diff --git a/psi/zbfont.c b/psi/zbfont.c
 |  | ||||||
| index 262fea9..abc03aa 100644
 |  | ||||||
| --- a/psi/zbfont.c
 |  | ||||||
| +++ b/psi/zbfont.c
 |  | ||||||
| @@ -272,7 +272,7 @@ gs_font_map_glyph_to_unicode(gs_font *font, gs_glyph glyph, int ch, ushort *u, u
 |  | ||||||
|           * can't be a default value for FontInfo.GlyphNames2Unicode . |  | ||||||
|           */ |  | ||||||
|      } |  | ||||||
| -    if (glyph <= GS_MIN_CID_GLYPH) {
 |  | ||||||
| +    if (glyph <= GS_MIN_CID_GLYPH && glyph != GS_NO_GLYPH) {
 |  | ||||||
|          UnicodeDecoding = zfont_get_to_unicode_map(font->dir); |  | ||||||
|          if (UnicodeDecoding != NULL && r_type(UnicodeDecoding) == t_dictionary) |  | ||||||
|              return gs_font_map_glyph_by_dict(font->memory, UnicodeDecoding, glyph, u, length); |  | ||||||
| @ -1,57 +0,0 @@ | |||||||
| diff --git a/devices/gdevdm24.c b/devices/gdevdm24.c
 |  | ||||||
| index 4736f4f..2f610cd 100644
 |  | ||||||
| --- a/devices/gdevdm24.c
 |  | ||||||
| +++ b/devices/gdevdm24.c
 |  | ||||||
| @@ -51,21 +51,39 @@ static void dot24_improve_bitmap (byte *, int);
 |  | ||||||
|  static int |  | ||||||
|  dot24_print_page (gx_device_printer *pdev, FILE *prn_stream, char *init_string, int init_len) |  | ||||||
|  { |  | ||||||
| -  int xres = (int)pdev->x_pixels_per_inch;
 |  | ||||||
| -  int yres = (int)pdev->y_pixels_per_inch;
 |  | ||||||
| -  int x_high = (xres == 360);
 |  | ||||||
| -  int y_high = (yres == 360);
 |  | ||||||
| -  int bits_per_column = (y_high ? 48 : 24);
 |  | ||||||
| -  uint line_size = gdev_prn_raster (pdev);
 |  | ||||||
| -  uint in_size = line_size * bits_per_column;
 |  | ||||||
| -  byte *in = (byte *) gs_malloc (pdev->memory, in_size, 1, "dot24_print_page (in)");
 |  | ||||||
| -  uint out_size = ((pdev->width + 7) & -8) * 3;
 |  | ||||||
| -  byte *out = (byte *) gs_malloc (pdev->memory, out_size, 1, "dot24_print_page (out)");
 |  | ||||||
| -  int y_passes = (y_high ? 2 : 1);
 |  | ||||||
| -  int dots_per_space = xres / 10;	/* pica space = 1/10" */
 |  | ||||||
| -  int bytes_per_space = dots_per_space * 3;
 |  | ||||||
| +  int xres;
 |  | ||||||
| +  int yres;
 |  | ||||||
| +  int x_high;
 |  | ||||||
| +  int y_high;
 |  | ||||||
| +  int bits_per_column;
 |  | ||||||
| +  uint line_size;
 |  | ||||||
| +  uint in_size;
 |  | ||||||
| +  byte *in;
 |  | ||||||
| +  uint out_size;
 |  | ||||||
| +  byte *out;
 |  | ||||||
| +  int y_passes;
 |  | ||||||
| +  int dots_per_space;
 |  | ||||||
| +  int bytes_per_space;
 |  | ||||||
|    int skip = 0, lnum = 0, ypass; |  | ||||||
|   |  | ||||||
| +  xres = (int)pdev->x_pixels_per_inch;
 |  | ||||||
| +  yres = (int)pdev->y_pixels_per_inch;
 |  | ||||||
| +  x_high = (xres == 360);
 |  | ||||||
| +  y_high = (yres == 360);
 |  | ||||||
| +  dots_per_space = xres / 10;       /* pica space = 1/10" */
 |  | ||||||
| +  bytes_per_space = dots_per_space * 3;
 |  | ||||||
| +  if (bytes_per_space == 0) {
 |  | ||||||
| +    /* We divide by bytes_per_space later on. */
 |  | ||||||
| +    return_error(gs_error_rangecheck);
 |  | ||||||
| +  }
 |  | ||||||
| +  bits_per_column = (y_high ? 48 : 24);
 |  | ||||||
| +  line_size = gdev_prn_raster (pdev);
 |  | ||||||
| +  in_size = line_size * bits_per_column;
 |  | ||||||
| +  in = (byte *) gs_malloc (pdev->memory, in_size, 1, "dot24_print_page (in)");
 |  | ||||||
| +  out_size = ((pdev->width + 7) & -8) * 3;
 |  | ||||||
| +  out = (byte *) gs_malloc (pdev->memory, out_size, 1, "dot24_print_page (out)");
 |  | ||||||
| +  y_passes = (y_high ? 2 : 1);
 |  | ||||||
| +
 |  | ||||||
|    /* Check allocations */ |  | ||||||
|    if (in == 0 || out == 0) |  | ||||||
|      { |  | ||||||
| @ -1,12 +0,0 @@ | |||||||
| diff --git a/base/gdevprn.c b/base/gdevprn.c
 |  | ||||||
| index 459846a..84802d9 100644
 |  | ||||||
| --- a/base/gdevprn.c
 |  | ||||||
| +++ b/base/gdevprn.c
 |  | ||||||
| @@ -1331,6 +1331,7 @@ gdev_prn_open_printer_seekable(gx_device *pdev, bool binary_mode,
 |  | ||||||
|                && !IS_LIBCTX_STDERR(pdev->memory ,ppdev->file)) { |  | ||||||
|   |  | ||||||
|                  code = gx_device_close_output_file(pdev, ppdev->fname, ppdev->file); |  | ||||||
| +                ppdev->file = NULL;
 |  | ||||||
|                  if (code < 0) |  | ||||||
|                      return code; |  | ||||||
|              } |  | ||||||
| @ -1,154 +0,0 @@ | |||||||
| diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
 |  | ||||||
| index 55a785e..be77534 100644
 |  | ||||||
| --- a/Resource/Init/gs_init.ps
 |  | ||||||
| +++ b/Resource/Init/gs_init.ps
 |  | ||||||
| @@ -2607,4 +2607,6 @@ WRITESYSTEMDICT {
 |  | ||||||
|  % be 'true' in some cases. |  | ||||||
|  userdict /AGM_preserve_spots //false put |  | ||||||
|   |  | ||||||
| +.opvpactivatepathcontrol
 |  | ||||||
| +
 |  | ||||||
|  % The interpreter will run the initial procedure (start). |  | ||||||
| diff --git a/base/gslibctx.c b/base/gslibctx.c
 |  | ||||||
| index 1ed6093..14fb57c 100644
 |  | ||||||
| --- a/base/gslibctx.c
 |  | ||||||
| +++ b/base/gslibctx.c
 |  | ||||||
| @@ -435,3 +435,27 @@ gs_check_file_permission (gs_memory_t *mem, const char *fname, const int len, co
 |  | ||||||
|      } |  | ||||||
|      return code; |  | ||||||
|  } |  | ||||||
| +
 |  | ||||||
| +void
 |  | ||||||
| +opvp_activate_path_control(gs_memory_t *mem, int enable)
 |  | ||||||
| +{
 |  | ||||||
| +    gs_lib_ctx_core_t *core;
 |  | ||||||
| +
 |  | ||||||
| +    if (mem == NULL || mem->gs_lib_ctx == NULL ||
 |  | ||||||
| +        (core = mem->gs_lib_ctx->core) == NULL)
 |  | ||||||
| +        return;
 |  | ||||||
| +
 |  | ||||||
| +    core->opvp_path_control_active = enable;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +int
 |  | ||||||
| +opvp_is_path_control_active(const gs_memory_t *mem)
 |  | ||||||
| +{
 |  | ||||||
| +    gs_lib_ctx_core_t *core;
 |  | ||||||
| +
 |  | ||||||
| +    if (mem == NULL || mem->gs_lib_ctx == NULL ||
 |  | ||||||
| +        (core = mem->gs_lib_ctx->core) == NULL)
 |  | ||||||
| +        return 0;
 |  | ||||||
| +
 |  | ||||||
| +    return core->opvp_path_control_active;
 |  | ||||||
| +}
 |  | ||||||
| diff --git a/base/gslibctx.h b/base/gslibctx.h
 |  | ||||||
| index 1481cb5..e4b3924 100644
 |  | ||||||
| --- a/base/gslibctx.h
 |  | ||||||
| +++ b/base/gslibctx.h
 |  | ||||||
| @@ -61,6 +61,8 @@ typedef struct {
 |  | ||||||
|      bool CPSI_mode; |  | ||||||
|      int scanconverter; |  | ||||||
|      int act_on_uel; |  | ||||||
| +
 |  | ||||||
| +    int opvp_path_control_active;
 |  | ||||||
|  } gs_lib_ctx_core_t; |  | ||||||
|   |  | ||||||
|  typedef struct gs_lib_ctx_s |  | ||||||
| @@ -167,4 +169,10 @@ int sjpxd_create(gs_memory_t *mem);
 |  | ||||||
|   |  | ||||||
|  void sjpxd_destroy(gs_memory_t *mem); |  | ||||||
|   |  | ||||||
| +void
 |  | ||||||
| +opvp_activate_path_control(gs_memory_t *mem, int enable);
 |  | ||||||
| +
 |  | ||||||
| +int
 |  | ||||||
| +opvp_is_path_control_active(const gs_memory_t *mem);
 |  | ||||||
| +
 |  | ||||||
|  #endif /* GSLIBCTX_H */ |  | ||||||
| diff --git a/contrib/opvp/gdevopvp.c b/contrib/opvp/gdevopvp.c
 |  | ||||||
| index 9a6b45b..9693673 100644
 |  | ||||||
| --- a/contrib/opvp/gdevopvp.c
 |  | ||||||
| +++ b/contrib/opvp/gdevopvp.c
 |  | ||||||
| @@ -185,7 +185,7 @@ static  int opvp_copy_color(gx_device *, const byte *, int, int,
 |  | ||||||
|  static  int _get_params(gs_param_list *); |  | ||||||
|  static  int opvp_get_params(gx_device *, gs_param_list *); |  | ||||||
|  static  int oprp_get_params(gx_device *, gs_param_list *); |  | ||||||
| -static  int _put_params(gs_param_list *);
 |  | ||||||
| +static  int _put_params(gx_device *, gs_param_list *);
 |  | ||||||
|  static  int opvp_put_params(gx_device *, gs_param_list *); |  | ||||||
|  static  int oprp_put_params(gx_device *, gs_param_list *); |  | ||||||
|  static  int opvp_fill_path(gx_device *, const gs_gstate *, gx_path *, |  | ||||||
| @@ -3039,7 +3039,7 @@ _get_params(gs_param_list *plist)
 |  | ||||||
|      /* vector driver name */ |  | ||||||
|      pname = "Driver"; |  | ||||||
|      vdps.data = (byte *)vectorDriver; |  | ||||||
| -    vdps.size = (vectorDriver ? strlen(vectorDriver) + 1 : 0);
 |  | ||||||
| +    vdps.size = (vectorDriver ? strlen(vectorDriver) : 0);
 |  | ||||||
|      vdps.persistent = false; |  | ||||||
|      code = param_write_string(plist, pname, &vdps); |  | ||||||
|      if (code) ecode = code; |  | ||||||
| @@ -3176,7 +3176,7 @@ oprp_get_params(gx_device *dev, gs_param_list *plist)
 |  | ||||||
|   * put params |  | ||||||
|   */ |  | ||||||
|  static  int |  | ||||||
| -_put_params(gs_param_list *plist)
 |  | ||||||
| +_put_params(gx_device *dev, gs_param_list *plist)
 |  | ||||||
|  { |  | ||||||
|      int code; |  | ||||||
|      int ecode = 0; |  | ||||||
| @@ -3198,6 +3198,12 @@ _put_params(gs_param_list *plist)
 |  | ||||||
|      code = param_read_string(plist, pname, &vdps); |  | ||||||
|      switch (code) { |  | ||||||
|      case 0: |  | ||||||
| +        if (opvp_is_path_control_active(dev->memory)
 |  | ||||||
| +            && (!vectorDriver || strlen(vectorDriver) != vdps.size
 |  | ||||||
| +                || memcmp(vectorDriver, vdps.data, vdps.size) != 0)) {
 |  | ||||||
| +            param_signal_error(plist, pname, gs_error_invalidaccess);
 |  | ||||||
| +            return_error(gs_error_invalidaccess);
 |  | ||||||
| +        }
 |  | ||||||
|          buff = realloc(buff, vdps.size + 1); |  | ||||||
|          memcpy(buff, vdps.data, vdps.size); |  | ||||||
|          buff[vdps.size] = 0; |  | ||||||
| @@ -3399,7 +3405,7 @@ opvp_put_params(gx_device *dev, gs_param_list *plist)
 |  | ||||||
|      int code; |  | ||||||
|   |  | ||||||
|      /* put params */ |  | ||||||
| -    code = _put_params(plist);
 |  | ||||||
| +    code = _put_params(dev, plist);
 |  | ||||||
|      if (code) return code; |  | ||||||
|   |  | ||||||
|      /* put default params */ |  | ||||||
| @@ -3415,7 +3421,7 @@ oprp_put_params(gx_device *dev, gs_param_list *plist)
 |  | ||||||
|      int code; |  | ||||||
|   |  | ||||||
|      /* put params */ |  | ||||||
| -    code = _put_params(plist);
 |  | ||||||
| +    code = _put_params(dev, plist);
 |  | ||||||
|      if (code) return code; |  | ||||||
|   |  | ||||||
|      /* put default params */ |  | ||||||
| diff --git a/psi/zfile.c b/psi/zfile.c
 |  | ||||||
| index 271a1a0..05b8203 100644
 |  | ||||||
| --- a/psi/zfile.c
 |  | ||||||
| +++ b/psi/zfile.c
 |  | ||||||
| @@ -875,6 +875,12 @@ static int zgetfilename(i_ctx_t *i_ctx_p)
 |  | ||||||
|      return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static int zopvpactivatepathcontrol(i_ctx_t *i_ctx_p)
 |  | ||||||
| +{
 |  | ||||||
| +    opvp_activate_path_control(imemory, 1);
 |  | ||||||
| +    return 0;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
|  /* ------ Initialization procedure ------ */ |  | ||||||
|   |  | ||||||
|  const op_def zfile_op_defs[] = |  | ||||||
| @@ -893,6 +899,7 @@ const op_def zfile_op_defs[] =
 |  | ||||||
|      {"0%file_continue", file_continue}, |  | ||||||
|      {"0%execfile_finish", execfile_finish}, |  | ||||||
|      {"1.getfilename", zgetfilename}, |  | ||||||
| +    {"0.opvpactivatepathcontrol", zopvpactivatepathcontrol},
 |  | ||||||
|      op_def_end(0) |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| @ -27,17 +27,22 @@ | |||||||
| #       tarballs, and their release tags/branches do not use the dot in version | #       tarballs, and their release tags/branches do not use the dot in version | ||||||
| #       tag. This makes obtaining the current version harder, and might prevent | #       tag. This makes obtaining the current version harder, and might prevent | ||||||
| #       automatic builds of new releases... | #       automatic builds of new releases... | ||||||
| %global version_short   %(echo "%{version}" | tr -d '.') | %global version_short %%(echo "%{version}" | tr -d '.') | ||||||
| 
 | 
 | ||||||
| # Obtain the location of Google Droid fonts directory: | # Obtain the location of Google Droid fonts directory: | ||||||
| %global google_droid_fontpath %%(dirname $(fc-list : file | grep "DroidSansFallback")) | %global google_droid_fontpath %%(dirname $(fc-list : file | grep "DroidSansFallback")) | ||||||
| 
 | 
 | ||||||
|  | # Desired jbig2dec header files and library version | ||||||
|  | # Apparantly, ghostscript complains even about newer versions | ||||||
|  | # Please update if needed. | ||||||
|  | %global jbig2dec_version 0.19 | ||||||
|  | 
 | ||||||
| # ============================================================================= | # ============================================================================= | ||||||
| 
 | 
 | ||||||
| Name:             ghostscript | Name:             ghostscript | ||||||
| Summary:          Interpreter for PostScript language & PDF | Summary:          Interpreter for PostScript language & PDF | ||||||
| Version:          9.27 | Version:          9.54.0 | ||||||
| Release:          17%{?dist} | Release:          13%{?dist} | ||||||
| 
 | 
 | ||||||
| License:          AGPLv3+ | License:          AGPLv3+ | ||||||
| 
 | 
 | ||||||
| @ -45,7 +50,12 @@ URL:              https://ghostscript.com/ | |||||||
| Source:           https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs%{version_short}/ghostscript-%{version}.tar.xz | Source:           https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs%{version_short}/ghostscript-%{version}.tar.xz | ||||||
| 
 | 
 | ||||||
| Requires:         libgs%{?_isa} = %{version}-%{release} | Requires:         libgs%{?_isa} = %{version}-%{release} | ||||||
| Requires:         jbig2dec-libs >= 0.16 | Requires:         jbig2dec-libs = %{jbig2dec_version} | ||||||
|  | Requires:         %{name}-tools-fonts%{?_isa} = %{version}-%{release} | ||||||
|  | Requires:         %{name}-tools-printing%{?_isa} = %{version}-%{release} | ||||||
|  | 
 | ||||||
|  | Provides:         ghostscript-core = %{version}-%{release} | ||||||
|  | Obsoletes:        ghostscript-core < 9.53.3-6 | ||||||
| 
 | 
 | ||||||
| # Auxiliary build requirements: | # Auxiliary build requirements: | ||||||
| BuildRequires:    automake | BuildRequires:    automake | ||||||
| @ -63,9 +73,10 @@ BuildRequires:    cups-devel | |||||||
| BuildRequires:    dbus-devel | BuildRequires:    dbus-devel | ||||||
| BuildRequires:    fontconfig-devel | BuildRequires:    fontconfig-devel | ||||||
| BuildRequires:    freetype-devel | BuildRequires:    freetype-devel | ||||||
| BuildRequires:    jbig2dec-devel | BuildRequires:    jbig2dec-devel = %{jbig2dec_version} | ||||||
|  | BuildRequires:    jbig2dec-libs = %{jbig2dec_version} | ||||||
| BuildRequires:    lcms2-devel | BuildRequires:    lcms2-devel | ||||||
| BuildRequires:    libidn-devel | BuildRequires:    libidn2-devel | ||||||
| BuildRequires:    libijs-devel | BuildRequires:    libijs-devel | ||||||
| BuildRequires:    libjpeg-turbo-devel | BuildRequires:    libjpeg-turbo-devel | ||||||
| BuildRequires:    libpng-devel | BuildRequires:    libpng-devel | ||||||
| @ -77,6 +88,7 @@ BuildRequires:    zlib-devel | |||||||
| # Enabling the GUI possibilities of Ghostscript: | # Enabling the GUI possibilities of Ghostscript: | ||||||
| BuildRequires:    gtk3-devel | BuildRequires:    gtk3-devel | ||||||
| BuildRequires:    libXt-devel | BuildRequires:    libXt-devel | ||||||
|  | BuildRequires:    make | ||||||
| 
 | 
 | ||||||
| # ============================================================================= | # ============================================================================= | ||||||
| 
 | 
 | ||||||
| @ -88,78 +100,21 @@ BuildRequires:    libXt-devel | |||||||
| # Upstream patches -- official upstream patches released by upstream since the | # Upstream patches -- official upstream patches released by upstream since the | ||||||
| # ----------------    last rebase that are necessary for any reason: | # ----------------    last rebase that are necessary for any reason: | ||||||
| #Patch000: example000.patch | #Patch000: example000.patch | ||||||
| Patch001: ghostscript-cve-2019-10216.patch | Patch001: ghostscript-9.54.0-gdevtxtw-null-also-pointers.patch | ||||||
| Patch002: ghostscript-cve-2019-14811-14812-14813.patch | Patch002: ghostscript-9.54.0-include-pipe-handle-in-validation.patch | ||||||
| Patch003: ghostscript-cve-2019-14817.patch | #2032789 - coverity warnings fixes | ||||||
| # fixed in 9.51 | Patch003: ghostscript-9.54.0-covscan-fixes.patch | ||||||
| Patch004: ghostscript-cve-2020-16290.patch | #2049767 -  CVE-2021-45949 heap-based buffer overflow in sampled_data_finish | ||||||
| Patch005: ghostscript-cve-2020-16291.patch | Patch004: ghostscript-9.54.0-Fix-op-stack-management-in-sampled_data_c.patch | ||||||
| Patch006: ghostscript-cve-2020-16293.patch | Patch005: ghostscript-9.54.0-Deal-with-different-VM-modes-during-CIDFont-loading.patch | ||||||
| Patch007: ghostscript-cve-2020-16295.patch | Patch006: ghostscript-9.54.0-ESC-Page-driver-does-not-set-page-size-correctly.patch | ||||||
| Patch008: ghostscript-cve-2020-16299.patch | Patch007: ghostscript-9.54.0-pdfwrite-Substituted-TTF-CIDFont-CID-hand.patch | ||||||
| Patch009: ghostscript-cve-2020-16302.patch | Patch008: ghostscript-9.54.0-CVE-2023-28879.patch | ||||||
| Patch010: ghostscript-cve-2020-16304.patch | Patch009: ghostscript-9.54.0-CVE-2023-36664.patch | ||||||
| Patch011: ghostscript-cve-2020-16306.patch | Patch010: ghostscript-9.54.0-CVE-2023-38559.patch | ||||||
| Patch012: ghostscript-cve-2020-16307.patch |  | ||||||
| Patch013: ghostscript-cve-2020-16310.patch |  | ||||||
| Patch014: ghostscript-cve-2020-16301.patch |  | ||||||
| # 2097448 - printed text drifts to the right |  | ||||||
| Patch015: ghostscript-9.27-fix-use-of-HWMargins.patch |  | ||||||
| Patch016: ghostscript-9.27-Deal-with-different-VM-modes-during-CIDFont-loading.patch |  | ||||||
| Patch017: ghostscript-9.27-ESC-Page-driver-does-not-set-page-size-correctly.patch |  | ||||||
| Patch018: ghostscript-9.27-fix-bbox.patch |  | ||||||
| Patch019: ghostscript-9.27-pdfwrite-Substituted-TTF-CIDFont-CID-hand.patch |  | ||||||
| Patch020: ghostscript-9.27-CVE-2023-28879.patch |  | ||||||
| Patch021: ghostscript-9.27-CVE-2023-38559.patch |  | ||||||
| Patch022: ghostscript-9.27-CVE-2023-4042.patch |  | ||||||
| Patch023: ghostscript-9.27-avoid-divide-by-zero-in-devices.patch |  | ||||||
| # RHEL-38837 CVE-2024-33871 ghostscript: OPVP device arbitrary code execution via custom Driver library |  | ||||||
| # the patch is based on upstream code from 9.50, where a new -dSAFER implementation was introduced and |  | ||||||
| # -dSAFER was made default for any gs calls. To do not backport the whole new -dSAFER implementation, |  | ||||||
| # to do not collide with any future backports related with -dSAFER and to do not change the current default |  | ||||||
| # for ghostscript in RHEL 8, only part of the new -dSAFER implementation was backported, |  | ||||||
| # and the several functions, variables and macros prefix was changed to 'opvp' and used only |  | ||||||
| # for OPVP device, which results in changing the default only for this device and fixing the CVE. |  | ||||||
| # 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 |  | ||||||
| # RHEL-18396 CVE-2023-46751 ghostscript: dangling pointer in gdev_prn_open_printer_seekable() |  | ||||||
| # partially taken from https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=dcdbc595c13c9 |  | ||||||
| Patch028: gs-CVE-2023-46751.patch |  | ||||||
| # RHEL-67046 CVE-2024-46951 ghostscript: Arbitrary Code Execution in Artifex Ghostscript Pattern Color Space |  | ||||||
| # https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=f49812186baa7 |  | ||||||
| Patch029: 0001-PS-interpreter-check-the-type-of-the-Pattern-Impleme.patch |  | ||||||
| # RHEL-15067 CVE-2020-27792 ghostscript: heap buffer over write vulnerability in GhostScript's lp8000_print_page() in gdevlp8k.c |  | ||||||
| # https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=4f6bc662909a |  | ||||||
| Patch030: 0001-Bug-701844-fixed-output-buffer-size-worst-case-in-lp.patch |  | ||||||
| # RHEL-67051 CVE-2024-46954 ghostscript: Directory Traversal in Ghostscript via Overlong UTF-8 Encoding |  | ||||||
| # implementing decode_utf8() https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=4fcf527584da2053 |  | ||||||
| # CVE fix, updated for gp_wutf8() in 9.27 https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=282f691f5e57b6b |  | ||||||
| Patch031: 0001-Bug-705911-Fix-Ghostscript-s-encoding-decoding-of-UT.patch |  | ||||||
| Patch032: 0001-Bug-707788-Fix-decode_utf8-to-forbid-overlong-encodi.patch |  | ||||||
| # RHEL-67051 CVE-2024-46953 ghostscript: Path Traversal and Code Execution via Integer Overflow in Ghostscript |  | ||||||
| # https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=1f21a45df0fa3abec |  | ||||||
| Patch033: 0001-Bug-707793-Check-for-overflow-validating-format-stri.patch |  | ||||||
| # RHEL-67051 CVE-2024-46956 ghostscript: Out-of-Bounds Data Access in Ghostscript Leads to Arbitrary Code Execution |  | ||||||
| # https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=f4151f12db32cd3 |  | ||||||
| Patch034: 0001-PostScript-interpreter-fix-buffer-length-check.patch |  | ||||||
| # RHEL-88965 CVE-2025-27832 ghostscript: NPDL device: Compression buffer overflow |  | ||||||
| # https://github.com/ArtifexSoftware/ghostpdl/commit/57291c8463 |  | ||||||
| Patch035: 0001-Bug-708133-Avoid-integer-overflow-leading-to-buffer-.patch |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| # Downstream patches -- these should be always included when doing rebase: | # Downstream patches -- these should be always included when doing rebase: | ||||||
| # ------------------ | # ------------------ | ||||||
| Patch100: ghostscript-9.23-100-run-dvipdf-securely.patch |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| # Downstream patches for RHEL -- patches that we keep only in RHEL for various | # Downstream patches for RHEL -- patches that we keep only in RHEL for various | ||||||
| # ---------------------------    reasons, but are not enabled in Fedora: | # ---------------------------    reasons, but are not enabled in Fedora: | ||||||
| %if %{defined rhel} || %{defined centos} | %if %{defined rhel} || %{defined centos} | ||||||
| @ -291,10 +246,7 @@ This package provides detailed documentation files for Ghostscript software. | |||||||
| %autosetup -N -S git | %autosetup -N -S git | ||||||
| 
 | 
 | ||||||
| # Libraries that we already have packaged in Fedora (see Build Requirements): | # Libraries that we already have packaged in Fedora (see Build Requirements): | ||||||
| rm -rf cups/libs freetype ijs jbig2dec jpeg lcms2* libpng openjpeg tiff zlib | rm -rf cups/libs freetype ijs jbig2dec jpeg lcms2* leptonica libpng openjpeg tesseract tiff windows zlib | ||||||
| 
 |  | ||||||
| # Yeah, not actually needed in Fedora (^_^): |  | ||||||
| rm -rf windows |  | ||||||
| 
 | 
 | ||||||
| # Add the remaining source code to the initial commit, patch the source code: | # Add the remaining source code to the initial commit, patch the source code: | ||||||
| git add --all --force . | git add --all --force . | ||||||
| @ -325,7 +277,7 @@ git commit --all --amend --no-edit > /dev/null | |||||||
| #         for China's GB18030 official certification: | #         for China's GB18030 official certification: | ||||||
| %if %{defined rhel} || %{defined centos} | %if %{defined rhel} || %{defined centos} | ||||||
| %configure --enable-dynamic --disable-compile-inits --without-versioned-path \ | %configure --enable-dynamic --disable-compile-inits --without-versioned-path \ | ||||||
|            --with-fontpath="%{urw_base35_fontpath}:%{google_droid_fontpath}:%{_datadir}/%{name}/conf.d/:%{_datadir}/fonts" |            --with-fontpath="%{urw_base35_fontpath}:%{google_droid_fontpath}:%{_datadir}/%{name}/conf.d/" | ||||||
| %else | %else | ||||||
| %configure --enable-dynamic --disable-compile-inits --without-versioned-path \ | %configure --enable-dynamic --disable-compile-inits --without-versioned-path \ | ||||||
|            --with-fontpath="%{urw_base35_fontpath}:%{google_droid_fontpath}" |            --with-fontpath="%{urw_base35_fontpath}:%{google_droid_fontpath}" | ||||||
| @ -372,7 +324,7 @@ ln -s %{_mandir}/man1/gs.1 %{buildroot}%{_mandir}/man1/ghostscript.1 | |||||||
| # process for Ghostscript startup, and they advise using the symlinks where | # process for Ghostscript startup, and they advise using the symlinks where | ||||||
| # possible. The fontconfig (Ghostscript's search path) should be used preferably | # possible. The fontconfig (Ghostscript's search path) should be used preferably | ||||||
| # as a fallback only. | # as a fallback only. | ||||||
| ln -fs %{google_droid_fontpath}/DroidSansFallback.ttf %{buildroot}%{_datadir}/%{name}/Resource/CIDFSubst/DroidSansFallback.ttf | ln -fs %{google_droid_fontpath}/DroidSansFallbackFull.ttf %{buildroot}%{_datadir}/%{name}/Resource/CIDFSubst/DroidSansFallback.ttf | ||||||
| 
 | 
 | ||||||
| for font in $(basename --multiple %{buildroot}%{_datadir}/%{name}/Resource/Font/*); do | for font in $(basename --multiple %{buildroot}%{_datadir}/%{name}/Resource/Font/*); do | ||||||
|   ln -fs %{urw_base35_fontpath}/${font}.t1 %{buildroot}%{_datadir}/%{name}/Resource/Font/${font} |   ln -fs %{urw_base35_fontpath}/${font}.t1 %{buildroot}%{_datadir}/%{name}/Resource/Font/${font} | ||||||
| @ -493,138 +445,172 @@ done | |||||||
| # ============================================================================= | # ============================================================================= | ||||||
| 
 | 
 | ||||||
| %changelog | %changelog | ||||||
| * Wed May 07 2025 Zdenek Dohnal <zdohnal@redhat.com> - 9.27-17 |  | ||||||
| - RHEL-88965 CVE-2025-27832 ghostscript: NPDL device: Compression buffer overflow |  | ||||||
| 
 | 
 | ||||||
| * Tue Apr 15 2025 Zdenek Dohnal <zdohnal@redhat.com> - 9.27-16 | * Fri Aug 04 2023 Richard Lescak <rlescak@redhat.com> - 9.54.0-13 | ||||||
| - RHEL-18396 CVE-2023-46751 ghostscript: dangling pointer in gdev_prn_open_printer_seekable() |  | ||||||
| - RHEL-67046 CVE-2024-46951 ghostscript: Arbitrary Code Execution in Artifex Ghostscript Pattern Color Space |  | ||||||
| - RHEL-15067 CVE-2020-27792 ghostscript: heap buffer over write vulnerability in GhostScript's lp8000_print_page() in gdevlp8k.c |  | ||||||
| - RHEL-67051 CVE-2024-46954 ghostscript: Directory Traversal in Ghostscript via Overlong UTF-8 Encoding |  | ||||||
| - RHEL-67051 CVE-2024-46953 ghostscript: Path Traversal and Code Execution via Integer Overflow in Ghostscript |  | ||||||
| - RHEL-67051 CVE-2024-46956 ghostscript: Out-of-Bounds Data Access in Ghostscript Leads to Arbitrary Code Execution |  | ||||||
| 
 |  | ||||||
| * Mon Oct 14 2024 Zdenek Dohnal <zdohnal@redhat.com> - 9.27-15 |  | ||||||
| - fix printing PCL XL on some printers |  | ||||||
| 
 |  | ||||||
| * Thu Oct 10 2024 Zdenek Dohnal <zdohnal@redhat.com> - 9.27-14 |  | ||||||
| - RHEL-61729 Ghostscript is generating PJL of a significantly larger size |  | ||||||
| 
 |  | ||||||
| * Wed Jun 12 2024 Zdenek Dohnal <zdohnal@redhat.com> - 9.27-13 |  | ||||||
| - CVE-2024-33871 ghostscript: OPVP device arbitrary code execution via custom Driver library |  | ||||||
| 
 |  | ||||||
| * Tue Sep 19 2023 Richard Lescak <rlescak@redhat.com> - 9.27-12 |  | ||||||
| - fix to prevent divison by zero in devices |  | ||||||
| - Resolves: rhbz#2235009 |  | ||||||
| 
 |  | ||||||
| * Fri Aug 04 2023 Richard Lescak <rlescak@redhat.com> - 9.27-11 |  | ||||||
| - fix for CVE-2023-4042 |  | ||||||
| - Resolves: rhbz#2228153 |  | ||||||
| 
 |  | ||||||
| * Fri Aug 04 2023 Richard Lescak <rlescak@redhat.com> - 9.27-10 |  | ||||||
| - fix for CVE-2023-38559 | - fix for CVE-2023-38559 | ||||||
| - Resolves: rhbz#2224371 | - Resolves: rhbz#2224372 | ||||||
| 
 | 
 | ||||||
| * Fri May 05 2023 Richard Lescak <rlescak@redhat.com> - 9.27-9 | * Tue Aug 01 2023 Richard Lescak <rlescak@redhat.com> - 9.54.0-12 | ||||||
|  | - fix for CVE-2023-36664 | ||||||
|  | - Resolves: rhbz#2217810 | ||||||
|  | 
 | ||||||
|  | * Fri May 05 2023 Richard Lescak <rlescak@redhat.com> - 9.54.0-11 | ||||||
| - fix for CVE-2023-28879 | - fix for CVE-2023-28879 | ||||||
| - Resolves: rhbz#2188297 | - Resolves: rhbz#2188300 | ||||||
| 
 | 
 | ||||||
| * Fri Mar 17 2023 Richard Lescak <rlescak@redhat.com> - 9.27-8 | * Fri Mar 17 2023 Richard Lescak <rlescak@redhat.com> - 9.54.0-10 | ||||||
| - fix embedding of CIDFonts | - fix embedding of CIDFonts | ||||||
| - Resolves: rhbz#2169890 | - Resolves: rhbz#2179023 | ||||||
| 
 | 
 | ||||||
| * Wed Mar 15 2023 Richard Lescak <rlescak@redhat.com> - 9.27-7 | * Thu Feb 02 2023 Richard Lescak <rlescak@redhat.com> - 9.54.0-9 | ||||||
| - fix bbox device calculating bounding box incorrectly |  | ||||||
| - Resolves: rhbz#2176327 |  | ||||||
| 
 |  | ||||||
| * Thu Feb 02 2023 Richard Lescak <rlescak@redhat.com> - 9.27-6 |  | ||||||
| - set the page size for A4 correctly in ESC/Page driver | - set the page size for A4 correctly in ESC/Page driver | ||||||
| - Resolves: rhbz#2164603 | - Resolves: rhbz#2164613 | ||||||
| 
 | 
 | ||||||
| * Tue Nov 15 2022 Richard Lescak <rlescak@redhat.com> - 9.27-5 | * Fri Dec 09 2022 Richard Lescak <rlescak@redhat.com> - 9.54.0-8 | ||||||
| - fix loading of CIDFonts | - fix loading of CIDFonts (#2138795) | ||||||
| - Resolves: rhbz#2118538 |  | ||||||
| 
 | 
 | ||||||
| * Mon Jul 25 2022 Richard Lescak <rlescak@redhat.com> - 9.27-4 | * Thu Feb 24 2022 Richard Lescak <rlescak@redhat.com> - 9.54.0-7 | ||||||
| - changed requirement to jbig2dec-libs | - Fix patch for covscan issues (#2032789) | ||||||
| - Resolves: rhbz#2097515, rhbz#2097448 |  | ||||||
| 
 | 
 | ||||||
| * Wed Jul 20 2022 Richard Lescak <rlescak@redhat.com> - 9.27-3 | * Tue Feb 22 2022 Richard Lescak <rlescak@redhat.com> - 9.54.0-6 | ||||||
| - fixed drifting text to the right when printing | - Added fix for vulnerability CVE-2021-45949 (#2049767) | ||||||
| - added Requirement for jbig2dec |  | ||||||
| - added patch for CVE-2020-16301 |  | ||||||
| - Resolves: rhbz#2097515, rhbz#2097448 |  | ||||||
| 
 | 
 | ||||||
| * Fri Jan 22 2021 Anna Khaitovich <akhaitov@redhat.com> - 9.27-2 | * Mon Feb 21 2022 Richard Lescak <rlescak@redhat.com> - 9.54.0-5 | ||||||
| - tools-dvipdf: require /usr/bin/dvips not %{_bindir}/dvips | - Added coverity fixes (#2032789) | ||||||
| - Resolves: rhbz#1918937 |  | ||||||
| 
 | 
 | ||||||
| * Tue Sep 01 2020 Anna Khaitovich <akhaitov@redhat.com> - 9.27-1 | * Thu Sep 16 2021 Richard Lescak <rlescak@redhat.com> - 9.54.0-4 | ||||||
| - Rebase to 9.27 | - Added fix for CVE-2021-3781 (#2002625) | ||||||
| - Resolves: rhbz#1874523 |  | ||||||
| 
 | 
 | ||||||
| * Tue Apr 07 2020 Zdenek Dohnal <zdohnal@redhat.com> - 9.25-7 | * Thu Sep 16 2021 Richard Lescak <rlescak@redhat.com> - 9.54.0-3 | ||||||
| - 1813228 - ghostscript fontconfig support broken when gs used with -dSAFER/-dPARANOIDSAFER | - Added fix for segfault bug (#1989084) | ||||||
| 
 | 
 | ||||||
| * Thu Nov 07 2019 Zdenek Dohnal <zdohnal@redhat.com> - 9.25-6 | * Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 9.54.0-2 | ||||||
| - 1769343 - CVE-2019-14869 - -dSAFER escape in .charkeys | - Rebuilt for IMA sigs, glibc 2.34, aarch64 flags | ||||||
|  |   Related: rhbz#1991688 | ||||||
| 
 | 
 | ||||||
| * Thu Aug 22 2019 Martin Osvald <mosvald@redhat.com> - 9.25-5 | * Mon Jul 26 2021 Richard Lescak <rlescak@redhat.com> - 9.54.0-1 | ||||||
| - Resolves: #1744011 - CVE-2019-14811 ghostscript: Safer Mode Bypass by .forceput Exposure in .pdf_hook_DSC_Creator (701445) | - Update to 9.54.0 (#1923969) | ||||||
| - Resolves: #1744015 - CVE-2019-14812 ghostscript: Safer Mode Bypass by .forceput Exposure in setuserparams (701444) |  | ||||||
| - Resolves: #1744006 - CVE-2019-14813 ghostscript: Safer Mode Bypass by .forceput Exposure in setsystemparams (701443) |  | ||||||
| - Resolves: #1744231 - CVE-2019-14817 ghostscript: Safer Mode Bypass by .forceput Exposure in .pdfexectoken and other procedures (701450) |  | ||||||
| 
 | 
 | ||||||
| * Mon Aug 05 2019 Martin Osvald <mosvald@redhat.com> - 9.25-4 | * Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 9.53.3-6 | ||||||
| - Resolves: #1737337 - CVE-2019-10216 ghostscript: -dSAFER escape via .buildfont1 (701394) | - Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 | ||||||
| 
 | 
 | ||||||
| * Thu Mar 28 2019 Martin Osvald <mosvald@redhat.com> - 9.25-3 | * Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 9.53.3-5 | ||||||
| - Resolves: #1692798 - CVE-2019-3839 ghostscript: missing attack vector | - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild | ||||||
|   protections for CVE-2019-6116 |  | ||||||
| - Resolves: #1678170 - CVE-2019-3835 ghostscript: superexec operator |  | ||||||
|   is available (700585) |  | ||||||
| - Resolves: #1691414 - CVE-2019-3838 ghostscript: forceput in DefineResource |  | ||||||
|   is still accessible (700576) |  | ||||||
| - fix included for ghostscript: Regression: double comment chars |  | ||||||
|   '%%' in gs_init.ps leading to missing metadata |  | ||||||
| - fix for pdf2dsc regression added to allow fix for CVE-2019-3839 |  | ||||||
| 
 | 
 | ||||||
| * Wed Jan 23 2019 Martin Osvald <mosvald@redhat.com> - 9.25-2 | * Tue Dec 22 2020 Michael J Gruber <mjg@fedoraproject.org> - 9.53.3-4 | ||||||
| - Resolves: #1652937 - CVE-2018-19409 ghostscript: Improperly implemented | - Restore opvp for good (#1909950) | ||||||
|   security check in zsetdevice function in psi/zdevice.c |  | ||||||
| - Resolves: #1642586 - CVE-2018-18073 ghostscript: saved execution stacks |  | ||||||
|   can leak operator arrays |  | ||||||
| - Resolves: #1642580 - CVE-2018-17961 ghostscript: saved execution stacks |  | ||||||
|   can leak operator arrays (incomplete fix for CVE-2018-17183) |  | ||||||
| - Resolves: #1642941 - CVE-2018-18284 ghostscript: 1Policy operator |  | ||||||
|   allows a sandbox protection bypass |  | ||||||
| - Resolves: #1656336 - CVE-2018-19134 ghostscript: Type confusion in |  | ||||||
|   setpattern (700141) |  | ||||||
| - Resolves: #1660571 - CVE-2018-19475 ghostscript: access bypass in |  | ||||||
|   psi/zdevice2.c (700153) |  | ||||||
| - Resolves: #1660830 - CVE-2018-19476 ghostscript: access bypass in |  | ||||||
|   psi/zicc.c |  | ||||||
| - Resolves: #1661280 - CVE-2018-19477 ghostscript: access bypass in |  | ||||||
|   psi/zfjbig2.c (700168) |  | ||||||
| - Resolves: #1668891 - CVE-2019-6116 ghostscript: subroutines within |  | ||||||
|   pseudo-operators must themselves be pseudo-operators (700317) |  | ||||||
| 
 | 
 | ||||||
| * Mon Sep 24 2018 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.25-1 | * Tue Nov 24 2020 Michael J Gruber <mjg@fedoraproject.org> - 9.53.3-3 | ||||||
| - rebase to latest upstream version to fix issues discovered in previous CVE fixes (bug #1631701 and #1626997) | - Restore opvp device (#1899885) | ||||||
| 
 | 
 | ||||||
| * Fri Sep 07 2018 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.24-1 | * Wed Nov 04 2020 Anna Khaitovich <akhaitov@redhat.com> - 9.53.3-2 | ||||||
|  | - Drop use of FT_CALLBACK_DEF() def | ||||||
|  | 
 | ||||||
|  | * Thu Oct 08 2020 Fedora Release Monitoring <release-monitoring@fedoraproject.org> - 9.53.1-3 | ||||||
|  | - Update to 9.53.3 (#1882743) | ||||||
|  | 
 | ||||||
|  | * Tue Sep 22 2020 Anna Khaitovich <akhaitov@redhat.com> - 9.53.1-2 | ||||||
|  | - Bump jbig2dec version | ||||||
|  | 
 | ||||||
|  | * Thu Sep 10 2020 Fedora Release Monitoring <release-monitoring@fedoraproject.org> - 9.53.0-1 | ||||||
|  | - Update to 9.53.1 (#1877781) | ||||||
|  | 
 | ||||||
|  | * Mon Jul 27 2020 Anna Khaitovich <akhaitov@redhat.com> - 9.52-8 | ||||||
|  | - Use libidn2 instead of libidn (fixes #1860890) | ||||||
|  | 
 | ||||||
|  | * Thu Jul 02 2020 Michael J Gruber <mjg@fedoraproject.org> - 9.52-7 | ||||||
|  | - really require the exact jbig2dec version | ||||||
|  | 
 | ||||||
|  | * Sat Jun 27 2020 Peter Robinson <pbrobinson@fedoraproject.org> - 9.52-6 | ||||||
|  | - standard packages should not require -devel packages | ||||||
|  | 
 | ||||||
|  | * Wed Jun 24 2020 Anna Khaitovich <akhaitov@redhat.com> - 9.52-5 | ||||||
|  | - Require the exact jbig2dec version in both build and runtime dependencies | ||||||
|  | 
 | ||||||
|  | * Thu May 21 2020 Anna Khaitovich <akhaitov@redhat.com> - 9.52-4 | ||||||
|  | - Define %%{jbig2dec_version} global macro | ||||||
|  | 
 | ||||||
|  | * Wed May 20 2020 Anna Khaitovich <akhaitov@redhat.com> - 9.52-3 | ||||||
|  | - Require the exact jbig2dec version to avoid a mismatch between header files and library | ||||||
|  | 
 | ||||||
|  | * Mon May 18 2020 Anna Khaitovich <akhaitov@redhat.com> - 9.52-2 | ||||||
|  | - Require the exact jbig2dec-devel version | ||||||
|  | 
 | ||||||
|  | * Thu Apr 02 2020 Zdenek Dohnal <zdohnal@redhat.com> - 9.52-1 | ||||||
|  | - 9.52 | ||||||
|  | 
 | ||||||
|  | * Wed Mar 11 2020 Zdenek Dohnal <zdohnal@redhat.com> - 9.50-1 | ||||||
|  | - 9.50 | ||||||
|  | 
 | ||||||
|  | * Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 9.27-3 | ||||||
|  | - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild | ||||||
|  | 
 | ||||||
|  | * Thu Nov 14 2019 Zdenek Dohnal <zdohnal@redhat.com> - 9.27-2 | ||||||
|  | - 1772486 - ghostscript: -dSAFER escape in .charkeys (701841) | ||||||
|  | 
 | ||||||
|  | * Fri Sep 06 2019 Martin Osvald <mosvald@redhat.com> - 9.27-1 | ||||||
|  | - rebase to latest upstream version 9.27 | ||||||
|  | - security fixes added for: | ||||||
|  |   - CVE-2019-14811 (bug #1747908) | ||||||
|  |   - CVE-2019-14812 (bug #1747907) | ||||||
|  |   - CVE-2019-14813 (bug #1747906) | ||||||
|  |   - CVE-2019-14817 (bug #1747909) | ||||||
|  | 
 | ||||||
|  | * Mon Aug 12 2019 Martin Osvald <mosvald@redhat.com> - 9.26-6 | ||||||
|  | - Fix for CVE-2019-10216 added | ||||||
|  | 
 | ||||||
|  | * Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 9.26-5 | ||||||
|  | - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild | ||||||
|  | 
 | ||||||
|  | * Fri Mar 22 2019 Martin Osvald <mosvald@redhat.com> - 9.26-4 | ||||||
|  | - Fixes for CVE-2019-3835 and CVE-2019-3838 added | ||||||
|  | 
 | ||||||
|  | * Mon Mar 11 2019 Martin Osvald <mosvald@redhat.com> - 9.26-3 | ||||||
|  | - Fix for bug #1687144 added | ||||||
|  | 
 | ||||||
|  | * Fri Mar 08 2019 Martin Osvald <mosvald@redhat.com> - 9.26-2 | ||||||
|  | - Fix for CVE-2019-6116 added (bug #1668888) | ||||||
|  | 
 | ||||||
|  | * Thu Feb 07 2019 Martin Osvald <mosvald@redhat.com> - 9.26-1 | ||||||
|  | - rebase to latest upstream version 9.26 | ||||||
|  | - spec change to remove gsdoc.el due to upstream 8bc783cb586 | ||||||
|  | 
 | ||||||
|  | * Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 9.25-2 | ||||||
|  | - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild | ||||||
|  | 
 | ||||||
|  | * Mon Sep 17 2018 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.25-1 | ||||||
|  | - rebase to latest upstream version to fix additional issues found in 9.24 | ||||||
|  | 
 | ||||||
|  | * Fri Sep 14 2018 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.24-3 | ||||||
|  | - ghostscript-9.24-002-icc-PermitReading.patch removed | ||||||
|  | - ghostscript-9.24-002-fix-for-Canon-and-Kyocera-printers.patch added (bug #1626818) | ||||||
|  | - ghostscript-9.24-003-CVE-2018-16802.patch added (bug #1627960) | ||||||
|  | 
 | ||||||
|  | * Fri Sep 07 2018 Tom Callaway <spot@fedoraproject.org> - 9.24-2 | ||||||
|  | - add upstream fix for reading in ICC profiles | ||||||
|  | 
 | ||||||
|  | * Wed Sep 05 2018 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.24-1 | ||||||
| - rebase to latest upstream version, which contains important CVE fixes | - rebase to latest upstream version, which contains important CVE fixes | ||||||
| - additional ZER0-DAY fixes added | - additional ZER0-DAY fixes added | ||||||
| 
 | 
 | ||||||
| * Wed Aug 29 2018 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.23-5 | * Wed Aug 29 2018 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.23-7 | ||||||
| - ghostscript-9.23-002-fixes-for-set-of-CVEs-reported-by-Google.patch added | - ghostscript-9.23-002-fixes-for-set-of-CVEs-reported-by-Google.patch added | ||||||
| 
 | 
 | ||||||
|  | * Mon Jul 30 2018 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.23-6 | ||||||
|  | - ghostscript-9.23-001-create-GC-descriptors-for-JPEG-passthrough.patch added (bug #1589467) | ||||||
|  | 
 | ||||||
|  | * Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 9.23-5 | ||||||
|  | - Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild | ||||||
|  | 
 | ||||||
| * Tue May 15 2018 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.23-4 | * Tue May 15 2018 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.23-4 | ||||||
| - One more rebuild for libidn ABI fix (BZ#'s 1573961 and 1566414) | - One more rebuild for libidn ABI fix (BZ#'s 1573961 and 1566414) | ||||||
| 
 | 
 | ||||||
| * Mon May 14 2018 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.23-3 | * Mon May 14 2018 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.23-3 | ||||||
| - %%conflicts_vers bumped to fix F27->F28 upgrade | - %%conflicts_vers bumped to fix F27->F28 upgrade | ||||||
| 
 | 
 | ||||||
|  | * Thu May 10 2018 Stephen Gallagher <sgallagh@redhat.com> - 9.23-2.1 | ||||||
|  | - Rebuilding for libidn ABI fix (BZ#'s 1573961 and 1566414) | ||||||
|  | 
 | ||||||
| * Mon Apr 23 2018 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.23-2 | * Mon Apr 23 2018 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 9.23-2 | ||||||
| - Fix for CVE-2018-10194 added (bug #1569821) | - Fix for CVE-2018-10194 added (bug #1569821) | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user