diff options
author | Thomas Deutschmann <whissi@gentoo.org> | 2021-03-30 10:59:39 +0200 |
---|---|---|
committer | Thomas Deutschmann <whissi@gentoo.org> | 2021-04-01 00:04:14 +0200 |
commit | 5ff1d6955496b3cf9a35042c9ac35db43bc336b1 (patch) | |
tree | 6d470f7eb448f59f53e8df1010aec9dad8ce1f72 /psi/interp.c | |
parent | Import Ghostscript 9.53.1 (diff) | |
download | ghostscript-gpl-patches-5ff1d6955496b3cf9a35042c9ac35db43bc336b1.tar.gz ghostscript-gpl-patches-5ff1d6955496b3cf9a35042c9ac35db43bc336b1.tar.bz2 ghostscript-gpl-patches-5ff1d6955496b3cf9a35042c9ac35db43bc336b1.zip |
Import Ghostscript 9.54ghostscript-9.54
Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
Diffstat (limited to 'psi/interp.c')
-rw-r--r-- | psi/interp.c | 61 |
1 files changed, 54 insertions, 7 deletions
diff --git a/psi/interp.c b/psi/interp.c index 730ddf16..40f94fe9 100644 --- a/psi/interp.c +++ b/psi/interp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -670,11 +670,12 @@ again: * so we'll always find the default one. If not SAFERERRORS, only gs specific * errors are in gserrordict. */ - if (dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 || - (dict_find(perrordict, &error_name, &epref) <= 0 && - (dict_find_string(systemdict, "errordict", &perrordict) <= 0 || - dict_find(perrordict, &error_name, &epref) <= 0)) - ) + if ((dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 || + !r_has_type(perrordict, t_dictionary) || + dict_find(perrordict, &error_name, &epref) <= 0) && + (dict_find_string(systemdict, "errordict", &perrordict) <= 0 || + !r_has_type(perrordict, t_dictionary) || + dict_find(perrordict, &error_name, &epref) <= 0)) return code; /* error name not in errordict??? */ doref = *epref; @@ -788,6 +789,41 @@ set_gc_signal(i_ctx_t *i_ctx_p, int value) } } +/* Create a printable string ref (or null) from an arbitrary ref. + * For the purpose this is used here, it cannot fail, any + * error in the process results in a null object, instead + * of the string. + */ +static void obj_cvs_ref(i_ctx_t *i_ctx_p, const ref *in, ref *out) +{ + uint rlen; + int code; + byte sbuf[65], *buf = sbuf; + uint len = sizeof(sbuf) - 1; + + code = obj_cvs(imemory, in, buf, len, &rlen, NULL); + if (code == gs_error_rangecheck) { + len = rlen; + buf = gs_alloc_bytes(imemory, len + 1, "obj_cvs_ref"); + if (!buf) + code = -1; + else + code = obj_cvs(imemory, in, buf, len, &rlen, NULL); + } + if (code < 0) { + make_null(out); + } + else { + buf[rlen] = '\0'; + code = string_to_ref((const char *)buf, out, iimemory, "obj_cvs_ref"); + if (code < 0) + make_null(out); + } + if (buf != sbuf) + gs_free_object(imemory, buf, "obj_cvs_ref"); + return; +} + /* Copy top elements of an overflowed stack into a (local) array. */ /* Adobe copies only 500 top elements, we copy up to 65535 top elements */ /* for better debugging, PLRM compliance, and backward compatibility. */ @@ -807,12 +843,23 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, int skip, ref * arr) code = ref_stack_store(pstack, arr, size, 0, 1, true, idmemory, "copy_stack"); /* If we are copying the exec stack, try to replace any oparrays with - * with the operator than references them + * the operator that references them + * We also replace any internal objects (t_struct and t_astruct) with + * string representations, since these can contain references to objects + * with uncertain lifespans, it is safer not to risk them persisting. + * Since we basically did this later on for the error handler, it isn't + * a significant speed hit. */ if (pstack == &e_stack) { for (i = 0; i < size; i++) { if (errorexec_find(i_ctx_p, &arr->value.refs[i]) < 0) make_null(&arr->value.refs[i]); + else if (r_has_type(&arr->value.refs[i], t_struct) + || r_has_type(&arr->value.refs[i], t_astruct)) { + ref r; + obj_cvs_ref(i_ctx_p, (const ref *)&arr->value.refs[i], &r); + ref_assign(&arr->value.refs[i], &r); + } } } if (pstack == &o_stack && dict_find_string(systemdict, "SAFETY", &safety) > 0 && |