Blame SOURCES/ghostscript-cve-2019-6116.patch

483aca
From 30cd347f37bfb293ffdc407397d1023628400b81 Mon Sep 17 00:00:00 2001
483aca
From: Ken Sharp <ken.sharp@artifex.com>
483aca
Date: Mon, 15 Oct 2018 13:35:15 +0100
483aca
Subject: [PATCH 1/6] font parsing - prevent SEGV in .cffparse
483aca
483aca
Bug #699961 "currentcolortransfer procs crash .parsecff"
483aca
483aca
zparsecff checked the operand for being an array (and not a packed
483aca
array) but the returned procedures from the default currentcolortransfer
483aca
are arrays, not packed arrays. This led to the code trying to
483aca
dereference a NULL pointer.
483aca
483aca
Add a specific check for the 'refs' pointer being NULL before we try
483aca
to use it.
483aca
483aca
Additionally, make the StartData procedure in the CFF Font Resource
483aca
executeonly to prevent pulling the hidden .parsecff operator out and
483aca
using it. Finally, extend this to other resource types.
483aca
---
483aca
 Resource/Init/gs_cff.ps   |  4 +--
483aca
 Resource/Init/gs_cidcm.ps |  6 ++--
483aca
 Resource/Init/gs_ciddc.ps |  4 +--
483aca
 Resource/Init/gs_cmap.ps  |  2 +-
483aca
 Resource/Init/gs_res.ps   | 60 +++++++++++++++++++--------------------
483aca
 psi/zfont2.c              |  4 +++
483aca
 6 files changed, 42 insertions(+), 38 deletions(-)
483aca
483aca
diff --git a/Resource/Init/gs_cff.ps b/Resource/Init/gs_cff.ps
483aca
index 20c35a5..b60e374 100644
483aca
--- a/Resource/Init/gs_cff.ps
483aca
+++ b/Resource/Init/gs_cff.ps
483aca
@@ -199,7 +199,7 @@ def
483aca
 % ordinary CFF font.
483aca
 /StartData {          % <resname> <nbytes> StartData -
483aca
   currentfile exch subfilefilter //false //false ReadData pop
483aca
-} bind def
483aca
+} bind executeonly def
483aca
 /ReadData {           % <resname> <file> <forceresname> <forcecid> ReadData <fontset>
483aca
         % Initialize.
483aca
 
483aca
@@ -234,7 +234,7 @@ def
483aca
   end		% FontSetInit ProcSet
483aca
   /FontSet defineresource
483aca
 
483aca
-} bind def
483aca
+} bind executeonly def
483aca
 
483aca
 % ---------------- Resource category definition ---------------- %
483aca
 
483aca
diff --git a/Resource/Init/gs_cidcm.ps b/Resource/Init/gs_cidcm.ps
483aca
index 0201ea8..60b0fdb 100644
483aca
--- a/Resource/Init/gs_cidcm.ps
483aca
+++ b/Resource/Init/gs_cidcm.ps
483aca
@@ -327,7 +327,7 @@ currentdict end def
483aca
       //FindResource exec
483aca
     } ifelse
483aca
   } ifelse
483aca
-} bind def
483aca
+} bind executeonly def
483aca
 
483aca
 /ResourceStatus {  % <InstName> ResourceStatus <nStatus> <nSize> true
483aca
                    % <InstName> ResourceStatus false
483aca
@@ -359,7 +359,7 @@ currentdict end def
483aca
       //false
483aca
     } ifelse
483aca
   } ifelse
483aca
-} bind def
483aca
+} bind executeonly def
483aca
 
483aca
 /ResourceForAll { % <template> <proc> <scratch> ResourceForAll -
483aca
 
483aca
@@ -440,7 +440,7 @@ currentdict end def
483aca
 
483aca
   % Make the enumerator and apply it :
483aca
   /MappedCategoryRedefiner /ProcSet findresource /MakeResourceEnumerator get exec exec
483aca
-} bind def
483aca
+} bind executeonly def
483aca
 
483aca
 currentdict end /Font exch /Category defineresource pop
483aca
 end
483aca
diff --git a/Resource/Init/gs_ciddc.ps b/Resource/Init/gs_ciddc.ps
483aca
index 54c6876..f83e960 100644
483aca
--- a/Resource/Init/gs_ciddc.ps
483aca
+++ b/Resource/Init/gs_ciddc.ps
483aca
@@ -204,7 +204,7 @@ begin
483aca
     exch pop begin                                   %
483aca
     .GetCIDDecoding
483aca
     end
483aca
-  } bind def
483aca
+  } bind executeonly def
483aca
 
483aca
   /FindResource      % <name> FindResource <dict>
483aca
   { currentglobal exch                               % bGlobal /InstName
483aca
@@ -212,7 +212,7 @@ begin
483aca
     dup //.MakeInstance exec                         % bGlobal /InstName <Inst>
483aca
     DefineResource                                   % bGlobal <Inst>
483aca
     exch setglobal                                   % <Inst>
483aca
-  } bind def
483aca
+  } bind executeonly def
483aca
 
483aca
 currentdict end
483aca
 /CIDDecoding exch /Category defineresource pop
483aca
diff --git a/Resource/Init/gs_cmap.ps b/Resource/Init/gs_cmap.ps
483aca
index 63c023b..a01afc2 100644
483aca
--- a/Resource/Init/gs_cmap.ps
483aca
+++ b/Resource/Init/gs_cmap.ps
483aca
@@ -536,7 +536,7 @@ dup /DefineResource {
483aca
   } if
483aca
   dup /CodeMap .knownget { //null eq { .buildcmap } if } if
483aca
   /Generic /Category findresource /DefineResource get exec
483aca
-} bind put
483aca
+} bind executeonly put
483aca
 /Category defineresource pop
483aca
         % We might have loaded CID font support already.
483aca
 /CIDInit /ProcSet 2 copy { findresource } .internalstopped
483aca
diff --git a/Resource/Init/gs_res.ps b/Resource/Init/gs_res.ps
483aca
index d1e10c9..9bdb8ff 100644
483aca
--- a/Resource/Init/gs_res.ps
483aca
+++ b/Resource/Init/gs_res.ps
483aca
@@ -155,10 +155,10 @@ setglobal
483aca
         } {
483aca
           /defineresource cvx /typecheck signaloperror
483aca
         } ifelse
483aca
-} bind def
483aca
+} bind executeonly def
483aca
 /FindResource		% (redefined below)
483aca
         { .Instances exch get 0 get
483aca
-        } bind def
483aca
+        } bind executeonly def
483aca
 
483aca
                 % Additional entries
483aca
 
483aca
@@ -210,7 +210,7 @@ def
483aca
       /findresource .systemvar /typecheck signalerror
483aca
     } if
483aca
     /findresource cvx //.findresource .errorexec
483aca
-} odef
483aca
+} bind executeonly odef
483aca
 
483aca
 /defineresource {	% <key> <instance> <category> defineresource <instance>
483aca
     2 .argindex 2 index 2 index	% catch stackunderflow
483aca
@@ -226,7 +226,7 @@ def
483aca
         /DefineResource .resourceexec
483aca
         4 1 roll pop pop pop
483aca
     } .errorexec
