Blob Blame History Raw
From fac7eb144135f3ed8fbb0028ab1f33ce4dcc1985 Mon Sep 17 00:00:00 2001
From: Ken Sharp <ken.sharp@artifex.com>
Date: Fri, 21 Sep 2018 13:02:56 +0100
Subject: [PATCH 1/3] Check all uses of dict_find* to ensure 0 return properly
 handled

dict_find and friends have the surprising quirk of returning < 0 for
an error and > 0 for no error. But they can also return 0 which means
'not found' without it being an error.

From bug 699801, if the code assumes the usual case where 0 is a success
then an attempt might be made to use the empty dictionary slot returned
by dict_find*, which can lead to seg faults, and certainly won't have
the expected result.
---
 psi/icontext.c |  4 ++--
 psi/zcid.c     |  6 ++++--
 psi/zfapi.c    | 33 ++++++++++++++++++---------------
 psi/zfcid0.c   | 39 +++++++++++++++++++++++++++++----------
 psi/zfcid1.c   | 14 ++++++++++----
 psi/zicc.c     |  4 ++++
 psi/zpdf_r6.c  | 31 +++++++++++++++++++++++--------
 psi/ztoken.c   |  2 +-
 8 files changed, 91 insertions(+), 42 deletions(-)

diff --git a/psi/icontext.c b/psi/icontext.c
index 4db78e0..1fbe486 100644
--- a/psi/icontext.c
+++ b/psi/icontext.c
@@ -162,7 +162,7 @@ context_state_alloc(gs_context_state_t ** ppcst,
         uint size;
         ref *system_dict = &pcst->dict_stack.system_dict;
 
-        if (dict_find_string(system_dict, "userparams", &puserparams) >= 0)
+        if (dict_find_string(system_dict, "userparams", &puserparams) > 0)
             size = dict_length(puserparams);
         else
             size = 300;
@@ -286,7 +286,7 @@ context_state_store(gs_context_state_t * pcst)
         /* We need i_ctx_p for access to the d_stack. */
         i_ctx_t *i_ctx_p = pcst;
 
-        if (dict_find_string(systemdict, "userparams", &puserparams) < 0)
+        if (dict_find_string(systemdict, "userparams", &puserparams) <= 0)
             return_error(gs_error_Fatal);
         pcst->userparams = *puserparams;
     }
