diff options
author | Robin Watts <Robin.Watts@artifex.com> | 2022-04-05 16:34:45 +0100 |
---|---|---|
committer | Robin Watts <Robin.Watts@artifex.com> | 2022-04-07 18:23:27 +0100 |
commit | db5f053a2838f6fdb69b387e0f8ef70daca59a96 (patch) | |
tree | 5fab3faf938387708f46e8a0f740643db836410e | |
parent | d6f88ef54434fcfc6dcefdcfe21bab1b1b77508b (diff) | |
download | ghostpdl-db5f053a2838f6fdb69b387e0f8ef70daca59a96.tar.gz |
Bug 705203: Fix SEGV seen in overnights with pattern cache problem.
Introduce new lock_pattern device proc and clist implementation.
Call that for fill_stroke operations.
-rw-r--r-- | base/gdevdflt.c | 1 | ||||
-rw-r--r-- | base/gdevepo.c | 3 | ||||
-rw-r--r-- | base/gdevnfwd.c | 16 | ||||
-rw-r--r-- | base/gdevsclass.c | 10 | ||||
-rw-r--r-- | base/gdevsclass.h | 3 | ||||
-rw-r--r-- | base/gsovrc.c | 3 | ||||
-rw-r--r-- | base/gspaint.c | 14 | ||||
-rw-r--r-- | base/gxcldev.h | 6 | ||||
-rw-r--r-- | base/gxclipm.c | 3 | ||||
-rw-r--r-- | base/gxclist.c | 1 | ||||
-rw-r--r-- | base/gxclpath.c | 22 | ||||
-rw-r--r-- | base/gxclpath.h | 3 | ||||
-rw-r--r-- | base/gxclrast.c | 46 | ||||
-rw-r--r-- | base/gxdevcli.h | 13 | ||||
-rw-r--r-- | base/gxdevice.h | 4 | ||||
-rw-r--r-- | base/gxfill.c | 11 | ||||
-rw-r--r-- | base/gxpcmap.c | 1 |
17 files changed, 113 insertions, 47 deletions
diff --git a/base/gdevdflt.c b/base/gdevdflt.c index f93e968d8..72a43ff17 100644 --- a/base/gdevdflt.c +++ b/base/gdevdflt.c @@ -729,6 +729,7 @@ gx_device_fill_in_procs(register gx_device * dev) fill_dev_proc(dev, process_page, gx_default_process_page); fill_dev_proc(dev, transform_pixel_region, gx_default_transform_pixel_region); fill_dev_proc(dev, fill_stroke_path, gx_default_fill_stroke_path); + fill_dev_proc(dev, lock_pattern, gx_default_lock_pattern); } diff --git a/base/gdevepo.c b/base/gdevepo.c index f8c46c549..eea3300e4 100644 --- a/base/gdevepo.c +++ b/base/gdevepo.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -235,6 +235,7 @@ disable_self(gx_device *dev) set_dev_proc(dev, process_page, default_subclass_process_page); set_dev_proc(dev, transform_pixel_region, default_subclass_transform_pixel_region); set_dev_proc(dev, fill_stroke_path, default_subclass_fill_stroke_path); + set_dev_proc(dev, lock_pattern, default_subclass_lock_pattern); } int diff --git a/base/gdevnfwd.c b/base/gdevnfwd.c index 948bfa09e..4b23cbcb0 100644 --- a/base/gdevnfwd.c +++ b/base/gdevnfwd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -106,6 +106,7 @@ gx_device_forward_fill_in_procs(register gx_device_forward * dev) fill_dev_proc(dev, strip_tile_rect_devn, gx_forward_strip_tile_rect_devn); fill_dev_proc(dev, transform_pixel_region, gx_forward_transform_pixel_region); fill_dev_proc(dev, fill_stroke_path, gx_forward_fill_stroke_path); + fill_dev_proc(dev, lock_pattern, gx_forward_lock_pattern); gx_device_fill_in_procs((gx_device *) dev); } @@ -367,6 +368,19 @@ gx_forward_fill_stroke_path(gx_device * dev, const gs_gstate * pgs, } int +gx_forward_lock_pattern(gx_device * dev, gs_gstate * pgs, gs_id pattern_id, int lock) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + dev_proc_lock_pattern((*proc)) = + (tdev == 0 ? (tdev = dev, gx_default_lock_pattern) : + dev_proc(tdev, lock_pattern)); + + return proc(tdev, pgs, pattern_id, lock); + +} + +int gx_forward_fill_mask(gx_device * dev, const byte * data, int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h, diff --git a/base/gdevsclass.c b/base/gdevsclass.c index 2f757b769..5ec59296f 100644 --- a/base/gdevsclass.c +++ b/base/gdevsclass.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -757,6 +757,13 @@ int default_subclass_fill_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_p return 0; } +int default_subclass_lock_pattern(gx_device *dev, gs_gstate *pgs, gs_id pattern_id, int lock) +{ + if (dev->child) + return dev_proc(dev->child, lock_pattern)(dev->child, pgs, pattern_id, lock); + return 0; +} + int default_subclass_transform_pixel_region(gx_device *dev, transform_pixel_region_reason reason, transform_pixel_region_data *data) { if (dev->child) @@ -860,6 +867,7 @@ void default_subclass_initialize_device_procs(gx_device *dev) set_dev_proc(dev, process_page, default_subclass_process_page); set_dev_proc(dev, transform_pixel_region, default_subclass_transform_pixel_region); set_dev_proc(dev, fill_stroke_path, default_subclass_fill_stroke_path); + set_dev_proc(dev, lock_pattern, default_subclass_lock_pattern); } int diff --git a/base/gdevsclass.h b/base/gdevsclass.h index 2fb440d63..b543b54b7 100644 --- a/base/gdevsclass.h +++ b/base/gdevsclass.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -89,6 +89,7 @@ dev_proc_copy_alpha_hl_color(default_subclass_copy_alpha_hl_color); dev_proc_process_page(default_subclass_process_page); dev_proc_transform_pixel_region(default_subclass_transform_pixel_region); dev_proc_fill_stroke_path(default_subclass_fill_stroke_path); +dev_proc_lock_pattern(default_subclass_lock_pattern); dev_page_proc_install(default_subclass_install); dev_page_proc_begin_page(default_subclass_begin_page); dev_page_proc_end_page(default_subclass_end_page); diff --git a/base/gsovrc.c b/base/gsovrc.c index 745ebfbe9..d5d5d1c46 100644 --- a/base/gsovrc.c +++ b/base/gsovrc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -424,6 +424,7 @@ nooverprint_initialize_device_procs(gx_device *dev) set_dev_proc(dev, copy_planes, gx_forward_copy_planes); set_dev_proc(dev, copy_alpha_hl_color, gx_forward_copy_alpha_hl_color); set_dev_proc(dev, fill_stroke_path, gx_forward_fill_stroke_path); + set_dev_proc(dev, lock_pattern, gx_forward_lock_pattern); } /* diff --git a/base/gspaint.c b/base/gspaint.c index f7127e0e5..8e4c75cf1 100644 --- a/base/gspaint.c +++ b/base/gspaint.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -615,7 +615,7 @@ static int do_fill_stroke(gs_gstate *pgs, int rule, int *restart) if(gs_currentdevicecolor_inline(pgs)->colors.pattern.p_tile != NULL) { id = gs_currentdevicecolor_inline(pgs)->colors.pattern.p_tile->id; - code = gx_pattern_cache_entry_set_lock(pgs, id, true); + code = dev_proc(pgs->device, lock_pattern)(pgs->device, pgs, id, true); } else { code = 0; } @@ -661,7 +661,7 @@ static int do_fill_stroke(gs_gstate *pgs, int rule, int *restart) if(gs_currentdevicecolor_inline(pgs)->colors.pattern.p_tile != NULL) { id = gs_currentdevicecolor_inline(pgs)->colors.pattern.p_tile->id; - code = gx_pattern_cache_entry_set_lock(pgs, id, true); + code = dev_proc(pgs->device, lock_pattern)(pgs->device, pgs, id, true); } else { code = 0; } @@ -769,7 +769,7 @@ static int do_fill_stroke(gs_gstate *pgs, int rule, int *restart) if(gs_currentdevicecolor_inline(pgs)->colors.pattern.p_tile != NULL) { id = gs_currentdevicecolor_inline(pgs)->colors.pattern.p_tile->id; - code = gx_pattern_cache_entry_set_lock(pgs, id, false); + code = dev_proc(pgs->device, lock_pattern)(pgs->device, pgs, id, false); } else { code = 0; } @@ -783,9 +783,9 @@ out: if (gs_swappeddevicecolor_inline(pgs)->colors.pattern.p_tile != NULL) { id = gs_swappeddevicecolor_inline(pgs)->colors.pattern.p_tile->id; - rcode = gx_pattern_cache_entry_set_lock(pgs, id, false); - if (rcode < 0) - return rcode; /* unlock failed -- shouldn't be possible */ + rcode = dev_proc(pgs->device, lock_pattern)(pgs->device, pgs, id, false); + if (rcode < 0) + return rcode; /* unlock failed -- shouldn't be possible */ } else { code = 0; } diff --git a/base/gxcldev.h b/base/gxcldev.h index 660205032..708b17795 100644 --- a/base/gxcldev.h +++ b/base/gxcldev.h @@ -204,7 +204,7 @@ typedef enum { cmd_op_path = 0xf0, /* (see below) */ cmd_opv_fill = 0xf0, cmd_opv_rgapto = 0xf1, /* dx%, dy% */ - /* UNUSED 0xf2 */ + cmd_opv_lock_pattern = 0xf2, /* lock, id */ cmd_opv_eofill = 0xf3, cmd_opv_fill_stroke = 0xf4, cmd_opv_eofill_stroke = 0xf5, @@ -220,12 +220,12 @@ typedef enum { /* UNUSED 0xff */ #define cmd_path_op_name_strings\ - "fill", "rgapto", "?f2?", "eofill",\ + "fill", "rgapto", "lock_pattern", "eofill",\ "fill_stroke", "eofill_stroke", "stroke", "?f7?",\ "?f8?", "polyfill", "?fa?", "?fb?",\ "fill_trapezoid", "?fd?", "?fe?", "?ff?" -/* unused cmd_op values: 0xf2, 0xf7, 0xf8, 0xfa, 0xfb, 0xfd, 0xfe, 0xff */ +/* unused cmd_op values: 0xf7, 0xf8, 0xfa, 0xfb, 0xfd, 0xfe, 0xff */ } gx_cmd_op; #define cmd_op_name_strings\ diff --git a/base/gxclipm.c b/base/gxclipm.c index 627f28a53..b4cd65551 100644 --- a/base/gxclipm.c +++ b/base/gxclipm.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -77,6 +77,7 @@ mask_clip_initialize_device_procs(gx_device *dev) set_dev_proc(dev, copy_alpha_hl_color, mask_clip_copy_alpha_hl_color); set_dev_proc(dev, transform_pixel_region, gx_default_transform_pixel_region); set_dev_proc(dev, fill_stroke_path, gx_forward_fill_stroke_path); + set_dev_proc(dev, lock_pattern, gx_forward_lock_pattern); /* Ideally these defaults would be set up automatically for us. */ set_dev_proc(dev, open_device, gx_default_open_device); diff --git a/base/gxclist.c b/base/gxclist.c index 3b778f533..fe12be56e 100644 --- a/base/gxclist.c +++ b/base/gxclist.c @@ -174,6 +174,7 @@ clist_initialize_device_procs(gx_device *dev) set_dev_proc(dev, copy_alpha_hl_color, clist_copy_alpha_hl_color); set_dev_proc(dev, process_page, clist_process_page); set_dev_proc(dev, fill_stroke_path, clist_fill_stroke_path); + set_dev_proc(dev, lock_pattern, clist_lock_pattern); } /*------------------- Choose the implementation ----------------------- diff --git a/base/gxclpath.c b/base/gxclpath.c index c202178c3..7c938adb0 100644 --- a/base/gxclpath.c +++ b/base/gxclpath.c @@ -927,6 +927,28 @@ clist_fill_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath, return 0; } +int clist_lock_pattern(gx_device * pdev, gs_gstate * pgs, gs_id pattern, int lock) +{ + gx_device_clist_writer * const cdev = + &((gx_device_clist *)pdev)->writer; + byte *dp; + int code; + + /* We need to both lock now, and ensure that we lock on reading this back. */ + code = gx_pattern_cache_entry_set_lock(pgs, pattern, lock); + if (code < 0) + return code; + + code = set_cmd_put_all_op(&dp, cdev, cmd_opv_lock_pattern, + 1 + 1 + sizeof(pattern)); + + if (code < 0) + return code; + dp[1] = lock; + memcpy(dp+2, &pattern, sizeof(pattern)); + return 0; +} + int clist_fill_stroke_path(gx_device * pdev, const gs_gstate * pgs, gx_path * ppath, diff --git a/base/gxclpath.h b/base/gxclpath.h index c334222c6..ccf12353a 100644 --- a/base/gxclpath.h +++ b/base/gxclpath.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -132,6 +132,7 @@ extern const char *cmd_extend_op_names[256]; dev_proc_fill_path(clist_fill_path); dev_proc_stroke_path(clist_stroke_path); dev_proc_fill_stroke_path(clist_fill_stroke_path); +dev_proc_lock_pattern(clist_lock_pattern); dev_proc_fill_parallelogram(clist_fill_parallelogram); dev_proc_fill_triangle(clist_fill_triangle); diff --git a/base/gxclrast.c b/base/gxclrast.c index c38faa49a..db6a4e132 100644 --- a/base/gxclrast.c +++ b/base/gxclrast.c @@ -2014,14 +2014,26 @@ idata: data_size = 0; } continue; case cmd_op_path >> 4: - { + if (op == cmd_opv_rgapto) + goto rgapto; + else if (op == cmd_opv_lock_pattern) { + gs_id id; + int lock = *cbp++; + cmd_get_value(id, cbp); + if_debug2m('L', mem, "id=0x%lx, lock=%d\n", id, lock); + /* We currently lock the pattern in all the bands, even in ones + * where we haven't used the pattern. This can cause the following + * call to return with 'undefined' because the pattern is not + * found. Just swallow this error and continue. */ + code = gx_pattern_cache_entry_set_lock(&gs_gstate, id, lock); + if (code == gs_error_undefined) + code = 0; + if (code < 0) + goto out; + continue; + } else { gx_path fpath; - gx_path *ppath; - - if (op == cmd_opv_rgapto) - goto rgapto; - - ppath = &path; + gx_path *ppath = &path; if_debug0m('L', mem, "\n"); /* if in clip, flatten path first */ @@ -2059,26 +2071,6 @@ idata: data_size = 0; code = (*dev_proc(tdev, fill_stroke_path))(tdev, &gs_gstate, ppath, &fill_params, &fill_color, &stroke_params, &stroke_color, pcpath); - /* if the color is a pattern, it may have had the "is_locked" flag set */ - /* clear those now (see do_fill_stroke). */ - if (gx_dc_is_pattern1_color(&stroke_color)) { - if (stroke_color.colors.pattern.p_tile != NULL) { - gs_id id = stroke_color.colors.pattern.p_tile->id; - - code = gx_pattern_cache_entry_set_lock(&gs_gstate, id, false); - if (code < 0) - return code; /* unlock failed -- should not happen */ - } - } - if (gx_dc_is_pattern1_color(&fill_color)) { - if (fill_color.colors.pattern.p_tile != NULL) { - gs_id id = fill_color.colors.pattern.p_tile->id; - - code = gx_pattern_cache_entry_set_lock(&gs_gstate, id, false); - if (code < 0) - return code; /* unlock failed -- should not happen */ - } - } break; case cmd_opv_stroke: stroke_params.flatness = gs_gstate.flatness; diff --git a/base/gxdevcli.h b/base/gxdevcli.h index 2476ea338..3fc1c742f 100644 --- a/base/gxdevcli.h +++ b/base/gxdevcli.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -997,6 +997,16 @@ typedef enum FILTER_FLAGS { #define dev_proc_fill_stroke_path(proc)\ dev_t_proc_fill_stroke_path(proc, gx_device) + /* Added in release 9.57 */ + +#define dev_t_proc_lock_pattern(proc, dev_t)\ + int proc(dev_t *dev,\ + gs_gstate *pgs,\ + gs_id pattern_id,\ + int lock) +#define dev_proc_lock_pattern(proc)\ + dev_t_proc_lock_pattern(proc, gx_device) + /* Added in release 3.60 */ #define dev_t_proc_fill_mask(proc, dev_t)\ @@ -1508,6 +1518,7 @@ typedef struct { dev_t_proc_process_page((*process_page), dev_t);\ dev_t_proc_transform_pixel_region((*transform_pixel_region), dev_t);\ dev_t_proc_fill_stroke_path((*fill_stroke_path), dev_t);\ + dev_t_proc_lock_pattern((*lock_pattern), dev_t);\ } /* diff --git a/base/gxdevice.h b/base/gxdevice.h index d9b0134d3..f62c0710e 100644 --- a/base/gxdevice.h +++ b/base/gxdevice.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -318,6 +318,7 @@ dev_proc_copy_alpha_hl_color(gx_default_copy_alpha_hl_color); dev_proc_process_page(gx_default_process_page); dev_proc_transform_pixel_region(gx_default_transform_pixel_region); dev_proc_fill_stroke_path(gx_default_fill_stroke_path); +dev_proc_lock_pattern(gx_default_lock_pattern); dev_proc_begin_transparency_group(gx_default_begin_transparency_group); dev_proc_end_transparency_group(gx_default_end_transparency_group); dev_proc_begin_transparency_mask(gx_default_begin_transparency_mask); @@ -418,6 +419,7 @@ dev_proc_strip_tile_rect_devn(gx_forward_strip_tile_rect_devn); dev_proc_copy_alpha_hl_color(gx_forward_copy_alpha_hl_color); dev_proc_transform_pixel_region(gx_forward_transform_pixel_region); dev_proc_fill_stroke_path(gx_forward_fill_stroke_path); +dev_proc_lock_pattern(gx_forward_lock_pattern); void gx_forward_device_initialize_procs(gx_device *dev); /* ---------------- Implementation utilities ---------------- */ diff --git a/base/gxfill.c b/base/gxfill.c index e33cb7787..81b5ba50c 100644 --- a/base/gxfill.c +++ b/base/gxfill.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2021 Artifex Software, Inc. +/* Copyright (C) 2001-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -670,6 +670,15 @@ gx_default_fill_path(gx_device * pdev, const gs_gstate * pgs, return gx_general_fill_path(pdev, pgs, ppath, params, pdevc, pcpath); } +int +gx_default_lock_pattern(gx_device *pdev, + gs_gstate *pgs, + gs_id pattern_id, + int lock) +{ + return gx_pattern_cache_entry_set_lock(pgs, pattern_id, lock); +} + /* * Fill/Stroke a path. This is the default implementation of the driver * fill_path procedure. diff --git a/base/gxpcmap.c b/base/gxpcmap.c index 86af08854..a85aafd72 100644 --- a/base/gxpcmap.c +++ b/base/gxpcmap.c @@ -133,6 +133,7 @@ pattern_accum_initialize_device_procs(gx_device *dev) set_dev_proc(dev, strip_tile_rect_devn, gx_default_strip_tile_rect_devn); set_dev_proc(dev, transform_pixel_region, gx_default_transform_pixel_region); set_dev_proc(dev, fill_stroke_path, gx_default_fill_stroke_path); + set_dev_proc(dev, lock_pattern, gx_default_lock_pattern); set_dev_proc(dev, copy_alpha_hl_color, gx_default_copy_alpha_hl_color); } |