483aca
-} bind odef
483aca
+} bind executeonly odef
483aca
 % We must prevent resourceforall from automatically restoring the stacks,
483aca
 % because we don't want the stacks restored if proc causes an error or
483aca
 % executes a 'stop'. On the other hand, resourceforall is defined in the
483aca
@@ -240,10 +240,10 @@ def
483aca
         % Stack: <template> <proc> <scratch> <category> proc
483aca
         exch pop		% pop the category
483aca
         exec end
483aca
-} bind def
483aca
+} bind executeonly def
483aca
 /resourceforall {	% <template> <proc> <scratch> <category> resourceforall1 -
483aca
         //resourceforall1 exec		% see above
483aca
-} bind odef
483aca
+} bind executeonly odef
483aca
 /resourcestatus {	% <key> <category> resourcestatus <status> <size> true
483aca
                         % <key> <category> resourcestatus false
483aca
   {
483aca
@@ -259,7 +259,7 @@ def
483aca
     % for error reporting. CET 23-26
483aca
     /resourcestatus cvx $error /errorname get signalerror
483aca
   } if
483aca
-} bind odef
483aca
+} bind executeonly odef
483aca
 /undefineresource {	% <key> <category> undefineresource -
483aca
   0 .argindex type /nametype ne {
483aca
     /undefinedresource cvx /typecheck signaloperror
483aca
@@ -272,7 +272,7 @@ def
483aca
     % here but uses operator for the errors above. CET 23-33
483aca
     /undefineresource cvx $error /errorname get signalerror
483aca
   } if
483aca
-} bind odef
483aca
+} bind executeonly odef
483aca
 
483aca
 % Define the system parameters used for the Generic implementation of
483aca
 % ResourceFileName.
483aca
@@ -457,7 +457,7 @@ status {
483aca
            { 2 copy .Instances exch exec
483aca
            }
483aca
           if .LocalInstances exch exec
483aca
-        } bind
483aca
+        } bind executeonly
483aca
 % Because of some badly designed code in Adobe's CID font downloader that
483aca
 % makes findresource and resourcestatus deliberately inconsistent with each
483aca
 % other, the default FindResource must not call ResourceStatus if there is
483aca
@@ -483,7 +483,7 @@ status {
483aca
            /findresource cvx .undefinedresource
483aca
           } ifelse
483aca
         } ifelse
483aca
-} bind
483aca
+} bind executeonly
483aca
 % Because of some badly designed code in Adobe's CID font downloader, the
483aca
 % definition of ResourceStatus for Generic and Font must be the same (!).
483aca
 % We patch around this by using an intermediate .ResourceFileStatus procedure.
483aca
@@ -493,10 +493,10 @@ status {
483aca
         } {
483aca
           .ResourceFileStatus
483aca
         } ifelse
483aca
-} bind
483aca
+} bind executeonly
483aca
 /.ResourceFileStatus {
483aca
         .ResourceFile { closefile 2 -1 //true } { pop //false } ifelse
483aca
-} bind
483aca
+} bind executeonly
483aca
 /ResourceForAll {
483aca
                 % Construct a new procedure to hold the arguments.
483aca
                 % All objects constructed here must be in local VM to avoid
483aca
@@ -554,7 +554,7 @@ status {
483aca
         3 2 roll pop % args
483aca
         { forall } 0 get
483aca
         currentdict end 2 .execn begin
483aca
-} bind
483aca
+} bind executeonly
483aca
 
483aca
 /ResourceFileName  {                          % /in (scr) --> (p/c/n)
483aca
   exch //.rfnstring cvs                       % (scr) (n)
483aca
@@ -586,7 +586,7 @@ status {
483aca
     ifelse
483aca
   } ifelse
483aca
   exch copy                                   % (p/c/n)
483aca
-} bind
483aca
+} bind executeonly
483aca
 
483aca
                 % Additional entries
483aca
 
483aca
@@ -752,17 +752,17 @@ counttomark 2 idiv
483aca
              ifelse
483aca
            }
483aca
           ifelse
483aca
-        } bind
483aca
+        } bind executeonly
483aca
    /UndefineResource
483aca
-        { /undefineresource cvx /invalidaccess signaloperror } bind
483aca
+        { /undefineresource cvx /invalidaccess signaloperror } bind executeonly
483aca
    /FindResource
483aca
         { .Instances 1 index .knownget
483aca
            { exch pop }
483aca
            { /findresource cvx .undefinedresource }
483aca
           ifelse
483aca
-        } bind
483aca
+        } bind executeonly
483aca
    /ResourceStatus
483aca
-        { .Instances exch known { 0 0 //true } { //false } ifelse } bind
483aca
+        { .Instances exch known { 0 0 //true } { //false } ifelse } bind executeonly
483aca
    /ResourceForAll
483aca
         /Generic .findcategory /ResourceForAll load end
483aca
 
483aca
@@ -865,7 +865,7 @@ userdict /.localcsdefaults //false put
483aca
     1 index .definedefaultcs
483aca
     currentglobal not { .userdict /.localcsdefaults //true put } if
483aca
   } if
483aca
-} bind
483aca
+} bind executeonly
483aca
 
483aca
 /UndefineResource {
483aca
   dup /Generic /Category findresource /UndefineResource get exec
483aca
@@ -888,7 +888,7 @@ userdict /.localcsdefaults //false put
483aca
   } {
483aca
     pop
483aca
   } ifelse
483aca
-} bind
483aca
+} bind executeonly
483aca
 
483aca
 .definecategory			% ColorSpace
483aca
 
483aca
@@ -918,7 +918,7 @@ userdict /.localcsdefaults //false put
483aca
     { exch copy exch pop }
483aca
     { /Generic /Category findresource /ResourceFileName get exec }
483aca
    ifelse
483aca
- } bind
483aca
+ } bind executeonly
483aca
 
483aca
 .definecategory			% Encoding
483aca
 
483aca
@@ -991,11 +991,11 @@ currentdict /.fontstatusaux .undef
483aca
 /DefineResource
483aca
         { 2 copy //definefont exch pop
483aca
           /Generic /Category findresource /DefineResource get exec
483aca
-        } bind
483aca
+        } bind executeonly
483aca
 /UndefineResource
483aca
         { dup //undefinefont
483aca
           /Generic /Category findresource /UndefineResource get exec
483aca
-        } bind
483aca
+        } bind executeonly
483aca
 /FindResource {
483aca
         dup .getvminstance {
483aca
           exch pop 0 get
483aca
@@ -1006,14 +1006,14 @@ currentdict /.fontstatusaux .undef
483aca
             .loadfontresource
483aca
           } ifelse
483aca
         } ifelse
483aca
-} bind
483aca
+} bind executeonly
483aca
 /ResourceForAll {
483aca
         { .scannextfontdir not { exit } if } loop
483aca
         /Generic /Category findresource /ResourceForAll get exec
483aca
-} bind
483aca
+} bind executeonly
483aca
 /.ResourceFileStatus {
483aca
         .fontstatus { pop 2 -1 //true } { pop //false } ifelse
483aca
-} bind
483aca
+} bind executeonly
483aca
 
