summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <Robin.Watts@artifex.com>2022-04-05 16:34:45 +0100
committerRobin Watts <Robin.Watts@artifex.com>2022-04-07 18:23:27 +0100
commitdb5f053a2838f6fdb69b387e0f8ef70daca59a96 (patch)
tree5fab3faf938387708f46e8a0f740643db836410e
parentd6f88ef54434fcfc6dcefdcfe21bab1b1b77508b (diff)
downloadghostpdl-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.c1
-rw-r--r--base/gdevepo.c3
-rw-r--r--base/gdevnfwd.c16
-rw-r--r--base/gdevsclass.c10
-rw-r--r--base/gdevsclass.h3
-rw-r--r--base/gsovrc.c3
-rw-r--r--base/gspaint.c14
-rw-r--r--base/gxcldev.h6
-rw-r--r--base/gxclipm.c3
-rw-r--r--base/gxclist.c1
-rw-r--r--base/gxclpath.c22
-rw-r--r--base/gxclpath.h3
-rw-r--r--base/gxclrast.c46
-rw-r--r--base/gxdevcli.h13
-rw-r--r--base/gxdevice.h4
-rw-r--r--base/gxfill.c11
-rw-r--r--base/gxpcmap.c1
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);
}