1 From 430f39144244ba4fd7b720cf87031e415e0fabce Mon Sep 17 00:00:00 2001
2 From: Chris Liddell <chris.liddell@artifex.com>
3 Date: Mon, 5 Nov 2018 15:42:52 +0800
4 Subject: [PATCH 2/2] Bug 699927: don't include operator arrays in execstack
7 When we transfer the contents of the execution stack into the array, take the
8 extra step of replacing any operator arrays on the stack with the operator
11 This prevents the contents of Postscript defined, internal only operators (those
12 created with .makeoperator) being exposed via execstack (and thus, via error
15 This necessitates a change in the resource remapping 'resource', which contains
16 a procedure which relies on the contents of the operators arrays being present.
17 As we already had internal-only variants of countexecstack and execstack
18 (.countexecstack and .execstack) - using those, and leaving thier operation
19 including the operator arrays means the procedure continues to work correctly.
21 Both .countexecstack and .execstack are undefined after initialization.
23 Also, when we store the execstack (or part thereof) for an execstackoverflow
24 error, make the same oparray/operator substitution as above for execstack.
27 Upstream-Status: Backport [git://git.ghostscript.com/ghostpdl.git]
28 Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
30 Resource/Init/gs_init.ps | 4 ++--
31 Resource/Init/gs_resmp.ps | 2 +-
33 psi/interp.c | 14 +++++++++++---
35 psi/zcontrol.c | 13 ++++++++++---
36 6 files changed, 27 insertions(+), 10 deletions(-)
38 diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
39 index 7c71d18..f4c1053 100644
40 --- a/Resource/Init/gs_init.ps
41 +++ b/Resource/Init/gs_init.ps
42 @@ -2191,7 +2191,7 @@ SAFER { .setsafeglobal } if
43 %% but can be easily restored (just delete the name from the list in the array). In future
44 %% we may remove the operator and the code implementation entirely.
46 - /.bitadd /.charboxpath /.cond /.countexecstack /.execstack /.runandhide /.popdevicefilter
47 + /.bitadd /.charboxpath /.cond /.runandhide /.popdevicefilter
48 /.execfile /.filenamesplit /.file_name_parent
49 /.setdefaultmatrix /.isprocfilter /.unread /.psstringencode
50 /.buildsampledfunction /.isencapfunction /.currentaccuratecurves /.currentcurvejoin /.currentdashadapt /.currentdotlength
51 @@ -2230,7 +2230,7 @@ SAFER { .setsafeglobal } if
52 /.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile
53 /.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams
54 /.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath
55 - /.type /.writecvs /.setSMask /.currentSMask
56 + /.type /.writecvs /.setSMask /.currentSMask /.countexecstack /.execstack
58 % Used by a free user in the Library of Congress. Apparently this is used to
59 % draw a partial page, which is then filled in by the results of a barcode
60 diff --git a/Resource/Init/gs_resmp.ps b/Resource/Init/gs_resmp.ps
61 index 7cacaf8..9bb4263 100644
62 --- a/Resource/Init/gs_resmp.ps
63 +++ b/Resource/Init/gs_resmp.ps
64 @@ -183,7 +183,7 @@ setpacking
65 % We don't check them.
67 currentglobal //false setglobal % <object> bGlobal
68 - countexecstack array execstack % <object> bGlobal [execstack]
69 + //false .countexecstack array //false .execstack % <object> bGlobal [execstack]
70 dup //null exch % <object> bGlobal [execstack] null [execstack]
71 length 3 sub -1 0 { % <object> bGlobal [execstack] null i
72 2 index exch get % <object> bGlobal [execstack] null proc
73 diff --git a/psi/int.mak b/psi/int.mak
74 index 5d9b3d5..6ab5bf0 100644
77 @@ -323,7 +323,7 @@ $(PSOBJ)zarray.$(OBJ) : $(PSSRC)zarray.c $(OP) $(memory__h)\
79 $(PSOBJ)zcontrol.$(OBJ) : $(PSSRC)zcontrol.c $(OP) $(string__h)\
80 $(estack_h) $(files_h) $(ipacked_h) $(iutil_h) $(store_h) $(stream_h)\
81 - $(INT_MAK) $(MAKEDIRS)
82 + $(interp_h) $(INT_MAK) $(MAKEDIRS)
83 $(PSCC) $(PSO_)zcontrol.$(OBJ) $(C_) $(PSSRC)zcontrol.c
85 $(PSOBJ)zdict.$(OBJ) : $(PSSRC)zdict.c $(OP)\
86 diff --git a/psi/interp.c b/psi/interp.c
87 index b70769d..6dc0dda 100644
90 @@ -142,7 +142,6 @@ static int oparray_pop(i_ctx_t *);
91 static int oparray_cleanup(i_ctx_t *);
92 static int zerrorexec(i_ctx_t *);
93 static int zfinderrorobject(i_ctx_t *);
94 -static int errorexec_find(i_ctx_t *, ref *);
95 static int errorexec_pop(i_ctx_t *);
96 static int errorexec_cleanup(i_ctx_t *);
97 static int zsetstackprotect(i_ctx_t *);
98 @@ -761,7 +760,7 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, int skip, ref * arr)
100 uint size = ref_stack_count(pstack) - skip;
101 uint save_space = ialloc_space(idmemory);
107 @@ -770,6 +769,15 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, int skip, ref * arr)
109 code = ref_stack_store(pstack, arr, size, 0, 1, true, idmemory,
111 + /* If we are copying the exec stack, try to replace any oparrays with
112 + * with the operator than references them
114 + if (pstack == &e_stack) {
115 + for (i = 0; i < size; i++) {
116 + if (errorexec_find(i_ctx_p, &arr->value.refs[i]) < 0)
117 + make_null(&arr->value.refs[i]);
120 ialloc_set_space(idmemory, save_space);
123 @@ -1934,7 +1942,7 @@ zfinderrorobject(i_ctx_t *i_ctx_p)
124 * .errorexec with errobj != null, store it in *perror_object and return 1,
125 * otherwise return 0;
129 errorexec_find(i_ctx_t *i_ctx_p, ref *perror_object)
132 diff --git a/psi/interp.h b/psi/interp.h
133 index e9275b9..4f551d1 100644
136 @@ -91,5 +91,7 @@ void gs_interp_reset(i_ctx_t *i_ctx_p);
137 /* Define the top-level interface to the interpreter. */
138 int gs_interpret(i_ctx_t **pi_ctx_p, ref * pref, int user_errors,
139 int *pexit_code, ref * perror_object);
141 +errorexec_find(i_ctx_t *i_ctx_p, ref *perror_object);
143 #endif /* interp_INCLUDED */
144 diff --git a/psi/zcontrol.c b/psi/zcontrol.c
145 index 36da22c..0362cf4 100644
154 /* Forward references */
155 static int check_for_exec(const_os_ptr);
156 @@ -787,7 +788,7 @@ zexecstack2(i_ctx_t *i_ctx_p)
157 /* Continuation operator to do the actual transfer. */
158 /* r_size(op1) was set just above. */
160 -do_execstack(i_ctx_t *i_ctx_p, bool include_marks, os_ptr op1)
161 +do_execstack(i_ctx_t *i_ctx_p, bool include_marks, bool include_oparrays, os_ptr op1)
164 ref *arefs = op1->value.refs;
165 @@ -829,6 +830,12 @@ do_execstack(i_ctx_t *i_ctx_p, bool include_marks, os_ptr op1)
166 strlen(tname), (const byte *)tname);
172 + if (!include_oparrays && errorexec_find(i_ctx_p, rq) < 0)
178 @@ -841,14 +848,14 @@ execstack_continue(i_ctx_t *i_ctx_p)
182 - return do_execstack(i_ctx_p, false, op);
183 + return do_execstack(i_ctx_p, false, false, op);
186 execstack2_continue(i_ctx_t *i_ctx_p)
190 - return do_execstack(i_ctx_p, op->value.boolval, op - 1);
191 + return do_execstack(i_ctx_p, op->value.boolval, true, op - 1);