483aca
 /.loadfontresource {
483aca
         dup .vmused exch
483aca
@@ -1063,20 +1063,20 @@ end
483aca
   { /Font defineresource } stopped {
483aca
       /definefont cvx $error /errorname get signalerror
483aca
   } if
483aca
-} bind odef
483aca
+} bind executeonly odef
483aca
 /undefinefont {
483aca
   /Font undefineresource
483aca
-} bind odef
483aca
+} bind executeonly odef
483aca
 % The Red Book requires that findfont be a procedure, not an operator,
483aca
 % but it still needs to restore the stacks reliably if it fails.
483aca
 /.findfontop {
483aca
   { /Font findresource } stopped {
483aca
     pop /findfont $error /errorname get signalerror
483aca
   } if
483aca
-} bind odef
483aca
+} bind executeonly odef
483aca
 /findfont {
483aca
   .findfontop
483aca
-} bind def	% Must be a procedure, not an operator
483aca
+} bind executeonly def	% Must be a procedure, not an operator
483aca
 
483aca
 % Remove initialization utilities.
483aca
 currentdict /.definecategory .undef
483aca
diff --git a/psi/zfont2.c b/psi/zfont2.c
483aca
index bed6c81..3123f19 100644
483aca
--- a/psi/zfont2.c
483aca
+++ b/psi/zfont2.c
483aca
@@ -2745,9 +2745,13 @@ zparsecff(i_ctx_t *i_ctx_p)
483aca
     ref blk_wrap[1];
483aca
 
483aca
     check_read(*op);
483aca
+
483aca
     if (r_has_type(op, t_array)) {  /* no packedarrays */
483aca
         int i, blk_sz, blk_cnt;
483aca
 
483aca
+        if (op->value.refs == NULL)
483aca
+            return_error(gs_error_typecheck);
483aca
+
483aca
         data.blk_ref = op->value.refs;
483aca
         blk_cnt  = r_size(op);
483aca
         blk_sz = r_size(data.blk_ref);
483aca
-- 
483aca
2.17.2
483aca
483aca
483aca
From 8e18fcdaa2e2247363c4cc8f851f3096cc5756fa Mon Sep 17 00:00:00 2001
483aca
From: Chris Liddell <chris.liddell@artifex.com>
483aca
Date: Fri, 19 Oct 2018 13:14:24 +0100
483aca
Subject: [PATCH 2/6] "Hide" a final use of a .force* operator
483aca
483aca
There was one use of .forceput remaining that was in a regular procedure
483aca
rather than being "hidden" behind an operator.
483aca
483aca
In this case, it's buried in the resource machinery, and hard to access (I
483aca
would not be confident in claiming it was impossible). This ensures it's
483aca
not accessible.
483aca
---
483aca
 Resource/Init/gs_res.ps | 6 +++---
483aca
 1 file changed, 3 insertions(+), 3 deletions(-)
483aca
483aca
diff --git a/Resource/Init/gs_res.ps b/Resource/Init/gs_res.ps
483aca
index 9bdb8ff..8eb8bb0 100644
483aca
--- a/Resource/Init/gs_res.ps
483aca
+++ b/Resource/Init/gs_res.ps
483aca
@@ -155,7 +155,7 @@ setglobal
483aca
         } {
483aca
           /defineresource cvx /typecheck signaloperror
483aca
         } ifelse
483aca
-} bind executeonly def
483aca
+} bind executeonly odef
483aca
 /FindResource		% (redefined below)
483aca
         { .Instances exch get 0 get
483aca
         } bind executeonly def
483aca
@@ -412,7 +412,7 @@ status {
483aca
   } ifelse
483aca
 } bind def
483aca
 
483aca
-/DefineResource {
483aca
+/DefineResource dup {
483aca
         .CheckResource
483aca
            { dup [ exch 0 -1 ]
483aca
                         % Stack: key value instance
483aca
@@ -441,7 +441,7 @@ status {
483aca
            { /defineresource cvx /typecheck signaloperror
483aca
            }
483aca
         ifelse
483aca
-} .bind executeonly		% executeonly to prevent access to .forcedef
483aca
+} .bind executeonly .makeoperator		% executeonly to prevent access to .forcedef
483aca
 /UndefineResource
483aca
         {  { dup 2 index .knownget
483aca
               { dup 1 get 1 ge
483aca
-- 
483aca
2.17.2
483aca
483aca
483aca
From 13b0a36f8181db66a91bcc8cea139998b53a8996 Mon Sep 17 00:00:00 2001
483aca
From: Chris Liddell <chris.liddell@artifex.com>
483aca
Date: Wed, 5 Dec 2018 12:22:13 +0000
483aca
Subject: [PATCH 3/6] Sanitize op stack for error conditions
483aca
483aca
We save the stacks to an array and store the array for the error handler to
483aca
access.
483aca
483aca
For SAFER, we traverse the array, and deep copy any op arrays (procedures). As
483aca
we make these copies, we check for operators that do *not* exist in systemdict,
483aca
when we find one, we replace the operator with a name object (of the form
483aca
"/--opname--").
483aca
---
483aca
 psi/int.mak  |  3 +-
483aca
 psi/interp.c |  8 ++++++
483aca
 psi/istack.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++
483aca
 psi/istack.h |  3 ++
483aca
 4 files changed, 91 insertions(+), 1 deletion(-)
483aca
483aca
diff --git a/psi/int.mak b/psi/int.mak
483aca
index 6ab5bf0..6b349cb 100644
483aca
--- a/psi/int.mak
483aca
+++ b/psi/int.mak
483aca
@@ -204,7 +204,8 @@ $(PSOBJ)iparam.$(OBJ) : $(PSSRC)iparam.c $(GH)\
483aca
 $(PSOBJ)istack.$(OBJ) : $(PSSRC)istack.c $(GH) $(memory__h)\
483aca
  $(ierrors_h) $(gsstruct_h) $(gsutil_h)\
483aca
  $(ialloc_h) $(istack_h) $(istkparm_h) $(istruct_h) $(iutil_h) $(ivmspace_h)\
483aca
- $(store_h) $(INT_MAK) $(MAKEDIRS)
483aca
+ $(store_h) $(icstate_h) $(iname_h) $(dstack_h) $(idict_h) \
483aca
+ $(INT_MAK) $(MAKEDIRS)
483aca
 	$(PSCC) $(PSO_)istack.$(OBJ) $(C_) $(PSSRC)istack.c
483aca
 
483aca
 $(PSOBJ)iutil.$(OBJ) : $(PSSRC)iutil.c $(GH) $(math__h) $(memory__h) $(string__h)\
483aca
diff --git a/psi/interp.c b/psi/interp.c
483aca
index 6dc0dda..aa5779c 100644
483aca
--- a/psi/interp.c
483aca
+++ b/psi/interp.c
483aca
@@ -761,6 +761,7 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, int skip, ref * arr)
483aca
     uint size = ref_stack_count(pstack) - skip;
483aca
     uint save_space = ialloc_space(idmemory);
483aca
     int code, i;
483aca
+    ref *safety, *safe;
483aca
 
483aca
     if (size > 65535)
483aca
         size = 65535;
483aca
@@ -778,6 +779,13 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, int skip, ref * arr)
483aca
                 make_null(&arr->value.refs[i]);
483aca
         }
483aca
     }
483aca
+    if (pstack == &o_stack && dict_find_string(systemdict, "SAFETY", &safety) > 0 &&
483aca
+        dict_find_string(safety, "safe", &safe) > 0 && r_has_type(safe, t_boolean) &&
483aca
+        safe->value.boolval == true) {
483aca
+        code = ref_stack_array_sanitize(i_ctx_p, arr, arr);
483aca
+        if (code < 0)
483aca
+            return code;
483aca
+    }
483aca
     ialloc_set_space(idmemory, save_space);
483aca
     return code;
483aca
 }
