diff options
author | Chris Liddell <chris.liddell@artifex.com> | 2018-08-23 14:13:25 +0100 |
---|---|---|
committer | Chris Liddell <chris.liddell@artifex.com> | 2018-08-23 15:41:05 +0100 |
commit | c432131c3fdb2143e148e8ba88555f7f7a63b25e (patch) | |
tree | be33325404f1d31a0a5a2e5483bab17450fc4dfb | |
parent | 0b6cd1918e1ec4ffd087400a754a845180a4522b (diff) |
Bug 699661: Avoid sharing pointers between pdf14 compositors
If a copdevice is triggered when the pdf14 compositor is the device, we make
a copy of the device, then throw an error because, by default we're only allowed
to copy the device prototype - then freeing it calls the finalize, which frees
several pointers shared with the parent.
Make a pdf14 specific finish_copydevice() which NULLs the relevant pointers,
before, possibly, throwing the same error as the default method.
This also highlighted a problem with reopening the X11 devices, where a custom
error handler could be replaced with itself, meaning it also called itself,
and infifite recursion resulted.
Keep a note of if the handler replacement has been done, and don't do it a
second time.
-rw-r--r-- | base/gdevp14.c | 17 | ||||
-rw-r--r-- | devices/gdevxini.c | 12 |
2 files changed, 24 insertions, 5 deletions
diff --git a/base/gdevp14.c b/base/gdevp14.c index d9f8e794c..eb9cc23bc 100644 --- a/base/gdevp14.c +++ b/base/gdevp14.c | |||
@@ -178,6 +178,7 @@ static dev_proc_fill_mask(pdf14_fill_mask); | |||
178 | static dev_proc_stroke_path(pdf14_stroke_path); | 178 | static dev_proc_stroke_path(pdf14_stroke_path); |
179 | static dev_proc_begin_typed_image(pdf14_begin_typed_image); | 179 | static dev_proc_begin_typed_image(pdf14_begin_typed_image); |
180 | static dev_proc_text_begin(pdf14_text_begin); | 180 | static dev_proc_text_begin(pdf14_text_begin); |
181 | static dev_proc_finish_copydevice(pdf14_finish_copydevice); | ||
181 | static dev_proc_create_compositor(pdf14_create_compositor); | 182 | static dev_proc_create_compositor(pdf14_create_compositor); |
182 | static dev_proc_create_compositor(pdf14_forward_create_compositor); | 183 | static dev_proc_create_compositor(pdf14_forward_create_compositor); |
183 | static dev_proc_begin_transparency_group(pdf14_begin_transparency_group); | 184 | static dev_proc_begin_transparency_group(pdf14_begin_transparency_group); |
@@ -245,7 +246,7 @@ static const gx_color_map_procs * | |||
245 | pdf14_create_compositor, /* create_compositor */\ | 246 | pdf14_create_compositor, /* create_compositor */\ |
246 | NULL, /* get_hardware_params */\ | 247 | NULL, /* get_hardware_params */\ |
247 | pdf14_text_begin, /* text_begin */\ | 248 | pdf14_text_begin, /* text_begin */\ |
248 | NULL, /* finish_copydevice */\ | 249 | pdf14_finish_copydevice, /* finish_copydevice */\ |
249 | pdf14_begin_transparency_group,\ | 250 | pdf14_begin_transparency_group,\ |
250 | pdf14_end_transparency_group,\ | 251 | pdf14_end_transparency_group,\ |
251 | pdf14_begin_transparency_mask,\ | 252 | pdf14_begin_transparency_mask,\ |
@@ -3935,6 +3936,19 @@ pdf14_text_begin(gx_device * dev, gs_gstate * pgs, | |||
3935 | return code; | 3936 | return code; |
3936 | } | 3937 | } |
3937 | 3938 | ||
3939 | static int | ||
3940 | pdf14_finish_copydevice(gx_device *new_dev, const gx_device *from_dev) | ||
3941 | { | ||
3942 | pdf14_device *pdev = (pdf14_device*)new_dev; | ||
3943 | |||
3944 | pdev->ctx = NULL; | ||
3945 | pdev->trans_group_parent_cmap_procs = NULL; | ||
3946 | pdev->smaskcolor = NULL; | ||
3947 | |||
3948 | /* Only allow copying the prototype. */ | ||
3949 | return (from_dev->memory ? gs_note_error(gs_error_rangecheck) : 0); | ||
3950 | } | ||
3951 | |||
3938 | /* | 3952 | /* |
3939 | * Implement copy_mono by filling lots of small rectangles. | 3953 | * Implement copy_mono by filling lots of small rectangles. |
3940 | */ | 3954 | */ |
@@ -8093,6 +8107,7 @@ c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev, | |||
8093 | before reopening the device */ | 8107 | before reopening the device */ |
8094 | if (p14dev->ctx != NULL) { | 8108 | if (p14dev->ctx != NULL) { |
8095 | pdf14_ctx_free(p14dev->ctx); | 8109 | pdf14_ctx_free(p14dev->ctx); |
8110 | p14dev->ctx = NULL; | ||
8096 | } | 8111 | } |
8097 | dev_proc(tdev, open_device) (tdev); | 8112 | dev_proc(tdev, open_device) (tdev); |
8098 | } | 8113 | } |
diff --git a/devices/gdevxini.c b/devices/gdevxini.c index 8511eac80..23b8c35a6 100644 --- a/devices/gdevxini.c +++ b/devices/gdevxini.c | |||
@@ -59,7 +59,8 @@ static struct xv_ { | |||
59 | Boolean alloc_error; | 59 | Boolean alloc_error; |
60 | XErrorHandler orighandler; | 60 | XErrorHandler orighandler; |
61 | XErrorHandler oldhandler; | 61 | XErrorHandler oldhandler; |
62 | } x_error_handler; | 62 | Boolean set; |
63 | } x_error_handler = {0}; | ||
63 | 64 | ||
64 | static int | 65 | static int |
65 | x_catch_alloc(Display * dpy, XErrorEvent * err) | 66 | x_catch_alloc(Display * dpy, XErrorEvent * err) |
@@ -74,7 +75,8 @@ x_catch_alloc(Display * dpy, XErrorEvent * err) | |||
74 | int | 75 | int |
75 | x_catch_free_colors(Display * dpy, XErrorEvent * err) | 76 | x_catch_free_colors(Display * dpy, XErrorEvent * err) |
76 | { | 77 | { |
77 | if (err->request_code == X_FreeColors) | 78 | if (err->request_code == X_FreeColors || |
79 | x_error_handler.orighandler == x_catch_free_colors) | ||
78 | return 0; | 80 | return 0; |
79 | return x_error_handler.orighandler(dpy, err); | 81 | return x_error_handler.orighandler(dpy, err); |
80 | } | 82 | } |
@@ -274,8 +276,10 @@ gdev_x_open(gx_device_X * xdev) | |||
274 | return_error(gs_error_ioerror); | 276 | return_error(gs_error_ioerror); |
275 | } | 277 | } |
276 | /* Buggy X servers may cause a Bad Access on XFreeColors. */ | 278 | /* Buggy X servers may cause a Bad Access on XFreeColors. */ |
277 | x_error_handler.orighandler = XSetErrorHandler(x_catch_free_colors); | 279 | if (!x_error_handler.set) { |
278 | 280 | x_error_handler.orighandler = XSetErrorHandler(x_catch_free_colors); | |
281 | x_error_handler.set = True; | ||
282 | } | ||
279 | /* Get X Resources. Use the toolkit for this. */ | 283 | /* Get X Resources. Use the toolkit for this. */ |
280 | XtToolkitInitialize(); | 284 | XtToolkitInitialize(); |
281 | app_con = XtCreateApplicationContext(); | 285 | app_con = XtCreateApplicationContext(); |