diff options
-rw-r--r-- | psi/int.mak | 3 | ||||
-rw-r--r-- | psi/interp.c | 8 | ||||
-rw-r--r-- | psi/istack.c | 78 | ||||
-rw-r--r-- | psi/istack.h | 3 |
4 files changed, 91 insertions, 1 deletions
diff --git a/psi/int.mak b/psi/int.mak index 81bc59d4b..5dfb66ca7 100644 --- a/psi/int.mak +++ b/psi/int.mak | |||
@@ -203,7 +203,8 @@ $(PSOBJ)iparam.$(OBJ) : $(PSSRC)iparam.c $(GH)\ | |||
203 | $(PSOBJ)istack.$(OBJ) : $(PSSRC)istack.c $(GH) $(memory__h)\ | 203 | $(PSOBJ)istack.$(OBJ) : $(PSSRC)istack.c $(GH) $(memory__h)\ |
204 | $(ierrors_h) $(gsstruct_h) $(gsutil_h)\ | 204 | $(ierrors_h) $(gsstruct_h) $(gsutil_h)\ |
205 | $(ialloc_h) $(istack_h) $(istkparm_h) $(istruct_h) $(iutil_h) $(ivmspace_h)\ | 205 | $(ialloc_h) $(istack_h) $(istkparm_h) $(istruct_h) $(iutil_h) $(ivmspace_h)\ |
206 | $(store_h) $(INT_MAK) $(MAKEDIRS) | 206 | $(store_h) $(icstate_h) $(iname_h) $(dstack_h) $(idict_h) \ |
207 | $(INT_MAK) $(MAKEDIRS) | ||
207 | $(PSCC) $(PSO_)istack.$(OBJ) $(C_) $(PSSRC)istack.c | 208 | $(PSCC) $(PSO_)istack.$(OBJ) $(C_) $(PSSRC)istack.c |
208 | 209 | ||
209 | $(PSOBJ)iutil.$(OBJ) : $(PSSRC)iutil.c $(GH) $(math__h) $(memory__h) $(string__h)\ | 210 | $(PSOBJ)iutil.$(OBJ) : $(PSSRC)iutil.c $(GH) $(math__h) $(memory__h) $(string__h)\ |
diff --git a/psi/interp.c b/psi/interp.c index 16cce232c..68f977c56 100644 --- a/psi/interp.c +++ b/psi/interp.c | |||
@@ -797,6 +797,7 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, int skip, ref * arr) | |||
797 | uint size = ref_stack_count(pstack) - skip; | 797 | uint size = ref_stack_count(pstack) - skip; |
798 | uint save_space = ialloc_space(idmemory); | 798 | uint save_space = ialloc_space(idmemory); |
799 | int code, i; | 799 | int code, i; |
800 | ref *safety, *safe; | ||
800 | 801 | ||
801 | if (size > 65535) | 802 | if (size > 65535) |
802 | size = 65535; | 803 | size = 65535; |
@@ -814,6 +815,13 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, int skip, ref * arr) | |||
814 | make_null(&arr->value.refs[i]); | 815 | make_null(&arr->value.refs[i]); |
815 | } | 816 | } |
816 | } | 817 | } |
818 | if (pstack == &o_stack && dict_find_string(systemdict, "SAFETY", &safety) > 0 && | ||
819 | dict_find_string(safety, "safe", &safe) > 0 && r_has_type(safe, t_boolean) && | ||
820 | safe->value.boolval == true) { | ||
821 | code = ref_stack_array_sanitize(i_ctx_p, arr, arr); | ||
822 | if (code < 0) | ||
823 | return code; | ||
824 | } | ||
817 | ialloc_set_space(idmemory, save_space); | 825 | ialloc_set_space(idmemory, save_space); |
818 | return code; | 826 | return code; |
819 | } | 827 | } |
diff --git a/psi/istack.c b/psi/istack.c index 2c030f817..1bfcde4d7 100644 --- a/psi/istack.c +++ b/psi/istack.c | |||
@@ -27,6 +27,10 @@ | |||
27 | #include "iutil.h" | 27 | #include "iutil.h" |
28 | #include "ivmspace.h" /* for local/global test */ | 28 | #include "ivmspace.h" /* for local/global test */ |
29 | #include "store.h" | 29 | #include "store.h" |
30 | #include "icstate.h" | ||
31 | #include "iname.h" | ||
32 | #include "dstack.h" | ||
33 | #include "idict.h" | ||
30 | 34 | ||
31 | /* Forward references */ | 35 | /* Forward references */ |
32 | static void init_block(ref_stack_t *pstack, const ref *pblock_array, | 36 | static void init_block(ref_stack_t *pstack, const ref *pblock_array, |
@@ -294,6 +298,80 @@ ref_stack_store_check(const ref_stack_t *pstack, ref *parray, uint count, | |||
294 | return 0; | 298 | return 0; |
295 | } | 299 | } |
296 | 300 | ||
301 | int | ||
302 | ref_stack_array_sanitize(i_ctx_t *i_ctx_p, ref *sarr, ref *darr) | ||
303 | { | ||
304 | int i, code; | ||
305 | ref obj, arr2; | ||
306 | ref *pobj2; | ||
307 | gs_memory_t *mem = (gs_memory_t *)idmemory->current; | ||
308 | |||
309 | if (!r_is_array(sarr) || !r_has_type(darr, t_array)) | ||
310 | return_error(gs_error_typecheck); | ||
311 | |||
312 | for (i = 0; i < r_size(sarr); i++) { | ||
313 | code = array_get(mem, sarr, i, &obj); | ||
314 | if (code < 0) | ||
315 | make_null(&obj); | ||
316 | switch(r_type(&obj)) { | ||
317 | case t_operator: | ||
318 | { | ||
319 | int index = op_index(&obj); | ||
320 | |||
321 | if (index > 0 && index < op_def_count) { | ||
322 | const byte *data = (const byte *)(op_index_def(index)->oname + 1); | ||
323 | if (dict_find_string(systemdict, (const char *)data, &pobj2) <= 0) { | ||
324 | byte *s = gs_alloc_bytes(mem, strlen((char *)data) + 5, "ref_stack_array_sanitize"); | ||
325 | if (s) { | ||
326 | s[0] = '\0'; | ||
327 | strcpy((char *)s, "--"); | ||
328 | strcpy((char *)s + 2, (char *)data); | ||
329 | strcpy((char *)s + strlen((char *)data) + 2, "--"); | ||
330 | } | ||
331 | else { | ||
332 | s = (byte *)data; | ||
333 | } | ||
334 | code = name_ref(imemory, s, strlen((char *)s), &obj, 1); | ||
335 | if (code < 0) make_null(&obj); | ||
336 | if (s != data) | ||
337 | gs_free_object(mem, s, "ref_stack_array_sanitize"); | ||
338 | } | ||
339 | } | ||
340 | else { | ||
341 | make_null(&obj); | ||
342 | } | ||
343 | ref_assign(darr->value.refs + i, &obj); | ||
344 | break; | ||
345 | } | ||
346 | case t_array: | ||
347 | case t_shortarray: | ||
348 | case t_mixedarray: | ||
349 | { | ||
350 | int attrs = r_type_attrs(&obj) & (a_write | a_read | a_execute | a_executable); | ||
351 | /* We only want to copy executable arrays */ | ||
352 | if (attrs & (a_execute | a_executable)) { | ||
353 | code = ialloc_ref_array(&arr2, attrs, r_size(&obj), "ref_stack_array_sanitize"); | ||
354 | if (code < 0) { | ||
355 | make_null(&arr2); | ||
356 | } | ||
357 | else { | ||
358 | code = ref_stack_array_sanitize(i_ctx_p, &obj, &arr2); | ||
359 | } | ||
360 | ref_assign(darr->value.refs + i, &arr2); | ||
361 | } | ||
362 | else { | ||
363 | ref_assign(darr->value.refs + i, &obj); | ||
364 | } | ||
365 | break; | ||
366 | } | ||
367 | default: | ||
368 | ref_assign(darr->value.refs + i, &obj); | ||
369 | } | ||
370 | } | ||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | |||
297 | /* | 375 | /* |
298 | * Store the top 'count' elements of a stack, starting 'skip' elements below | 376 | * Store the top 'count' elements of a stack, starting 'skip' elements below |
299 | * the top, into an array, with or without store/undo checking. age=-1 for | 377 | * the top, into an array, with or without store/undo checking. age=-1 for |
diff --git a/psi/istack.h b/psi/istack.h index 4619a3b3d..7c33844ed 100644 --- a/psi/istack.h +++ b/psi/istack.h | |||
@@ -125,6 +125,9 @@ int ref_stack_store(const ref_stack_t *pstack, ref *parray, uint count, | |||
125 | uint skip, int age, bool check, | 125 | uint skip, int age, bool check, |
126 | gs_dual_memory_t *idmem, client_name_t cname); | 126 | gs_dual_memory_t *idmem, client_name_t cname); |
127 | 127 | ||
128 | int | ||
129 | ref_stack_array_sanitize(i_ctx_t *i_ctx_p, ref *sarr, ref *darr); | ||
130 | |||
128 | /* | 131 | /* |
129 | * Pop the top N elements off a stack. | 132 | * Pop the top N elements off a stack. |
130 | * The number must not exceed the number of elements in use. | 133 | * The number must not exceed the number of elements in use. |