483aca
diff --git a/psi/istack.c b/psi/istack.c
483aca
index 8fe151f..f1a3e51 100644
483aca
--- a/psi/istack.c
483aca
+++ b/psi/istack.c
483aca
@@ -27,6 +27,10 @@
483aca
 #include "iutil.h"
483aca
 #include "ivmspace.h"		/* for local/global test */
483aca
 #include "store.h"
483aca
+#include "icstate.h"
483aca
+#include "iname.h"
483aca
+#include "dstack.h"
483aca
+#include "idict.h"
483aca
 
483aca
 /* Forward references */
483aca
 static void init_block(ref_stack_t *pstack, const ref *pblock_array,
483aca
@@ -294,6 +298,80 @@ ref_stack_store_check(const ref_stack_t *pstack, ref *parray, uint count,
483aca
     return 0;
483aca
 }
483aca
 
483aca
+int
483aca
+ref_stack_array_sanitize(i_ctx_t *i_ctx_p, ref *sarr, ref *darr)
483aca
+{
483aca
+    int i, code;
483aca
+    ref obj, arr2;
483aca
+    ref *pobj2;
483aca
+    gs_memory_t *mem = (gs_memory_t *)idmemory->current;
483aca
+
483aca
+    if (!r_is_array(sarr) || !r_has_type(darr, t_array))
483aca
+        return_error(gs_error_typecheck);
483aca
+
483aca
+    for (i = 0; i < r_size(sarr); i++) {
483aca
+        code = array_get(mem, sarr, i, &obj);
483aca
+        if (code < 0)
483aca
+            make_null(&obj);
483aca
+        switch(r_type(&obj)) {
483aca
+          case t_operator:
483aca
+          {
483aca
+            int index = op_index(&obj);
483aca
+
483aca
+            if (index > 0 && index < op_def_count) {
483aca
+                const byte *data = (const byte *)(op_index_def(index)->oname + 1);
483aca
+                if (dict_find_string(systemdict, (const char *)data, &pobj2) <= 0) {
483aca
+                    byte *s = gs_alloc_bytes(mem, strlen((char *)data) + 5, "ref_stack_array_sanitize");
483aca
+                    if (s) {
483aca
+                        s[0] =  '\0';
483aca
+                        strcpy((char *)s, "--");
483aca
+                        strcpy((char *)s + 2, (char *)data);
483aca
+                        strcpy((char *)s + strlen((char *)data) + 2, "--");
483aca
+                    }
483aca
+                    else {
483aca
+                        s = (byte *)data;
483aca
+                    }
483aca
+                    code = name_ref(imemory, s, strlen((char *)s), &obj, 1);
483aca
+                    if (code < 0) make_null(&obj);
483aca
+                    if (s != data)
483aca
+                        gs_free_object(mem, s, "ref_stack_array_sanitize");
483aca
+                }
483aca
+            }
483aca
+            else {
483aca
+                make_null(&obj);
483aca
+            }
483aca
+            ref_assign(darr->value.refs + i, &obj);
483aca
+            break;
483aca
+          }
483aca
+          case t_array:
483aca
+          case t_shortarray:
483aca
+          case t_mixedarray:
483aca
+          {
483aca
+            int attrs = r_type_attrs(&obj) & (a_write | a_read | a_execute | a_executable);
483aca
+            /* We only want to copy executable arrays */
483aca
+            if (attrs & (a_execute | a_executable)) {
483aca
+                code = ialloc_ref_array(&arr2, attrs, r_size(&obj), "ref_stack_array_sanitize");
483aca
+                if (code < 0) {
483aca
+                    make_null(&arr2);
483aca
+                }
483aca
+                else {
483aca
+                    code = ref_stack_array_sanitize(i_ctx_p, &obj, &arr2);
483aca
+                }
483aca
+                ref_assign(darr->value.refs + i, &arr2);
483aca
+            }
483aca
+            else {
483aca
+                ref_assign(darr->value.refs + i, &obj);
483aca
+            }
483aca
+            break;
483aca
+          }
483aca
+          default:
483aca
+            ref_assign(darr->value.refs + i, &obj);
483aca
+        }
483aca
+    }
483aca
+    return 0;
483aca
+}
483aca
+
483aca
+
483aca
 /*
483aca
  * Store the top 'count' elements of a stack, starting 'skip' elements below
483aca
  * the top, into an array, with or without store/undo checking.  age=-1 for
483aca
diff --git a/psi/istack.h b/psi/istack.h
483aca
index 051dcbe..54be405 100644
483aca
--- a/psi/istack.h
483aca
+++ b/psi/istack.h
483aca
@@ -129,6 +129,9 @@ int ref_stack_store(const ref_stack_t *pstack, ref *parray, uint count,
483aca
                     uint skip, int age, bool check,
483aca
                     gs_dual_memory_t *idmem, client_name_t cname);
483aca
 
483aca
+int
483aca
+ref_stack_array_sanitize(i_ctx_t *i_ctx_p, ref *sarr, ref *darr);
483aca
+
483aca
 /*
483aca
  * Pop the top N elements off a stack.
483aca
  * The number must not exceed the number of elements in use.
483aca
-- 
483aca
2.17.2
483aca
483aca
483aca
From 2db98f9c66135601efb103d8db7d020a672308db Mon Sep 17 00:00:00 2001
483aca
From: Chris Liddell <chris.liddell@artifex.com>
483aca
Date: Thu, 13 Dec 2018 15:28:34 +0000
483aca
Subject: [PATCH 4/6] Any transient procedures that call .force* operators
483aca
483aca
(i.e. for conditionals or loops) make them executeonly.
483aca
---
483aca
 Resource/Init/gs_diskn.ps |  2 +-
483aca
 Resource/Init/gs_dps1.ps  |  4 ++--
483aca
 Resource/Init/gs_fntem.ps |  4 ++--
483aca
 Resource/Init/gs_fonts.ps | 12 ++++++------
483aca
 Resource/Init/gs_init.ps  |  4 ++--
483aca
 Resource/Init/gs_lev2.ps  | 11 ++++++-----
483aca
 Resource/Init/gs_pdfwr.ps |  2 +-
483aca
 Resource/Init/gs_res.ps   |  4 ++--
483aca
 Resource/Init/gs_setpd.ps |  2 +-
483aca
 Resource/Init/pdf_base.ps | 13 ++++++++-----
483aca
 Resource/Init/pdf_draw.ps | 16 +++++++++-------
483aca
 Resource/Init/pdf_font.ps |  6 +++---
483aca
 Resource/Init/pdf_main.ps |  4 ++--
483aca
 Resource/Init/pdf_ops.ps  |  7 ++++---
483aca
 14 files changed, 49 insertions(+), 42 deletions(-)
483aca
483aca
diff --git a/Resource/Init/gs_diskn.ps b/Resource/Init/gs_diskn.ps
483aca
index fd694bc..8bf2054 100644
483aca
--- a/Resource/Init/gs_diskn.ps
483aca
+++ b/Resource/Init/gs_diskn.ps
483aca
@@ -51,7 +51,7 @@ systemdict begin
483aca
     mark 5 1 roll ] mark exch { { } forall } forall ]
483aca
     //systemdict /.searchabledevs 2 index .forceput
483aca
     exch .setglobal
483aca
-  }
483aca
+  } executeonly
483aca
   if
483aca
 } .bind executeonly odef % must be bound and hidden for .forceput
483aca
 
483aca
diff --git a/Resource/Init/gs_dps1.ps b/Resource/Init/gs_dps1.ps
483aca
index ec5db61..4fae283 100644
483aca
--- a/Resource/Init/gs_dps1.ps
483aca
+++ b/Resource/Init/gs_dps1.ps
483aca
@@ -78,7 +78,7 @@ level2dict begin
483aca
    .currentglobal
483aca
     {		% Current mode is global; delete from local directory too.
483aca
       //systemdict /LocalFontDirectory .knownget
483aca
-       { 1 index .forceundef }		% LocalFontDirectory is readonly
483aca
+       { 1 index .forceundef } executeonly		% LocalFontDirectory is readonly
483aca
       if
483aca
     }
483aca
     {		% Current mode is local; if there was a shadowed global
483aca
@@ -126,7 +126,7 @@ level2dict begin
483aca
           }
483aca
          ifelse
483aca
        } forall
483aca
-      pop counttomark 2 idiv { .forceundef } repeat pop		% readonly
483aca
+      pop counttomark 2 idiv { .forceundef } executeonly repeat pop		% readonly
483aca
     }
483aca
    if
483aca
    //SharedFontDirectory exch .forcecopynew pop
483aca
diff --git a/Resource/Init/gs_fntem.ps b/Resource/Init/gs_fntem.ps
483aca
index c1f7651..6eb672a 100644
483aca
--- a/Resource/Init/gs_fntem.ps
483aca
+++ b/Resource/Init/gs_fntem.ps
483aca
@@ -401,12 +401,12 @@ currentdict end def
483aca
       .forceput % FontInfo can be read-only.
483aca
       pop                                                        % bool <font>
483aca
       exit
483aca
-    } if
483aca
+    } executeonly if
483aca
     dup /FontInfo get                                            % bool <font> <FI>
483aca
     /GlyphNames2Unicode /Unicode /Decoding findresource
483aca
     .forceput % FontInfo can be read-only.
483aca
     exit
483aca
-  } loop
483aca
+  } executeonly loop
483aca
   exch setglobal
483aca
 } .bind executeonly odef % must be bound and hidden for .forceput
483aca
 
483aca
diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps
483aca
index 052a191..6d2c26b 100644
483aca
--- a/Resource/Init/gs_fonts.ps
483aca
+++ b/Resource/Init/gs_fonts.ps
483aca
@@ -374,7 +374,7 @@ FONTPATH length 0 eq { (%END FONTPATH) .skipeof } if
483aca
 /.setnativefontmapbuilt { % set whether we've been run
483aca
   dup type /booleantype eq {
483aca
       systemdict exch /.nativefontmapbuilt exch .forceput
483aca
-  }
483aca
+  } executeonly
483aca
   {pop}
483aca
   ifelse
483aca
 } .bind executeonly odef
483aca
@@ -1007,11 +1007,11 @@ $error /SubstituteFont { } put
483aca
 { 2 index gcheck currentglobal
483aca
   2 copy eq {
483aca
     pop pop .forceput
483aca
-  } {
483aca
+  } executeonly {
483aca
     5 1 roll setglobal
483aca
     dup length string copy
483aca
     .forceput setglobal
483aca
-  } ifelse
483aca
+  } executeonly ifelse
483aca
 } .bind executeonly odef % must be bound and hidden for .forceput
483aca
 
483aca
 % Attempt to load a font from a file.
483aca
@@ -1084,7 +1084,7 @@ $error /SubstituteFont { } put
483aca
            .FontDirectory 3 index .forceundef		% readonly
483aca
            1 index (r) file .loadfont .FontDirectory exch
483aca
            /.setglobal .systemvar exec
483aca
-         }
483aca
+         } executeonly
483aca
          { .loadfont .FontDirectory
483aca
          }
483aca
         ifelse
483aca
@@ -1105,7 +1105,7 @@ $error /SubstituteFont { } put
483aca
         dup 3 index .fontknownget
483aca
          { dup /PathLoad 4 index //.putgstringcopy
483aca
            4 1 roll pop pop pop //true exit
483aca
-         } if
483aca
+         } executeonly if
483aca
 
483aca
                 % Maybe the file had a different FontName.
483aca
                 % See if we can get a FontName from the file, and if so,
483aca
@@ -1134,7 +1134,7 @@ $error /SubstituteFont { } put
483aca
               ifelse  % Stack: origfontname fontdict
483aca
               exch pop //true exit
483aca
                       % Stack: fontdict
483aca
-            }
483aca
+            } executeonly
483aca
            if pop % Stack: origfontname fontdirectory path
483aca
          }
483aca
         if pop pop  % Stack: origfontname
483aca
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
483aca
index 0b900e6..9015f90 100644
483aca
--- a/Resource/Init/gs_init.ps
483aca
+++ b/Resource/Init/gs_init.ps
483aca
@@ -2347,7 +2347,7 @@ SAFER { .setsafeglobal } if
483aca
         % Update the copy of the user parameters.
483aca
   mark .currentuserparams counttomark 2 idiv {
483aca
     userparams 3 1 roll .forceput	% userparams is read-only
483aca
-  } repeat pop
483aca
+  } executeonly repeat pop
483aca
         % Turn on idiom recognition, if available.
483aca
   currentuserparams /IdiomRecognition known {
483aca
     /IdiomRecognition //true .definepsuserparam
483aca
@@ -2366,7 +2366,7 @@ SAFER { .setsafeglobal } if
483aca
         % Remove real system params from pssystemparams.
483aca
   mark .currentsystemparams counttomark 2 idiv {
483aca
     pop pssystemparams exch .forceundef
483aca
-  } repeat pop
483aca
+  } executeonly repeat pop
483aca
 } if
483aca
 
483aca
 % Set up AlignToPixels :
483aca
diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps
483aca
index a8ed892..b69303d 100644
483aca
--- a/Resource/Init/gs_lev2.ps
483aca
+++ b/Resource/Init/gs_lev2.ps
483aca
@@ -154,7 +154,8 @@ end
483aca
       % protect top level of parameters that we copied
483aca
       dup type dup /arraytype eq exch /stringtype eq or { readonly } if
483aca
       /userparams .systemvar 3 1 roll .forceput  % userparams is read-only
483aca
-    } {
483aca
+    } executeonly
483aca
+    {
483aca
       pop pop
483aca
     } ifelse
483aca
   } forall
483aca
@@ -224,7 +225,7 @@ end
483aca
          % protect top level parameters that we copied
483aca
          dup type dup /arraytype eq exch /stringtype eq or { readonly } if
483aca
          //pssystemparams 3 1 roll .forceput	% pssystemparams is read-only
483aca
-       }
483aca
+       } executeonly
483aca
        { pop pop
483aca
        }
483aca
       ifelse
483aca
@@ -920,7 +921,7 @@ mark
483aca
   dup /PaintProc get
483aca
   1 index /Implementation known not {
483aca
     1 index dup /Implementation //null .forceput readonly pop
483aca
-  } if
483aca
+  } executeonly if
483aca
   exec
483aca
 }.bind odef
483aca
 
483aca
@@ -944,7 +945,7 @@ mark
483aca
   dup /PaintProc get
483aca
   1 index /Implementation known not {
483aca
     1 index dup /Implementation //null .forceput readonly pop
483aca
-  } if
483aca
+  } executeonly if
483aca
   /UNROLLFORMS where {/UNROLLFORMS get}{false}ifelse not
483aca
   %% [CTM] <<Form>> PaintProc .beginform -
483aca
   {
483aca
@@ -991,7 +992,7 @@ mark
483aca
         %% Form dictioanry using the /Implementation key).
483aca
         1 dict dup /FormID 4 -1 roll put
483aca
         1 index exch /Implementation exch .forceput readonly pop
483aca
-      }
483aca
+      } executeonly
483aca
       ifelse
483aca
     }
483aca
     {
483aca
diff --git a/Resource/Init/gs_pdfwr.ps b/Resource/Init/gs_pdfwr.ps
483aca
index 58e75d3..b425103 100644
483aca
--- a/Resource/Init/gs_pdfwr.ps
483aca
+++ b/Resource/Init/gs_pdfwr.ps
483aca
@@ -650,7 +650,7 @@ currentdict /.pdfmarkparams .undef
483aca
             } ifelse
483aca
           } bind .makeoperator .forceput
483aca
           systemdict /.pdf_hooked_DSC_Creator //true .forceput
483aca
-        } if
483aca
+        } executeonly if
483aca
         pop
483aca
       } if
483aca
     } {
483aca
diff --git a/Resource/Init/gs_res.ps b/Resource/Init/gs_res.ps
483aca
index 8eb8bb0..d9b3459 100644
483aca
--- a/Resource/Init/gs_res.ps
483aca
+++ b/Resource/Init/gs_res.ps
483aca
@@ -152,7 +152,7 @@ setglobal
483aca
                 % use .forceput / .forcedef later to replace the dummy,
483aca
                 % empty .Instances dictionary with the real one later.
483aca
           readonly
483aca
-        } {
483aca
+        }{
483aca
           /defineresource cvx /typecheck signaloperror
483aca
         } ifelse
483aca
 } bind executeonly odef
483aca
@@ -424,7 +424,7 @@ status {
483aca
                         % As noted above, Category dictionaries are read-only,
483aca
                         % so we have to use .forcedef here.
483aca
                   /.Instances 1 index .forcedef	% Category dict is read-only
483aca
-                } if
483aca
+                } executeonly if
483aca
               }
483aca
               { .LocalInstances dup //.emptydict eq
483aca
                  { pop 3 dict localinstancedict Category 2 index put
483aca
diff --git a/Resource/Init/gs_setpd.ps b/Resource/Init/gs_setpd.ps
483aca
index 71eb622..46e5810 100644
483aca
--- a/Resource/Init/gs_setpd.ps
483aca
+++ b/Resource/Init/gs_setpd.ps
483aca
@@ -634,7 +634,7 @@ NOMEDIAATTRS {
483aca
   SETPDDEBUG { (Rolling back.) = pstack flush } if
483aca
   3 index 2 index 3 -1 roll .forceput
483aca
   4 index 1 index .knownget
483aca
-  { 4 index 3 1 roll .forceput }
483aca
+  { 4 index 3 1 roll .forceput } executeonly
483aca
   { 3 index exch .undef }
483aca
   ifelse
483aca
 } bind executeonly odef
483aca
diff --git a/Resource/Init/pdf_base.ps b/Resource/Init/pdf_base.ps
483aca
index 7ccd4cd..c62ac0e 100644
483aca
--- a/Resource/Init/pdf_base.ps
483aca
+++ b/Resource/Init/pdf_base.ps
483aca
@@ -130,26 +130,29 @@ currentdict /num-chars-dict .undef
483aca
 
483aca
 /.pdfexectoken {		% <count> <opdict> <exectoken> .pdfexectoken ?
483aca
   PDFDEBUG {
483aca
-    pdfdict /PDFSTEPcount known not { pdfdict /PDFSTEPcount 1 .forceput } if
483aca
+    pdfdict /PDFSTEPcount known not { pdfdict /PDFSTEPcount 1 .forceput } executeonly if
483aca
     PDFSTEP {
483aca
       pdfdict /PDFtokencount 2 copy .knownget { 1 add } { 1 } ifelse .forceput
483aca
       PDFSTEPcount 1 gt {
483aca
         pdfdict /PDFSTEPcount PDFSTEPcount 1 sub .forceput
483aca
-      } {
483aca
+      } executeonly
483aca
+      {
483aca
         dup ==only
483aca
         (    step # ) print PDFtokencount =only
483aca
         ( ? ) print flush 1 //false .outputpage
483aca
         (%stdin) (r) file 255 string readline {
483aca
           token {
483aca
             exch pop pdfdict /PDFSTEPcount 3 -1 roll .forceput
483aca
-          } {
483aca
+          } executeonly
483aca
+          {
483aca
             pdfdict /PDFSTEPcount 1 .forceput
483aca
-          } ifelse % token
483aca
+          } executeonly ifelse % token
483aca
         } {
483aca
           pop /PDFSTEP //false def	 % EOF on stdin
483aca
         } ifelse % readline
483aca
       } ifelse % PDFSTEPcount > 1
483aca
-    } {
483aca
+    } executeonly
483aca
+    {
483aca
       dup ==only () = flush
483aca
     } ifelse % PDFSTEP
483aca
   } if % PDFDEBUG
483aca
diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps
483aca
index c239daf..d743ae1 100644
483aca
--- a/Resource/Init/pdf_draw.ps
483aca
+++ b/Resource/Init/pdf_draw.ps
483aca
@@ -1118,14 +1118,14 @@ currentdict end readonly def
483aca
           pdfdict /.Qqwarning_issued //true .forceput
483aca
           .setglobal
483aca
           pdfformaterror
483aca
-        } ifelse
483aca
+        } executeonly ifelse
483aca
       }
483aca
       {
483aca
         currentglobal pdfdict gcheck .setglobal
483aca
         pdfdict /.Qqwarning_issued //true .forceput
483aca
         .setglobal
483aca
         pdfformaterror
483aca
-      } ifelse
483aca
+      } executeonly ifelse
483aca
       end
483aca
     } ifelse
483aca
   } loop
483aca
@@ -1141,14 +1141,14 @@ currentdict end readonly def
483aca
         pdfdict /.Qqwarning_issued //true .forceput
483aca
         .setglobal
483aca
         pdfformaterror
483aca
-      } ifelse
483aca
+      } executeonly ifelse
483aca
     }
483aca
     {
483aca
       currentglobal pdfdict gcheck .setglobal
483aca
       pdfdict /.Qqwarning_issued //true .forceput
483aca
       .setglobal
483aca
       pdfformaterror
483aca
-    } ifelse
483aca
+    } executeonly ifelse
483aca
   } if
483aca
   pop
483aca
 
483aca
@@ -2350,9 +2350,10 @@ currentdict /last-ditch-bpc-csp undef
483aca
 /IncrementAppearanceNumber {
483aca
   pdfdict /AppearanceNumber .knownget {
483aca
     1 add pdfdict /AppearanceNumber 3 -1 roll .forceput
483aca
-  }{
483aca
+  } executeonly
483aca
+  {
483aca
     pdfdict /AppearanceNumber 0 .forceput
483aca
-  } ifelse
483aca
+  } executeonly ifelse
483aca
 }bind executeonly odef
483aca
 
483aca
 /MakeAppearanceName {
483aca
@@ -2510,7 +2511,8 @@ currentdict /last-ditch-bpc-csp undef
483aca
     %% want to preserve it.
483aca
     pdfdict /.PreservePDFForm false .forceput
483aca
     /q cvx /execform cvx 5 -2 roll
483aca
-  }{
483aca
+  } executeonly
483aca
+  {
483aca
     /q cvx /PDFexecform cvx 5 -2 roll
483aca
   } ifelse
483aca
 
483aca
diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps
483aca
index 535b14a..f1d1728 100644
483aca
--- a/Resource/Init/pdf_font.ps
483aca
+++ b/Resource/Init/pdf_font.ps
483aca
@@ -714,7 +714,7 @@ currentdict end readonly def
483aca
     pop pop pop
483aca
     currentdict /.stackdepth .forceundef
483aca
     currentdict /.dstackdepth .forceundef
483aca
-  }
483aca
+  } executeonly
483aca
   {pop pop pop}
483aca
   ifelse
483aca
 
483aca
@@ -1224,7 +1224,7 @@ currentdict /eexec_pdf_param_dict .undef
483aca
                 (\n   **** Warning: Type 3 glyph has unbalanced q/Q operators \(too many q's\)\n               Output may be incorrect.\n)
483aca
                 pdfformatwarning
483aca
                 pdfdict /.Qqwarning_issued //true .forceput
483aca
-              } if
483aca
+              } executeonly if
483aca
               Q
483aca
             } repeat
483aca
             Q
483aca
@@ -1989,7 +1989,7 @@ currentdict /CMap_read_dict undef
483aca
               /CIDFallBack /CIDFont findresource
483aca
             } if
483aca
             exit
483aca
-          } if
483aca
+          } executeonly if
483aca
         } if
483aca
       } if
483aca
 
483aca
diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps
483aca
index c823e69..dd1480b 100644
483aca
--- a/Resource/Init/pdf_main.ps
483aca
+++ b/Resource/Init/pdf_main.ps
483aca
@@ -2694,14 +2694,14 @@ currentdict /PDF2PS_matrix_key undef
483aca
           pdfdict /.Qqwarning_issued //true .forceput
483aca
           .setglobal
483aca
           pdfformaterror
483aca
-        } ifelse
483aca
+        } executeonly ifelse
483aca
       }
483aca
       {
483aca
         currentglobal pdfdict gcheck .setglobal
483aca
         pdfdict /.Qqwarning_issued //true .forceput
483aca
         .setglobal
483aca
         pdfformaterror
483aca
-      } ifelse
483aca
+      } executeonly ifelse
483aca
     } if
483aca
   } if
483aca
   pop
483aca
diff --git a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps
483aca
index 8672d61..aa09641 100644
483aca
--- a/Resource/Init/pdf_ops.ps
483aca
+++ b/Resource/Init/pdf_ops.ps
483aca
@@ -184,14 +184,14 @@ currentdict /gput_always_allow .undef
483aca
         pdfdict /.Qqwarning_issued //true .forceput
483aca
         .setglobal
483aca
         pdfformaterror
483aca
-      } ifelse
483aca
+      } executeonly ifelse
483aca
     }
483aca
     {
483aca
       currentglobal pdfdict gcheck .setglobal
483aca
       pdfdict /.Qqwarning_issued //true .forceput
483aca
       .setglobal
483aca
       pdfformaterror
483aca
-    } ifelse
483aca
+    } executeonly ifelse
483aca
   } if
483aca
 } bind executeonly odef
483aca
 
483aca
@@ -439,7 +439,8 @@ currentdict /gput_always_allow .undef
483aca
   dup type /booleantype eq {
483aca
     .currentSMask type /dicttype eq {
483aca
       .currentSMask /Processed 2 index .forceput
483aca
-    } {
483aca
+  } executeonly
483aca
+  {
483aca
       .setSMask
483aca
   }ifelse
483aca
   }{
483aca
-- 
483aca
2.17.2
483aca
483aca
483aca
From 99f13091a3f309bdc95d275ea9fec10bb9f42d9a Mon Sep 17 00:00:00 2001
483aca
From: Chris Liddell <chris.liddell@artifex.com>
483aca
Date: Sat, 15 Dec 2018 09:08:32 +0000
483aca
Subject: [PATCH 5/6] Bug700317: Fix logic for an older change
483aca
483aca
Unlike almost every other function in gs, dict_find_string() returns 1 on
483aca
success 0 or <0 on failure. The logic for this case was wrong.
483aca
---
483aca
 psi/interp.c | 2 +-
483aca
 1 file changed, 1 insertion(+), 1 deletion(-)
483aca
483aca
diff --git a/psi/interp.c b/psi/interp.c
483aca
index aa5779c..f6c45bb 100644
483aca
--- a/psi/interp.c
483aca
+++ b/psi/interp.c
483aca
@@ -703,7 +703,7 @@ again:
483aca
                  * i.e. it's an internal operator we have hidden
483aca
                  */
483aca
                 code = dict_find_string(systemdict, (const char *)bufptr, &tobj);
483aca
-                if (code < 0) {
483aca
+                if (code <= 0) {
483aca
                     buf[0] = buf[1] = buf[rlen + 2] = buf[rlen + 3] = '-';
483aca
                     rlen += 4;
483aca
                     bufptr = buf;
483aca
-- 
483aca
2.17.2
483aca
483aca
483aca
From 59d8f4deef90c1598ff50616519d5576756b4495 Mon Sep 17 00:00:00 2001
483aca
From: Chris Liddell <chris.liddell@artifex.com>
483aca
Date: Tue, 18 Dec 2018 10:42:10 +0000
483aca
Subject: [PATCH 6/6] Harden some uses of .force* operators
483aca
483aca
by adding a few immediate evalutions
483aca
---
483aca
 Resource/Init/gs_dps1.ps  |  4 ++--
483aca
 Resource/Init/gs_fonts.ps | 20 ++++++++++----------
483aca
 Resource/Init/gs_init.ps  |  6 +++---
483aca
 3 files changed, 15 insertions(+), 15 deletions(-)
483aca
483aca
diff --git a/Resource/Init/gs_dps1.ps b/Resource/Init/gs_dps1.ps
483aca
index 4fae283..b75ea14 100644
483aca
--- a/Resource/Init/gs_dps1.ps
483aca
+++ b/Resource/Init/gs_dps1.ps
483aca
@@ -74,7 +74,7 @@ level2dict begin
483aca
  } odef
483aca
 % undefinefont has to take local/global VM into account.
483aca
 /undefinefont		% <fontname> undefinefont -
483aca
- { .FontDirectory 1 .argindex .forceundef	% FontDirectory is readonly
483aca
+ { //.FontDirectory 1 .argindex .forceundef	% FontDirectory is readonly
483aca
    .currentglobal
483aca
     {		% Current mode is global; delete from local directory too.
483aca
       //systemdict /LocalFontDirectory .knownget
483aca
@@ -85,7 +85,7 @@ level2dict begin
483aca
                 % definition, copy it into the local directory.
483aca
       //systemdict /SharedFontDirectory .knownget
483aca
        { 1 index .knownget
483aca
-          { .FontDirectory 2 index 3 -1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } % readonly
483aca
+          { //.FontDirectory 2 index 3 -1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } % readonly
483aca
          if
483aca
        }
483aca
       if
483aca
diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps
483aca
index 6d2c26b..4807f81 100644
483aca
--- a/Resource/Init/gs_fonts.ps
483aca
+++ b/Resource/Init/gs_fonts.ps
483aca
@@ -516,7 +516,7 @@ buildfontdict 3 /.buildfont3 cvx put
483aca
       if
483aca
     }
483aca
    if
483aca
-   dup .FontDirectory 4 -2 roll { .growput } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse	% readonly
483aca
+   dup //.FontDirectory 4 -2 roll { .growput } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse	% readonly
483aca
                 % If the font originated as a resource, register it.
483aca
    currentfile .currentresourcefile eq { dup .registerfont } if
483aca
    readonly
483aca
@@ -943,7 +943,7 @@ $error /SubstituteFont { } put
483aca
 % Try to find a font using only the present contents of Fontmap.
483aca
 /.tryfindfont {         % <fontname> .tryfindfont <font> true
483aca
                         % <fontname> .tryfindfont false
483aca
-  .FontDirectory 1 index .fontknownget
483aca
+  //.FontDirectory 1 index .fontknownget
483aca
     {                   % Already loaded
483aca
       exch pop //true
483aca
     }
483aca
@@ -975,7 +975,7 @@ $error /SubstituteFont { } put
483aca
                {                % Font with a procedural definition
483aca
                  exec           % The procedure will load the font.
483aca
                                 % Check to make sure this really happened.
483aca
-                 .FontDirectory 1 index .knownget
483aca
+                 //.FontDirectory 1 index .knownget
483aca
                   { exch pop //true exit }
483aca
                  if
483aca
                }
483aca
@@ -1081,11 +1081,11 @@ $error /SubstituteFont { } put
483aca
                 % because it's different depending on language level.
483aca
            .currentglobal exch /.setglobal .systemvar exec
483aca
                 % Remove the fake definition, if any.
483aca
-           .FontDirectory 3 index .forceundef		% readonly
483aca
-           1 index (r) file .loadfont .FontDirectory exch
483aca
+           //.FontDirectory 3 index .forceundef		% readonly
483aca
+           1 index (r) file .loadfont //.FontDirectory exch
483aca
            /.setglobal .systemvar exec
483aca
          } executeonly
483aca
-         { .loadfont .FontDirectory
483aca
+         { .loadfont //.FontDirectory
483aca
          }
483aca
         ifelse
483aca
                 % Stack: fontname fontfilename fontdirectory
483aca
@@ -1119,8 +1119,8 @@ $error /SubstituteFont { } put
483aca
                       % Stack: origfontname fontdirectory filefontname fontdict
483aca
               3 -1 roll pop
483aca
                       % Stack: origfontname filefontname fontdict
483aca
-              dup /FontName get dup FontDirectory exch .forceundef
483aca
-              GlobalFontDirectory exch .forceundef
483aca
+              dup /FontName get dup //.FontDirectory exch .forceundef
483aca
+              /GlobalFontDirectory .systemvar exch .forceundef
483aca
               dup length dict .copydict dup 3 index /FontName exch put
483aca
               2 index exch definefont
483aca
               exch
483aca
@@ -1175,10 +1175,10 @@ currentdict /.putgstringcopy .forceundef
483aca
       {
483aca
         {
483aca
           pop dup type /stringtype eq { cvn } if
483aca
-          .FontDirectory 1 index known not {
483aca
+          //.FontDirectory 1 index known not {
483aca
             2 dict dup /FontName 3 index put
483aca
             dup /FontType 1 put
483aca
-            .FontDirectory 3 1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse   % readonly
483aca
+            //.FontDirectory 3 1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse   % readonly
483aca
           } {
483aca
             pop
483aca
           } ifelse
483aca
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
483aca
index 9015f90..48bb96d 100644
483aca
--- a/Resource/Init/gs_init.ps
483aca
+++ b/Resource/Init/gs_init.ps
483aca
@@ -1158,8 +1158,8 @@ errordict /unknownerror .undef
483aca
   //.SAFERERRORLIST
483aca
   {dup errordict exch get 2 index 3 1 roll put} forall
483aca
   noaccess pop
483aca
-  systemdict /.setsafeerrors .forceundef
483aca
-  systemdict /.SAFERERRORLIST .forceundef
483aca
+  //systemdict /.setsafeerrors .forceundef
483aca
+  //systemdict /.SAFERERRORLIST .forceundef
483aca
 } bind executeonly odef
483aca
 
483aca
 SAFERERRORS {.setsafererrors} if
483aca
@@ -2104,7 +2104,7 @@ currentdict /tempfilepaths undef
483aca
 
483aca
 /.locksafe {
483aca
   .locksafe_userparams
483aca
-  systemdict /getenv {pop //false} .forceput
483aca
+  //systemdict /getenv {pop //false} .forceput
483aca
   % setpagedevice has the side effect of clearing the page, but
483aca
   % we will just document that. Using setpagedevice keeps the device
483aca
   % properties and pagedevice .LockSafetyParams in agreement even
483aca
-- 
483aca
2.17.2
483aca