summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2018-09-20 17:08:08 +0100
committerKen Sharp <ken.sharp@artifex.com>2018-09-20 18:07:57 +0100
commit8ed08cb9904bc718ad57e0b4884a81a9227ce3ea (patch)
tree7ff270d41e07077d5f57fd71ad08d0d3c384535d
parent18e8a06bd34bb51c08760b7ebdbab68ab45712c1 (diff)
downloadghostpdl-8ed08cb9904bc718ad57e0b4884a81a9227ce3ea.tar.gz
Bug 699797 "setundercolorremoval memory corruption"
What is happening is that we are not properly reference counting a structure. For setblackgeneration and setundercolorremoval we need to use a continuation procedure, which samples the supplied PostScript function and then stores the sample map. As part of this we create an internal structure to hold the map, and we make this the current undercolorremoval/blackgeneration entry in the graphics state. We *also* push a reference to it onto the exec stack, so that the continuation procedure can use it from there. However we don't increment the reference count. When we execute the 'grestore' in the function we reset the values in the graphics state, and because the reference count is one we count it down and then discard the structure. When we then throw an error we try to copy data off the exec stack into an array, when we hit the reference to the freed strcuture we potentially are pointing to invalid memory, leading to a seg fault. To fix this, increment the reference count of the object when we put it on the exec stack, and decrement it when we remove it from the exec stack.
-rw-r--r--psi/zcolor.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/psi/zcolor.c b/psi/zcolor.c
index 53f176836..0409f62be 100644
--- a/psi/zcolor.c
+++ b/psi/zcolor.c
@@ -687,6 +687,7 @@ zcolor_remap_one(
++esp;
make_struct(esp, imemory_space((gs_ref_memory_t *) pgs->memory),
pmap);
+ rc_increment(pmap);
push_op_estack(finish_proc);
push_op_estack(zfor_samples);
return o_push_estack;
@@ -699,6 +700,7 @@ zcolor_remap_one_store(i_ctx_t *i_ctx_p, double min_value)
int i;
gx_transfer_map *pmap = r_ptr(esp, gx_transfer_map);
+ rc_decrement_only(pmap, "zcolor_remap_one_store");
if (ref_stack_count(&o_stack) < transfer_map_size)
return_error(gs_error_stackunderflow);
for (i = 0; i < transfer_map_size; i++) {