summaryrefslogtreecommitdiff
path: root/base/gdevp14.c
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2022-07-01 10:07:57 +0100
committerKen Sharp <ken.sharp@artifex.com>2022-07-01 10:11:10 +0100
commit510bd436dec7c52cdf7222d3daa4184392453464 (patch)
tree49684dbd68cf8772063ffcb918f884779243c4e3 /base/gdevp14.c
parentb609c25f7f881bea4b10c8e1b9b950b635437320 (diff)
downloadghostpdl-510bd436dec7c52cdf7222d3daa4184392453464.tar.gz
Fix Nup subclassing device
Chris found this problem when working on OSS-fuzz #48305, setting the compile-time subclass device testing caused numerous seg faults on the cluster. The basic problem is the 'copy_and_modify_sub' routine which is an altered version of the graphics library 'param_list_copy' function. Both of these have a bug; the new param list 'persistent_keys' variable is set from the original param list, but the actual key we use is not the key from the original list, it's a char buffer on the heap. This is (obviously) not persistent and if the original list had persistent keys then we would not copy it. When the buffer went out of scope the pointer could be corrupted. Fix both functions here by insisting that the keys be copied (persistent = false) Following that, there is a hacky work-around in the pdf14 device for preventing new copies of 'kernel' subclass devices being installed when we push a compositor. The Nup device hadn't been added there. Add the device to that list, and also add a comment to the function that installs these devices reminding developers to make similar changes if they add new devices. Finally; commit b609c25f7f881bea4b10c8e1b9b950b635437320 changed the subclassing code to use reference counting, but used rc_decrement on the 'child' device. That causes seg faults because we rely on the finalize routine to 'unchain' subclassed devices. The rc_decrement macro sets the pointer (ie dev->child) to NULL after it has decremented the reference count and called the finalize routine, which corrupts the chain. Use rc_decrement_only which does the deceremnt but does not assign the pointer to NULL. Add a comment to explain why we are using it.
Diffstat (limited to 'base/gdevp14.c')
-rw-r--r--base/gdevp14.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/base/gdevp14.c b/base/gdevp14.c
index 3966f9546..60ee9215c 100644
--- a/base/gdevp14.c
+++ b/base/gdevp14.c
@@ -8891,6 +8891,7 @@ gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
new_target->PageHandlerPushed = true;
new_target->ObjectHandlerPushed = true;
+ new_target->NupHandlerPushed = true;
/* if the device has separations already defined (by SeparationOrderNames) */
/* we need to copy them (allocating new names) so the colorants are in the */
/* same order as the target device. */