Blob Blame History Raw
From 3a0439ded9a206060f560bd6784942adeab759ff Mon Sep 17 00:00:00 2001
From: Chris Liddell <chris.liddell@artifex.com>
Date: Thu, 27 Apr 2017 13:03:33 +0100
Subject: [PATCH 1/4] Bug 697799: have .eqproc check its parameters

The Ghostscript custom operator .eqproc was not check the number or type of
the parameters it was given.
---
 psi/zmisc3.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/psi/zmisc3.c b/psi/zmisc3.c
index 54b3042..0d357f1 100644
--- a/psi/zmisc3.c
+++ b/psi/zmisc3.c
@@ -56,6 +56,12 @@ zeqproc(i_ctx_t *i_ctx_p)
     ref2_t stack[MAX_DEPTH + 1];
     ref2_t *top = stack;
 
+    if (ref_stack_count(&o_stack) < 2)
+        return_error(e_stackunderflow);
+    if (!r_is_array(op - 1) || !r_is_array(op)) {
+        return_error(e_typecheck);
+    }
+
     make_array(&stack[0].proc1, 0, 1, op - 1);
     make_array(&stack[0].proc2, 0, 1, op);
     for (;;) {
-- 
2.9.3


From 9040e08c62422937c27fa5179657fbe3690809f3 Mon Sep 17 00:00:00 2001
From: Chris Liddell <chris.liddell@artifex.com>
Date: Thu, 27 Apr 2017 13:21:31 +0100
Subject: [PATCH 2/4] Bug 697799: have .rsdparams check its parameters

The Ghostscript internal operator .rsdparams wasn't checking the number or
type of the operands it was being passed. Do so.
---
 psi/zfrsd.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/psi/zfrsd.c b/psi/zfrsd.c
index fb4bce9..2629afa 100644
--- a/psi/zfrsd.c
+++ b/psi/zfrsd.c
@@ -49,13 +49,20 @@ zrsdparams(i_ctx_t *i_ctx_p)
     ref *pFilter;
     ref *pDecodeParms;
     int Intent = 0;
-    bool AsyncRead;
+    bool AsyncRead = false;
     ref empty_array, filter1_array, parms1_array;
     uint i;
-    int code;
+    int code = 0;
+
+    if (ref_stack_count(&o_stack) < 1)
+        return_error(e_stackunderflow);
+    if (!r_has_type(op, t_dictionary) && !r_has_type(op, t_null)) {
+        return_error(e_typecheck);
+    }
 
     make_empty_array(&empty_array, a_readonly);
-    if (dict_find_string(op, "Filter", &pFilter) > 0) {
+    if (r_has_type(op, t_dictionary)
+        && dict_find_string(op, "Filter", &pFilter) > 0) {
         if (!r_is_array(pFilter)) {
             if (!r_has_type(pFilter, t_name))
                 return_error(e_typecheck);
@@ -94,12 +101,13 @@ zrsdparams(i_ctx_t *i_ctx_p)
                 return_error(e_typecheck);
         }
     }
-    code = dict_int_param(op, "Intent", 0, 3, 0, &Intent);
+    if (r_has_type(op, t_dictionary))
+        code = dict_int_param(op, "Intent", 0, 3, 0, &Intent);
     if (code < 0 && code != e_rangecheck) /* out-of-range int is ok, use 0 */
         return code;
-    if ((code = dict_bool_param(op, "AsyncRead", false, &AsyncRead)) < 0
-        )
-        return code;
+    if (r_has_type(op, t_dictionary))
+        if ((code = dict_bool_param(op, "AsyncRead", false, &AsyncRead)) < 0)
+            return code;
     push(1);
     op[-1] = *pFilter;
     if (pDecodeParms)
-- 
2.9.3


From ba6c38c25e8c0ece91c47d96578f3f7a0e6c4e6c Mon Sep 17 00:00:00 2001
From: Chris Liddell <chris.liddell@artifex.com>
Date: Wed, 3 May 2017 12:05:45 +0100
Subject: [PATCH 3/4] Bug 697846: revision to commit 4f83478c88 (.eqproc)

When using the "DELAYBIND" feature, it turns out that .eqproc can be called with
parameters that are not both procedures. In this case, it turns out, the
expectation is for the operator to return 'false', rather than throw an error.
---
 psi/zmisc3.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/psi/zmisc3.c b/psi/zmisc3.c
index 0d357f1..9042908 100644
--- a/psi/zmisc3.c
+++ b/psi/zmisc3.c
@@ -38,6 +38,15 @@ zcliprestore(i_ctx_t *i_ctx_p)
     return gs_cliprestore(igs);
 }
 
+static inline bool
+eqproc_check_type(ref *r)
+{
+    return r_has_type(r, t_array)
+           || r_has_type(r, t_mixedarray)
+           || r_has_type(r, t_shortarray)
+           || r_has_type(r, t_oparray);
+}
+
 /* <proc1> <proc2> .eqproc <bool> */
 /*
  * Test whether two procedures are equal to depth 10.
@@ -58,8 +67,10 @@ zeqproc(i_ctx_t *i_ctx_p)
 
     if (ref_stack_count(&o_stack) < 2)
         return_error(e_stackunderflow);
-    if (!r_is_array(op - 1) || !r_is_array(op)) {
-        return_error(e_typecheck);
+    if (!eqproc_check_type(op -1) || !eqproc_check_type(op)) {
+        make_false(op - 1);
+        pop(1);
+        return 0;
     }
 
     make_array(&stack[0].proc1, 0, 1, op - 1);
-- 
2.9.3


From ae3fdbd05b0e654273402e7391288a091a1c0a9e Mon Sep 17 00:00:00 2001
From: Chris Liddell <chris.liddell@artifex.com>
Date: Thu, 11 May 2017 14:07:48 +0100
Subject: [PATCH 4/4] Bug 697892: fix check for op stack underflow.

In the original fix, I used the wrong method to check for stack underflow, this
is using the correct method.
---
 psi/zfrsd.c  | 3 +--
 psi/zmisc3.c | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/psi/zfrsd.c b/psi/zfrsd.c
index 2629afa..fd9872e 100644
--- a/psi/zfrsd.c
+++ b/psi/zfrsd.c
@@ -54,8 +54,7 @@ zrsdparams(i_ctx_t *i_ctx_p)
     uint i;
     int code = 0;
 
-    if (ref_stack_count(&o_stack) < 1)
-        return_error(e_stackunderflow);
+    check_op(1);
     if (!r_has_type(op, t_dictionary) && !r_has_type(op, t_null)) {
         return_error(e_typecheck);
     }
diff --git a/psi/zmisc3.c b/psi/zmisc3.c
index 9042908..43803b5 100644
--- a/psi/zmisc3.c
+++ b/psi/zmisc3.c
@@ -65,8 +65,7 @@ zeqproc(i_ctx_t *i_ctx_p)
     ref2_t stack[MAX_DEPTH + 1];
     ref2_t *top = stack;
 
-    if (ref_stack_count(&o_stack) < 2)
-        return_error(e_stackunderflow);
+    check_op(2);
     if (!eqproc_check_type(op -1) || !eqproc_check_type(op)) {
         make_false(op - 1);
         pop(1);
-- 
2.9.3