diff --git a/psi/zcid.c b/psi/zcid.c
index e394877..5c98fc9 100644
--- a/psi/zcid.c
+++ b/psi/zcid.c
@@ -72,11 +72,13 @@ TT_char_code_from_CID_no_subst(const gs_memory_t *mem,
     } else
         return false; /* Must not happen. */
     for (;n--; i++) {
+        int code;
+
         if (array_get(mem, DecodingArray, i, &char_code1) < 0 ||
             !r_has_type(&char_code1, t_integer))
             return false; /* Must not happen. */
-        if (dict_find(TT_cmap, &char_code1, &glyph_index) >= 0 &&
-                r_has_type(glyph_index, t_integer)) {
+        code = dict_find(TT_cmap, &char_code1, &glyph_index);
+        if (code > 0 && r_has_type(glyph_index, t_integer)) {
             *c = glyph_index->value.intval;
             found = true;
             if (*c != 0)
diff --git a/psi/zfapi.c b/psi/zfapi.c
index 48e1d54..1b687b0 100644
--- a/psi/zfapi.c
+++ b/psi/zfapi.c
@@ -1826,6 +1826,9 @@ FAPI_get_xlatmap(i_ctx_t *i_ctx_p, char **xlatmap)
 
     if ((code = dict_find_string(systemdict, ".xlatmap", &pref)) < 0)
         return code;
+    if (code == 0)
+        return_error(gs_error_undefined);
+
     if (r_type(pref) != t_string)
         return_error(gs_error_typecheck);
     *xlatmap = (char *)pref->value.bytes;
@@ -1881,11 +1884,11 @@ ps_get_server_param(gs_fapi_server *I, const byte *subtype,
     ref *FAPIconfig, *options, *server_options;
     i_ctx_t *i_ctx_p = (i_ctx_t *) I->client_ctx_p;
 
-    if (dict_find_string(systemdict, ".FAPIconfig", &FAPIconfig) >= 0
+    if (dict_find_string(systemdict, ".FAPIconfig", &FAPIconfig) > 0
         && r_has_type(FAPIconfig, t_dictionary)) {
-        if (dict_find_string(FAPIconfig, "ServerOptions", &options) >= 0
+        if (dict_find_string(FAPIconfig, "ServerOptions", &options) > 0
             && r_has_type(options, t_dictionary)) {
-            if (dict_find_string(options, (char *)subtype, &server_options) >=
+            if (dict_find_string(options, (char *)subtype, &server_options) >
                 0 && r_has_type(server_options, t_string)) {
                 *server_param = (byte *) server_options->value.const_bytes;
                 *server_param_size = r_size(server_options);
@@ -2070,7 +2073,7 @@ zFAPIrebuildfont(i_ctx_t *i_ctx_p)
     pdata = (font_data *) pfont->client_data;
     I = pbfont->FAPI;
 
-    if (dict_find_string((op - 1), "SubfontId", &v) >= 0
+    if (dict_find_string((op - 1), "SubfontId", &v) > 0
         && r_has_type(v, t_integer))
         subfont = v->value.intval;
     else
@@ -2277,8 +2280,8 @@ ps_get_glyphname_or_cid(gs_text_enum_t *penum,
         if (pbfont->FontType == ft_CID_TrueType && font_file_path) {
             ref *pdr2, *fidr, *dummy;
             pdr2 = pfont_dict(gs_rootfont(igs));
-            if (dict_find_string(pdr2, "FontInfo", &fidr) &&
-                dict_find_string(fidr, "GlyphNames2Unicode", &dummy))
+            if (dict_find_string(pdr2, "FontInfo", &fidr) > 0 &&
+                dict_find_string(fidr, "GlyphNames2Unicode", &dummy) > 0)
             {
                 unsigned char uc[4] = {0};
                 unsigned int cc = 0;
@@ -2417,13 +2420,13 @@ ps_get_glyphname_or_cid(gs_text_enum_t *penum,
 
                 fdict = pfont_dict(gs_rootfont(igs));
                 code = dict_find_string(fdict, "CMap", &CMapDict);
-                if (code >= 0 && r_has_type(CMapDict, t_dictionary)) {
+                if (code > 0 && r_has_type(CMapDict, t_dictionary)) {
                     code = dict_find_string(CMapDict, "WMode", &WMode);
-                    if (code >= 0 && r_has_type(WMode, t_integer)) {
+                    if (code > 0 && r_has_type(WMode, t_integer)) {
                         wmode = WMode->value.intval;
                     }
                     code = dict_find_string(CMapDict, "CMapName", &CMapName);
-                    if (code >= 0 && r_has_type(CMapName, t_name)) {
+                    if (code > 0 && r_has_type(CMapName, t_name)) {
                         name_string_ref(imemory, CMapName, &CMapNameStr);
                         cmapnm = (char *)CMapNameStr.value.bytes;
                         cmapnmlen = r_size(&CMapNameStr);
@@ -2432,10 +2435,10 @@ ps_get_glyphname_or_cid(gs_text_enum_t *penum,
                 /* We only have to lookup the char code if we're *not* using an identity ordering 
                    with the exception of Identity-UTF16 which is a different beast altogether */
                 if (unicode_cp || (cmapnmlen > 0 && !strncmp(cmapnm, utfcmap, cmapnmlen > utfcmaplen ? utfcmaplen : cmapnmlen))
-                    || (dict_find_string(pdr, "CIDSystemInfo", &CIDSystemInfo) >= 0
+                    || (dict_find_string(pdr, "CIDSystemInfo", &CIDSystemInfo) > 0
                     && r_has_type(CIDSystemInfo, t_dictionary)
                     && dict_find_string(CIDSystemInfo, "Ordering",
-                                        &Ordering) >= 0
+                                        &Ordering) > 0
                     && r_has_type(Ordering, t_string)
                     && strncmp((const char *)Ordering->value.bytes,
                                "Identity", 8) != 0)) {
@@ -2463,7 +2466,7 @@ ps_get_glyphname_or_cid(gs_text_enum_t *penum,
                 ref cc32;
                 ref *gid;
                 make_int(&cc32, 32);
-                if (dict_find(TT_cmap, &cc32, &gid) >= 0)
+                if (dict_find(TT_cmap, &cc32, &gid) > 0)
                     c = gid->value.intval;
             }
             cr->char_codes[0] = c;
@@ -2536,7 +2539,7 @@ ps_get_glyphname_or_cid(gs_text_enum_t *penum,
         if (dict_find_string(pdr, "CharStrings", &CharStrings) <= 0
             || !r_has_type(CharStrings, t_dictionary))
             return_error(gs_error_invalidfont);
-        if ((dict_find(CharStrings, &char_name, &glyph_index) < 0)
+        if ((dict_find(CharStrings, &char_name, &glyph_index) <= 0)
             || r_has_type(glyph_index, t_null)) {
 #ifdef DEBUG
             ref *pvalue;
@@ -2955,7 +2958,7 @@ zFAPIpassfont(i_ctx_t *i_ctx_p)
     if (code < 0)
         return code;
 
-    if (dict_find_string(op, "SubfontId", &v) >= 0
+    if (dict_find_string(op, "SubfontId", &v) > 0
         && r_has_type(v, t_integer))
         subfont = v->value.intval;
     else
@@ -2968,7 +2971,7 @@ zFAPIpassfont(i_ctx_t *i_ctx_p)
     /* If the font dictionary contains a FAPIPlugInReq key, the the PS world wants us
      * to try to use a specific FAPI plugin, so find it, and try it....
      */
-    if (dict_find_string(op, "FAPIPlugInReq", &v) >= 0 && r_type(v) == t_name) {
+    if (dict_find_string(op, "FAPIPlugInReq", &v) > 0 && r_type(v) == t_name) {
 
         name_string_ref(imemory, v, &reqstr);
 
diff --git a/psi/zfcid0.c b/psi/zfcid0.c
index 2aba09a..ba00b21 100644
--- a/psi/zfcid0.c
+++ b/psi/zfcid0.c
@@ -410,13 +410,25 @@ zbuildfont9(i_ctx_t *i_ctx_p)
      * from a file, GlyphData will be an integer, and DataSource will be
      * a (reusable) stream.
      */
-    if (code < 0 ||
-        (code = cid_font_data_param(op, &common, &GlyphDirectory)) < 0 ||
-        (code = dict_find_string(op, "FDArray", &prfda)) < 0 ||
-        (code = dict_find_string(op, "CIDFontName", &pCIDFontName)) <= 0 ||
-        (code = dict_int_param(op, "FDBytes", 0, MAX_FDBytes, -1, &FDBytes)) < 0
-        )
+    if (code < 0)
+        return code;
+    code = cid_font_data_param(op, &common, &GlyphDirectory);
+    if (code < 0)
+        return code;
+    code = dict_find_string(op, "FDArray", &prfda);
+    if (code < 0)
+        return code;
+    if (code == 0)
+        return_error(gs_error_undefined);
+    code = dict_find_string(op, "CIDFontName", &pCIDFontName);
+    if (code < 0)
+        return code;
+    if (code == 0)
+        return_error(gs_error_undefined);
+    code = dict_int_param(op, "FDBytes", 0, MAX_FDBytes, -1, &FDBytes);
+    if (code < 0)
         return code;
+
     /*
      * Since build_gs_simple_font may resize the dictionary and cause
      * pointers to become invalid, save CIDFontName
@@ -426,17 +438,24 @@ zbuildfont9(i_ctx_t *i_ctx_p)
         /* Standard CIDFont, require GlyphData and CIDMapOffset. */
         ref *pGlyphData;
 
-        if ((code = dict_find_string(op, "GlyphData", &pGlyphData)) < 0 ||
-            (code = dict_uint_param(op, "CIDMapOffset", 0, max_uint - 1,
-                                    max_uint, &CIDMapOffset)) < 0)
+        code = dict_find_string(op, "GlyphData", &pGlyphData);
+        if (code < 0)
+            return code;
+        if (code == 0)
+            return_error(gs_error_undefined);
+        code = dict_uint_param(op, "CIDMapOffset", 0, max_uint - 1, max_uint, &CIDMapOffset);
+        if (code < 0)
             return code;
         GlyphData = *pGlyphData;
         if (r_has_type(&GlyphData, t_integer)) {
             ref *pds;
             stream *ignore_s;
 
-            if ((code = dict_find_string(op, "DataSource", &pds)) < 0)
+            code = dict_find_string(op, "DataSource", &pds);
+            if (code < 0)
                 return code;
+            if (code == 0)
+                return_error(gs_error_undefined);
             check_read_file(i_ctx_p, ignore_s, pds);
             DataSource = *pds;
         } else {
diff --git a/psi/zfcid1.c b/psi/zfcid1.c
index ef3ece0..e3643a0 100644
--- a/psi/zfcid1.c
+++ b/psi/zfcid1.c
@@ -347,11 +347,17 @@ zbuildfont11(i_ctx_t *i_ctx_p)
     ref rcidmap, ignore_gdir, file, *pfile, cfnstr, *pCIDFontName, CIDFontName, *t;
     ulong loca_glyph_pos[2][2];
     int code = cid_font_data_param(op, &common, &ignore_gdir);
+    if (code < 0)
+        return code;
 
-    if (code < 0 ||
-        (code = dict_find_string(op, "CIDFontName", &pCIDFontName)) <= 0 ||
-        (code = dict_int_param(op, "MetricsCount", 0, 4, 0, &MetricsCount)) < 0
-        )
+    code = dict_find_string(op, "CIDFontName", &pCIDFontName);
+    if (code <= 0) {
+        if (code == 0)
+            return_error(gs_error_undefined);
+        return code;
+    }
+    code = dict_int_param(op, "MetricsCount", 0, 4, 0, &MetricsCount);
+    if (code < 0)
         return code;
     /*
      * Since build_gs_simple_font may resize the dictionary and cause
diff --git a/psi/zicc.c b/psi/zicc.c
index ebf25fe..53bdf34 100644
--- a/psi/zicc.c
+++ b/psi/zicc.c
@@ -261,6 +261,8 @@ zset_outputintent(i_ctx_t * i_ctx_p)
     code = dict_find_string(op, "N", &pnval);
     if (code < 0)
         return code;
+    if (code == 0)
+        return_error(gs_error_undefined);
     ncomps = pnval->value.intval;
 
     /* verify the DataSource entry. Creat profile from stream */
@@ -491,6 +493,8 @@ znumicc_components(i_ctx_t * i_ctx_p)
     code = dict_find_string(op, "N", &pnval);
     if (code < 0)
         return code;
+    if (code == 0)
+        return_error(gs_error_undefined);
     ncomps = pnval->value.intval;
     /* verify the DataSource entry. Create profile from stream */
     if (dict_find_string(op, "DataSource", &pstrmval) <= 0)
diff --git a/psi/zpdf_r6.c b/psi/zpdf_r6.c
index bcd4907..992f316 100644
--- a/psi/zpdf_r6.c
+++ b/psi/zpdf_r6.c
@@ -145,21 +145,36 @@ zcheck_r6_password(i_ctx_t * i_ctx_p)
         return_error(gs_error_typecheck);
     
     code = dict_find_string(CryptDict, "O", &Oref);
-    if (code < 0 || !r_has_type(Oref, t_string)) {
+    if (code < 0)
+        return code;
+    if (code == 0)
+        return_error(gs_error_undefined);
+    if (!r_has_type(Oref, t_string))
       return_error(gs_error_typecheck);
-    }
+
     code = dict_find_string(CryptDict, "OE", &OEref);
-    if (code < 0 || !r_has_type(OEref, t_string)) {
+    if (code < 0)
+        return code;
+    if (code == 0)
+        return_error(gs_error_undefined);
+    if (!r_has_type(OEref, t_string))
       return_error(gs_error_typecheck);
-    }
+
     code = dict_find_string(CryptDict, "U", &Uref);
-    if (code < 0 || !r_has_type(Uref, t_string)) {
+    if (code < 0)
+        return code;
+    if (code == 0)
+        return_error(gs_error_undefined);
+    if (!r_has_type(Uref, t_string))
       return_error(gs_error_typecheck);
-    }
+
     code = dict_find_string(CryptDict, "UE", &UEref);
-    if (code < 0 || !r_has_type(UEref, t_string)) {
+    if (code < 0)
+        return code;
+    if (code == 0)
+        return_error(gs_error_undefined);
+    if (!r_has_type(UEref, t_string))
       return_error(gs_error_typecheck);
-    }
 
     pop(2);
     op = osp;
diff --git a/psi/ztoken.c b/psi/ztoken.c
index 519cd09..9314d97 100644
--- a/psi/ztoken.c
+++ b/psi/ztoken.c
@@ -356,7 +356,7 @@ ztoken_scanner_options(const ref *upref, int old_options)
         int code = dict_find_string(upref, pnso->pname, &ppcproc);
 
         /* Update the options only if the parameter has changed. */
-        if (code >= 0) {
+        if (code > 0) {
             if (r_has_type(ppcproc, t_null))
                 options &= ~pnso->option;
             else
-- 
2.17.2


From 434753adbe8be5534bfb9b7d91746023e8073d16 Mon Sep 17 00:00:00 2001
From: Ken Sharp <ken.sharp@artifex.com>
Date: Wed, 14 Nov 2018 09:25:13 +0000
Subject: [PATCH 2/3] Bug #700169 - unchecked type

Bug #700169 "Type confusion in setcolorspace"

In seticc() we extract "Name" from a dictionary, if it succeeds we then
use it as a string, without checking the type to see if it is in fact
a string.

Add a check on the type, and add a couple to check that 'N' is an integer
in a few places too.
---
 psi/zicc.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/psi/zicc.c b/psi/zicc.c
index 53bdf34..dbd2562 100644
--- a/psi/zicc.c
+++ b/psi/zicc.c
@@ -76,7 +76,7 @@ int seticc(i_ctx_t * i_ctx_p, int ncomps, ref *ICCdict, float *range_buff)
         want to have this buffer. */
     /* Check if we have the /Name entry.  This is used to associate with
        specs that have enumerated types to indicate sRGB sGray etc */
-    if (dict_find_string(ICCdict, "Name", &pnameval) > 0){
+    if (dict_find_string(ICCdict, "Name", &pnameval) > 0 && r_has_type(pnameval, t_string)){
         uint size = r_size(pnameval);
         char *str = (char *)gs_alloc_bytes(gs_gstate_memory(igs), size+1, "seticc");
         memcpy(str, (const char *)pnameval->value.bytes, size);
@@ -263,6 +263,8 @@ zset_outputintent(i_ctx_t * i_ctx_p)
         return code;
     if (code == 0)
         return_error(gs_error_undefined);
+    if (r_type(pnval) != t_integer)
+        return gs_note_error(gs_error_typecheck);
     ncomps = pnval->value.intval;
 
     /* verify the DataSource entry. Creat profile from stream */
@@ -495,6 +497,8 @@ znumicc_components(i_ctx_t * i_ctx_p)
         return code;
     if (code == 0)
         return_error(gs_error_undefined);
+    if (r_type(pnval) != t_integer)
+        return gs_note_error(gs_error_typecheck);
     ncomps = pnval->value.intval;
     /* verify the DataSource entry. Create profile from stream */
     if (dict_find_string(op, "DataSource", &pstrmval) <= 0)
-- 
2.17.2


From 9a1b3ac61761094713f44dedfce56013308a3b1d Mon Sep 17 00:00:00 2001
From: Ken Sharp <ken.sharp@artifex.com>
Date: Wed, 14 Nov 2018 09:31:10 +0000
Subject: [PATCH 3/3] PS interpreter - add some type checking

These were 'probably' safe anyway, since they mostly treat the objects
as integers without checking, which at least can't result in a crash.

Nevertheless, we ought to check.

The return from comparedictkeys could be wrong if one of the keys had
a value which was not an array, it could incorrectly decide the two
were in fact the same.
---
 psi/zbfont.c  | 15 +++++++++------
 psi/zcolor.c  | 24 +++++++++++++++++++++++-
 psi/zcrd.c    |  4 +++-
 psi/zfjpx.c   |  2 ++
 psi/zfont.c   |  3 +++
 psi/zfont0.c  |  3 +++
 psi/zimage3.c |  2 ++
 psi/ztrans.c  |  4 ++++
 8 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/psi/zbfont.c b/psi/zbfont.c
index c1d0461..5b830a2 100644
--- a/psi/zbfont.c
+++ b/psi/zbfont.c
@@ -666,6 +666,9 @@ sub_font_params(gs_memory_t *mem, const ref *op, gs_matrix *pmat, gs_matrix *pom
         return_error(gs_error_invalidfont);
     if (dict_find_string(op, "OrigFont", &porigfont) <= 0)
         porigfont = NULL;
+    if (porigfont != NULL && !r_has_type(porigfont, t_dictionary))
+        return_error(gs_error_typecheck);
+
     if (pomat!= NULL) {
         if (porigfont == NULL ||
             dict_find_string(porigfont, "FontMatrix", &pmatrix) <= 0 ||
@@ -676,8 +679,8 @@ sub_font_params(gs_memory_t *mem, const ref *op, gs_matrix *pmat, gs_matrix *pom
     /* Use the FontInfo/OrigFontName key preferrentially (created by MS PSCRIPT driver) */
     if ((dict_find_string((porigfont != NULL ? porigfont : op), "FontInfo", &pfontinfo) > 0) &&
         r_has_type(pfontinfo, t_dictionary) &&
-        (dict_find_string(pfontinfo, "OrigFontName", &pfontname) > 0)) {
-        if ((dict_find_string(pfontinfo, "OrigFontStyle", &pfontstyle) > 0) &&
+        (dict_find_string(pfontinfo, "OrigFontName", &pfontname) > 0) && (r_has_type(pfontname, t_name) || r_has_type(pfontname, t_string))) {
+        if ((dict_find_string(pfontinfo, "OrigFontStyle", &pfontstyle) > 0) && (r_has_type(pfontname, t_name) || r_has_type(pfontname, t_string)) &&
                 r_size(pfontstyle) > 0) {
             const byte *tmpStr1 = pfontname->value.const_bytes;
             const byte *tmpStr2 = pfontstyle->value.const_bytes;
@@ -775,11 +778,11 @@ build_gs_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font ** ppfont, font_type ftype,
             avm_space useglob = r_is_local(pencoding) ? avm_local : avm_global;
 
             ialloc_set_space(idmemory, useglob);
-            
+
             count = r_size(pencoding);
             if ((code = ialloc_ref_array(&penc, (r_type_attrs(pencoding) & a_readonly), count, "build_gs_font")) < 0)
                  return code;
-            
+
             while (count--) {
                ref r;
                if (array_get(imemory, pencoding, count, &r) < 0){
@@ -790,7 +793,7 @@ build_gs_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font ** ppfont, font_type ftype,
                    ref_assign(&(penc.value.refs[count]), &r);
                }
                else {
-               
+
                    if ((code = obj_cvs(imemory, &r, (byte *)buf, 32, &size, (const byte **)(&bptr))) < 0) {
                        return(code);
                    }
@@ -799,7 +802,7 @@ build_gs_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font ** ppfont, font_type ftype,
                    ref_assign(&(penc.value.refs[count]), &r);
                }
             }
-            
+
             if ((code = dict_put_string(osp, "Encoding", &penc, NULL)) < 0)
                return code;
             ialloc_set_space(idmemory, curglob);
diff --git a/psi/zcolor.c b/psi/zcolor.c
index fe81e79..b69b8f5 100644
--- a/psi/zcolor.c
+++ b/psi/zcolor.c
@@ -1877,7 +1877,12 @@ static int comparedictkey(i_ctx_t * i_ctx_p, ref *CIEdict1, ref *CIEdict2, char
     if (r_type(tempref1) == t_null)
         return 1;
 
-    return comparearrays(i_ctx_p, tempref1, tempref2);
+    code = comparearrays(i_ctx_p, tempref1, tempref2);
+
+    if (code > 0)
+        return 1;
+    else
+        return 0;
 }
 
 static int hasharray(i_ctx_t * i_ctx_p, ref *m1, gs_md5_state_t *md5)
@@ -5473,6 +5478,9 @@ static int seticcspace(i_ctx_t * i_ctx_p, ref *r, int *stage, int *cont, int CIE
                     return code;
                 if (code == 0)
                     return gs_note_error(gs_error_undefined);
+                if (r_type(tempref) != t_integer)
+                    return gs_note_error(gs_error_typecheck);
+
                 components = tempref->value.intval;
                 if (components > count_of(range)/2)
                     return_error(gs_error_rangecheck);
@@ -5584,6 +5592,10 @@ static int iccompareproc(i_ctx_t *i_ctx_p, ref *space, ref *testspace)
     /* Need to check all the various parts */
     code1 = dict_find_string(&ICCdict1, "N", &tempref1);
     code2 = dict_find_string(&ICCdict2, "N", &tempref2);
+
+    if (!r_has_type(tempref1, t_integer) || !r_has_type(tempref2, t_integer))
+        return 0;
+
     if (code1 != code2)
         return 0;
     if (tempref1->value.intval != tempref2->value.intval)
@@ -5737,6 +5749,8 @@ static int iccalternatespace(i_ctx_t * i_ctx_p, ref *space, ref **r, int *CIESub
         return code;
     if (code == 0)
         return gs_note_error(gs_error_undefined);
+    if (!r_has_type(tempref, t_integer))
+        return_error(gs_error_typecheck);
 
     components = tempref->value.intval;
 
@@ -5775,6 +5789,9 @@ static int icccomponents(i_ctx_t * i_ctx_p, ref *space, int *n)
         return code;
     if (code == 0)
         return gs_note_error(gs_error_undefined);
+    if (!r_has_type(tempref, t_integer))
+        return gs_note_error(gs_error_typecheck);
+
     *n = tempref->value.intval;
     return 0;
 }
@@ -5791,6 +5808,9 @@ static int iccdomain(i_ctx_t * i_ctx_p, ref *space, float *ptr)
         return code;
     if (code == 0)
         return gs_note_error(gs_error_undefined);
+    if (!r_has_type(tempref, t_integer))
+        return gs_note_error(gs_error_typecheck);
+
     components = tempref->value.intval;
     code = dict_find_string(&ICCdict, "Range", &tempref);
     if (code > 0 && !r_has_type(tempref, t_null)) {
@@ -5824,6 +5844,8 @@ static int iccrange(i_ctx_t * i_ctx_p, ref *space, float *ptr)
         return code;
     if (code == 0)
         return gs_note_error(gs_error_undefined);
+    if (!r_has_type(tempref, t_integer))
+        return gs_note_error(gs_error_typecheck);
     components = tempref->value.intval;
     code = dict_find_string(&ICCdict, "Range", &tempref);
     if (code > 0 && !r_has_type(tempref, t_null)) {
diff --git a/psi/zcrd.c b/psi/zcrd.c
index 7993b15..d58160d 100644
--- a/psi/zcrd.c
+++ b/psi/zcrd.c
@@ -231,8 +231,10 @@ zcrd1_params(os_ptr op, gs_cie_render * pcrd,
         return code;
 
     if (dict_find_string(op, "RenderTable", &pRT) > 0) {
-        const ref *prte = pRT->value.const_refs;
+        const ref *prte;
 
+        check_read_type(*pRT, t_array);
+        prte = pRT->value.const_refs;
         /* Finish unpacking and checking the RenderTable parameter. */
         check_type_only(prte[4], t_integer);
         if (!(prte[4].value.intval == 3 || prte[4].value.intval == 4))
diff --git a/psi/zfjpx.c b/psi/zfjpx.c
index c622f48..db1fae2 100644
--- a/psi/zfjpx.c
+++ b/psi/zfjpx.c
@@ -115,6 +115,8 @@ z_jpx_decode(i_ctx_t * i_ctx_p)
                                 dict_find_string(csdict, "N", &nref) > 0) {
                           if_debug1m('w', imemory, "[w] JPX image has an external %"PRIpsint
                                      " channel colorspace\n", nref->value.intval);
+                          if (r_type(nref) != t_integer)
+                              return gs_note_error(gs_error_typecheck);
                           switch (nref->value.intval) {
                             case 1: state.colorspace = gs_jpx_cs_gray;
                                 break;
diff --git a/psi/zfont.c b/psi/zfont.c
index 9c51792..f6c5ae1 100644
--- a/psi/zfont.c
+++ b/psi/zfont.c
@@ -596,6 +596,9 @@ zfont_info(gs_font *font, const gs_point *pscale, int members,
         info->members |= FONT_INFO_FULL_NAME;
     if ((members & FONT_INFO_EMBEDDING_RIGHTS)
         && (dict_find_string(pfontinfo, "FSType", &pvalue) > 0)) {
+        if (r_type(pvalue) != t_integer)
+            return gs_note_error(gs_error_typecheck);
+
         info->EmbeddingRights = pvalue->value.intval;
         info->members |= FONT_INFO_EMBEDDING_RIGHTS;
     }
diff --git a/psi/zfont0.c b/psi/zfont0.c
index 4b01c20..a179d7b 100644
--- a/psi/zfont0.c
+++ b/psi/zfont0.c
@@ -243,6 +243,9 @@ zbuildfont0(i_ctx_t *i_ctx_p)
         array_get(pfont->memory, &fdepvector, i, &fdep);
         /* The lookup can't fail, because of the pre-check above. */
         dict_find_string(&fdep, "FID", &pfid);
+        if (!r_has_type(pfid, t_fontID))
+            return gs_note_error(gs_error_typecheck);
+
         data.FDepVector[i] = r_ptr(pfid, gs_font);
     }
     pfont->data = data;
diff --git a/psi/zimage3.c b/psi/zimage3.c
index 87a3dce..2beda9f 100644
--- a/psi/zimage3.c
+++ b/psi/zimage3.c
@@ -53,6 +53,8 @@ zimage3(i_ctx_t *i_ctx_p)
         dict_find_string(op, "MaskDict", &pMaskDict) <= 0
         )
         return_error(gs_error_rangecheck);
+    check_type(*pDataDict, t_dictionary);
+    check_type(*pMaskDict, t_dictionary);
     if ((code = pixel_image_params(i_ctx_p, pDataDict,
                         (gs_pixel_image_t *)&image, &ip_data,
                         12, false, gs_currentcolorspace(igs))) < 0 ||
diff --git a/psi/ztrans.c b/psi/ztrans.c
index 64defda..0550a10 100644
--- a/psi/ztrans.c
+++ b/psi/ztrans.c
@@ -417,6 +417,7 @@ zimage3x(i_ctx_t *i_ctx_p)
     gs_image3x_t_init(&image, NULL);
     if (dict_find_string(op, "DataDict", &pDataDict) <= 0)
         return_error(gs_error_rangecheck);
+    check_type(*pDataDict, t_dictionary);
     if ((code = pixel_image_params(i_ctx_p, pDataDict,
                    (gs_pixel_image_t *)&image, &ip_data,
                    16, false, gs_currentcolorspace(igs))) < 0 ||
@@ -453,6 +454,9 @@ image_params *pip_data, const char *dict_name,
 
     if (dict_find_string(op, dict_name, &pMaskDict) <= 0)
         return 1;
+    if (!r_has_type(pMaskDict, t_dictionary))
+        return gs_note_error(gs_error_typecheck);
+
     if ((mcode = code = data_image_params(mem, pMaskDict, &pixm->MaskDict,
                                           &ip_mask, false, 1, 16, false, false)) < 0 ||
         (code = dict_int_param(pMaskDict, "ImageType", 1, 1, 0, &ignored)) < 0 ||
-- 
2.17.2