Sophie

Sophie

distrib > Mageia > 6 > armv7hl > media > core-updates-src > by-pkgid > bc219369320b6b5781eed48254462cef > files > 20

ghostscript-9.25-1.2.mga6.src.rpm

From 90e8f8d32b64bae015e19e85e693988daaea54f4 Mon Sep 17 00:00:00 2001
From: Ken Sharp <ken.sharp@artifex.com>
Date: Thu, 20 Sep 2018 10:09:37 +0100
Subject: [PATCH] Bug #699796 "copydevice fails after stack device copies
 invalidated"

This isn't anything to do with .fill_identity_cmap. A simpler example
is:

.distillerdevice
nulldevice
copydevice

The problem is that when we execute nulldevice we need to invalidate any
copies, stored on the operand stack, of the device that was current
before the nulldevice was installed.

We do that by setting the pdevice member of the device structure to NULL.
However the fact that a device can be invalidated has clearly passed
by a number of developers in the intervening years, and a number of
places in the code do check the type of the operand is a device, but
they don't check to see if the device has been invalidated.

Add validation checks where required.
---
 psi/idisp.c   |  4 ++++
 psi/zdevice.c | 18 ++++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/psi/idisp.c b/psi/idisp.c
index 2ca7b57..c65671c 100644
--- a/psi/idisp.c
+++ b/psi/idisp.c
@@ -81,6 +81,10 @@ display_set_callback(gs_main_instance *minst, display_callback *callback)
          * setting callback, then reopen it.
          */
         check_read_type(op[-1], t_device);
+        if (op[-1].value.pdevice == NULL)
+            /* This can happen if we invalidated devices on the stack by calling nulldevice after they were pushed */
+            return_error(gs_error_undefined);
+
         dev = op[-1].value.pdevice;
 
         was_open = dev->is_open;
diff --git a/psi/zdevice.c b/psi/zdevice.c
index 7d5f58d..6d2ce05 100644
--- a/psi/zdevice.c
+++ b/psi/zdevice.c
@@ -46,6 +46,10 @@ zcopydevice2(i_ctx_t *i_ctx_p)
 
     check_read_type(op[-1], t_device);
     check_type(*op, t_boolean);
+    if (op[-1].value.pdevice == NULL)
+        /* This can happen if we invalidated devices on the stack by calling nulldevice after they were pushed */
+        return_error(gs_error_undefined);
+
     code = gs_copydevice2(&new_dev, op[-1].value.pdevice, op->value.boolval,
                           imemory);
     if (code < 0)
@@ -108,6 +112,10 @@ zdevicename(i_ctx_t *i_ctx_p)
     const char *dname;
 
     check_read_type(*op, t_device);
+    if (op->value.pdevice == NULL)
+        /* This can happen if we invalidated devices on the stack by calling nulldevice after they were pushed */
+        return_error(gs_error_undefined);
+
     dname = op->value.pdevice->dname;
     make_const_string(op, avm_foreign | a_readonly, strlen(dname),
                       (const byte *)dname);
@@ -157,6 +165,10 @@ zgetbitsrect(i_ctx_t *i_ctx_p)
 
     check_read_type(op[-7], t_device);
     dev = op[-7].value.pdevice;
+    if (dev == NULL)
+        /* This can happen if we invalidated devices on the stack by calling nulldevice after they were pushed */
+        return_error(gs_error_undefined);
+
     check_int_leu(op[-6], dev->width);
     rect.p.x = op[-6].value.intval;
     check_int_leu(op[-5], dev->height);
@@ -274,6 +286,9 @@ zget_device_params(i_ctx_t *i_ctx_p, bool is_hardware)
     }
     rkeys = *op;
     dev = op[-1].value.pdevice;
+    if (op[-1].value.pdevice == NULL)
+        /* This can happen if we invalidated devices on the stack by calling nulldevice after they were pushed */
+        return_error(gs_error_undefined);
     pop(1);
     stack_param_list_write(&list, &o_stack, &rkeys, iimemory);
     code = gs_get_device_or_hardware_params(dev, (gs_param_list *) & list,
@@ -440,6 +455,9 @@ zputdeviceparams(i_ctx_t *i_ctx_p)
     check_type_only(*prequire_all, t_boolean);
     check_write_type_only(*pdev, t_device);
     dev = pdev->value.pdevice;
+    if (dev == NULL)
+        /* This can happen if we invalidated devices on the stack by calling nulldevice after they were pushed */
+        return_error(gs_error_undefined);
     code = stack_param_list_read(&list, &o_stack, 0, ppolicy,
                                  prequire_all->value.boolval, iimemory);
     if (code < 0)
-- 
2.9.1