summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Deutschmann <whissi@gentoo.org>2021-09-27 11:19:24 +0200
committerThomas Deutschmann <whissi@gentoo.org>2021-10-20 18:22:47 +0200
commitcc6be9c3577168805ec34b2d396e63361012282b (patch)
tree7dc794b08a1a6a786d540516c623cb1eebfb1863 /base/gsparam.c
parentImport Ghostscript 9.54 (diff)
downloadghostscript-gpl-patches-cc6be9c3577168805ec34b2d396e63361012282b.tar.gz
ghostscript-gpl-patches-cc6be9c3577168805ec34b2d396e63361012282b.tar.bz2
ghostscript-gpl-patches-cc6be9c3577168805ec34b2d396e63361012282b.zip
Import Ghostscript 9.55ghostscript-9.55
Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
Diffstat (limited to 'base/gsparam.c')
-rw-r--r--base/gsparam.c129
1 files changed, 126 insertions, 3 deletions
diff --git a/base/gsparam.c b/base/gsparam.c
index e8a2f0c5..c8bfe7f9 100644
--- a/base/gsparam.c
+++ b/base/gsparam.c
@@ -102,7 +102,8 @@ static const byte xfer_item_sizes[] = {
};
int
gs_param_read_items(gs_param_list * plist, void *obj,
- const gs_param_item_t * items)
+ const gs_param_item_t * items,
+ gs_memory_t *mem)
{
const gs_param_item_t *pi;
int ecode = 0;
@@ -123,8 +124,128 @@ gs_param_read_items(gs_param_list * plist, void *obj,
case 0:
if (typed.type != pi->type) /* shouldn't happen! */
ecode = gs_note_error(gs_error_typecheck);
- else
- memcpy(pvalue, &typed.value, xfer_item_sizes[pi->type]);
+ else {
+ switch(typed.type)
+ {
+ case gs_param_type_dict:
+ case gs_param_type_dict_int_keys:
+ case gs_param_type_array:
+ return_error(gs_error_rangecheck);
+ case gs_param_type_string:
+ case gs_param_type_name:
+ {
+ void *copy;
+ gs_string *s;
+ if (mem == NULL) {
+ /* Return pointers to the data in the param list. This
+ * means that if the caller wants to keep it around it
+ * needs to copy it itself, or run the risk of the
+ * param list going away. */
+ goto copy_pointer;
+ }
+ /* Free any existing data before copying into it. */
+ s = ((gs_string *)pvalue);
+ if (typed.value.s.size != s->size) {
+ gs_free_string(mem, s->data, s->size, "gs_param_read_items");
+ s->data = NULL;
+ s->size = 0;
+ copy = gs_alloc_string(mem, typed.value.s.size, "gs_param_read_items");
+ if (copy == NULL)
+ return_error(gs_error_VMerror);
+ s->size = typed.value.s.size;
+ } else {
+ copy = s->data;
+ }
+ memcpy(copy, typed.value.s.data, typed.value.s.size);
+ s->data = copy;
+ ((gs_param_string *)pvalue)->persistent = 0; /* 0 => We own this copy */
+ break;
+ }
+ case gs_param_type_int_array:
+ case gs_param_type_float_array:
+ case gs_param_type_string_array:
+ case gs_param_type_name_array:
+ {
+ int eltsize;
+ gs_param_string_array *sa;
+ if (mem == NULL) {
+ /* Return pointers to the data in the param list. This
+ * means that if the caller wants to keep it around it
+ * needs to copy it itself, or run the risk of the
+ * param list going away. */
+ goto copy_pointer;
+ }
+ /* Free any existing data before copying into it. */
+ eltsize = gs_param_type_base_sizes[typed.type];
+ sa = ((gs_param_string_array *)pvalue);
+ if (typed.value.ia.size != sa->size) {
+ void *copy;
+ if (typed.type == gs_param_type_name_array ||
+ typed.type == gs_param_type_string_array) {
+ /* Free the strings. */
+ int i;
+ gs_param_string *arr;
+ union { const gs_param_string *cs; gs_param_string *s; } u;
+ u.cs = sa->data;
+ arr = u.s; /* Hideous dodge to avoid the const. */
+ for (i = 0; i < typed.value.sa.size; i++) {
+ /* Hideous hackery to get around the const nature of gs_param_strings. */
+ gs_string *arr_non_const = (gs_string *)(void *)(&arr[i]);
+ if (arr[i].persistent == 0)
+ gs_free_string(mem, arr_non_const->data, arr_non_const->size, "gs_param_read_items");
+ arr_non_const->data = NULL;
+ arr_non_const->size = 0;
+ }
+ }
+ gs_free_const_object(mem, sa->data, "gs_param_read_items");
+ sa->data = NULL;
+ sa->size = 0;
+ copy = gs_alloc_bytes(mem, eltsize * typed.value.s.size, "gs_param_read_items");
+ if (copy == NULL)
+ return_error(gs_error_VMerror);
+ memset(copy, 0, eltsize * typed.value.s.size);
+ sa->size = typed.value.s.size;
+ sa->data = copy;
+ }
+ /* Now copy the elements of the arrays. */
+ if (typed.type == gs_param_type_name_array ||
+ typed.type == gs_param_type_string_array) {
+ /* Free the strings. */
+ int i;
+ const gs_param_string *src = typed.value.sa.data;
+ gs_param_string *dst;
+ union { const gs_param_string *cs; gs_param_string *s; } u;
+ u.cs = sa->data;
+ dst = u.s; /* Hideous dodge to avoid the const. */
+ for (i = 0; i < typed.value.sa.size; i++) {
+ /* Hideous hackery to get around the const nature of gs_param_strings. */
+ gs_string *dst_non_const = (gs_string *)(void *)(&dst[i]);
+ if (dst[i].persistent == 0)
+ gs_free_string(mem, dst_non_const->data, dst_non_const->size, "gs_param_read_items");
+ dst_non_const->data = NULL;
+ dst_non_const->size = 0;
+ }
+ /* Copy values */
+ for (i = 0; i < sa->size; i++) {
+ dst[i].data = gs_alloc_string(mem, src[i].size, "gs_param_read_items");
+ if (dst[i].data == NULL)
+ return_error(gs_error_VMerror);
+ dst[i].size = src[i].size;
+ dst[i].persistent = 0; /* 0 => We own this copy */
+ }
+ } else {
+ /* Hideous hackery to get around the const nature of gs_param_strings. */
+ gs_string *s = (gs_string *)(void *)sa;
+ memcpy(s->data, typed.value.s.data, eltsize * typed.value.s.size);
+ }
+ ((gs_param_string *)pvalue)->persistent = 0; /* 0 => We own this copy */
+ break;
+ }
+ default:
+ copy_pointer:
+ memcpy(pvalue, &typed.value, xfer_item_sizes[pi->type]);
+ }
+ }
}
}
return ecode;
@@ -150,6 +271,8 @@ gs_param_write_items(gs_param_list * plist, const void *obj,
continue;
memcpy(&typed.value, pvalue, size);
typed.type = pi->type;
+ /* Ensure the list doesn't end up keeping a pointer to our values. */
+ typed.value.s.persistent = 0;
code = (*plist->procs->xmit_typed) (plist, key, &typed);
if (code < 0)
ecode = code;