summaryrefslogtreecommitdiff
path: root/base
diff options
context:
space:
mode:
authorRobin Watts <Robin.Watts@artifex.com>2022-01-19 11:25:34 +0000
committerRobin Watts <Robin.Watts@artifex.com>2022-01-19 14:47:43 +0000
commit9005cc3889222a4f5f0b77932e82cadf23c31151 (patch)
tree0633debaa1f1153f8f902f21fd55e60d4646a91d /base
parent10bc8def15b55415aa2776b675144ebc6ec9b4a8 (diff)
downloadghostpdl-9005cc3889222a4f5f0b77932e82cadf23c31151.tar.gz
Bug 704692: Fix gs_memory_t mismatch in cms alloc/free operations.
We generate a cmsContext to use at gs_lib_ctx startup, and then use that for every call into the cms. This encapsulates the gs_memory_t. For gs/pcl/xps etc this works well, as there is only a single interpreter, hence a single cmsContext. Unfortunately, for gpdl, each interpreter (potentially) gets its own cmsContext (certainly, the PS interpreter does). So on startup, when the PS interpreter initialises, it loads some default profiles and allocates them with one gs_memory_t. When we then come to read a profile using another interpreter (in this case, tiff), we read that using a different gs_memory_t. Because the icc_cache is stored in the device, it is shared across all the different interpreters, so we can end up with a mixture of blocks allocated with different gs_memory_t's. If we stored which gs_memory_t * had been used to allocate each block with the block we'd be fine - but we don't. Accordingly, when we closedown, blocks are 'freed' with the wrong gs_memory_t, causing problems. The simplest solution here (short of updating the memory wrappers that we pass into lcms2/lcms2mt to store gs_memory_t's in every block, with the attendant memory increase this would cause) is to move the cmsContext from gs_lib_ctx_t to the gs_lib_ctx core. In this way we only have a single cmsContext shared across all the different interpreters. This feels like the correct solution to me.
Diffstat (limited to 'base')
-rw-r--r--base/gsicc_cms.h6
-rw-r--r--base/gsicc_lcms2.c15
-rw-r--r--base/gsicc_lcms2mt.c15
-rw-r--r--base/gslibctx.c40
-rw-r--r--base/gslibctx.h6
5 files changed, 37 insertions, 45 deletions
diff --git a/base/gsicc_cms.h b/base/gsicc_cms.h
index b9b38f93b..d3e0e1dee 100644
--- a/base/gsicc_cms.h
+++ b/base/gsicc_cms.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
@@ -76,8 +76,8 @@ gcmmhlink_t gscms_get_link_proof_devlink(gcmmhprofile_t lcms_srchandle,
gsicc_rendering_param_t *rendering_params,
bool src_dev_link, int cmm_flags,
gs_memory_t *memory);
-int gscms_create(gs_memory_t *memory);
-void gscms_destroy(gs_memory_t *memory);
+void *gscms_create(gs_memory_t *memory);
+void gscms_destroy(void *);
void gscms_release_link(gsicc_link_t *icclink);
void gscms_release_profile(void *profile, gs_memory_t *memory);
int gscms_transform_named_color(gsicc_link_t *icclink, float tint_value,
diff --git a/base/gsicc_lcms2.c b/base/gsicc_lcms2.c
index 9badb6dee..3c2d1d579 100644
--- a/base/gsicc_lcms2.c
+++ b/base/gsicc_lcms2.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
@@ -731,7 +731,7 @@ gscms_get_link_proof_devlink(gcmmhprofile_t lcms_srchandle,
}
/* Do any initialization if needed to the CMS */
-int
+void *
gscms_create(gs_memory_t *memory)
{
cmsContext ctx;
@@ -739,27 +739,26 @@ gscms_create(gs_memory_t *memory)
/* Set our own error handling function */
ctx = cmsCreateContext((void *)&gs_cms_memhandler, memory);
if (ctx == NULL)
- return_error(gs_error_VMerror);
+ return NULL;
#ifdef USE_LCMS2_LOCKING
cmsPluginTHR(ctx, (void *)&gs_cms_mutexhandler);
#endif
cmsSetLogErrorHandlerTHR(ctx, gscms_error);
- gs_lib_ctx_set_cms_context(memory, ctx);
- return 0;
+
+ return ctx;
}
/* Do any clean up when done with the CMS if needed */
void
-gscms_destroy(gs_memory_t *memory)
+gscms_destroy(void *cmsContext_)
{
- cmsContext ctx = gs_lib_ctx_get_cms_context(memory);
+ cmsContext ctx = (cmsContext)cmsContext_;
if (ctx == NULL)
return;
cmsDeleteContext(ctx);
- gs_lib_ctx_set_cms_context(memory, NULL);
}
/* Have the CMS release the link */
diff --git a/base/gsicc_lcms2mt.c b/base/gsicc_lcms2mt.c
index b0d854051..ac83787b9 100644
--- a/base/gsicc_lcms2mt.c
+++ b/base/gsicc_lcms2mt.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
@@ -877,7 +877,7 @@ gscms_get_link_proof_devlink(gcmmhprofile_t lcms_srchandle,
}
/* Do any initialization if needed to the CMS */
-int
+void *
gscms_create(gs_memory_t *memory)
{
cmsContext ctx;
@@ -885,7 +885,7 @@ gscms_create(gs_memory_t *memory)
/* Set our own error handling function */
ctx = cmsCreateContext((void *)&gs_cms_memhandler, memory);
if (ctx == NULL)
- return_error(gs_error_VMerror);
+ return NULL;
#ifdef USE_LCMS2_LOCKING
cmsPlugin(ctx, (void *)&gs_cms_mutexhandler);
@@ -897,20 +897,19 @@ gscms_create(gs_memory_t *memory)
#endif
cmsSetLogErrorHandler(ctx, gscms_error);
- gs_lib_ctx_set_cms_context(memory, ctx);
- return 0;
+
+ return ctx;
}
/* Do any clean up when done with the CMS if needed */
void
-gscms_destroy(gs_memory_t *memory)
+gscms_destroy(void *cmsContext_)
{
- cmsContext ctx = gs_lib_ctx_get_cms_context(memory);
+ cmsContext ctx = (cmsContext)cmsContext_;
if (ctx == NULL)
return;
cmsDeleteContext(ctx);
- gs_lib_ctx_set_cms_context(memory, NULL);
}
/* Have the CMS release the link */
diff --git a/base/gslibctx.c b/base/gslibctx.c
index 0bb427b51..11dd00aed 100644
--- a/base/gslibctx.c
+++ b/base/gslibctx.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
@@ -325,15 +325,8 @@ int gs_lib_ctx_init(gs_lib_ctx_t *ctx, gs_memory_t *mem)
pio->core->fs->next = NULL;
pio->core->monitor = gx_monitor_alloc(mem);
- if (pio->core->monitor == NULL) {
-#ifdef WITH_CAL
- cal_fin(pio->core->cal_ctx, mem);
-#endif
- gs_free_object(mem, pio->core->fs, "gs_lib_ctx_init");
- gs_free_object(mem, pio->core, "gs_lib_ctx_init");
- gs_free_object(mem, pio, "gs_lib_ctx_init");
- return -1;
- }
+ if (pio->core->monitor == NULL)
+ goto core_create_failed;
pio->core->refs = 1;
pio->core->memory = mem;
@@ -344,6 +337,18 @@ int gs_lib_ctx_init(gs_lib_ctx_t *ctx, gs_memory_t *mem)
pio->core->gs_next_id = 5; /* Cloned contexts share the state */
/* Set scanconverter to 1 (default) */
pio->core->scanconverter = GS_SCANCONVERTER_DEFAULT;
+ /* Initialise the underlying CMS. */
+ pio->core->cms_context = gscms_create(mem);
+ if (pio->core->cms_context == NULL) {
+core_create_failed:
+#ifdef WITH_CAL
+ cal_fin(pio->core->cal_ctx, mem);
+#endif
+ gs_free_object(mem, pio->core->fs, "gs_lib_ctx_init");
+ gs_free_object(mem, pio->core, "gs_lib_ctx_init");
+ gs_free_object(mem, pio, "gs_lib_ctx_init");
+ return -1;
+ }
}
/* Now set the non zero/false/NULL things */
@@ -362,10 +367,6 @@ int gs_lib_ctx_init(gs_lib_ctx_t *ctx, gs_memory_t *mem)
strlen(gs_dev_defaults)) < 0)
goto Failure;
- /* Initialise the underlying CMS. */
- if (gscms_create(mem))
- goto Failure;
-
/* Initialise any lock required for the jpx codec */
if (sjpxd_create(mem))
goto Failure;
@@ -417,7 +418,6 @@ void gs_lib_ctx_fin(gs_memory_t *mem)
ctx_mem = ctx->memory;
sjpxd_destroy(mem);
- gscms_destroy(ctx_mem);
gs_free_object(ctx_mem, ctx->profiledir,
"gs_lib_ctx_fin");
@@ -432,6 +432,7 @@ void gs_lib_ctx_fin(gs_memory_t *mem)
refs = --ctx->core->refs;
gx_monitor_leave((gx_monitor_t *)(ctx->core->monitor));
if (refs == 0) {
+ gscms_destroy(ctx->core->cms_context);
gx_monitor_free((gx_monitor_t *)(ctx->core->monitor));
#ifdef WITH_CAL
cal_fin(ctx->core->cal_ctx, ctx->core->memory);
@@ -477,14 +478,7 @@ void *gs_lib_ctx_get_cms_context( const gs_memory_t *mem )
{
if (mem == NULL)
return NULL;
- return mem->gs_lib_ctx->cms_context;
-}
-
-void gs_lib_ctx_set_cms_context( const gs_memory_t *mem, void *cms_context )
-{
- if (mem == NULL)
- return;
- mem->gs_lib_ctx->cms_context = cms_context;
+ return mem->gs_lib_ctx->core->cms_context;
}
int gs_lib_ctx_get_act_on_uel( const gs_memory_t *mem )
diff --git a/base/gslibctx.h b/base/gslibctx.h
index 9d1aa921d..c86c90307 100644
--- a/base/gslibctx.h
+++ b/base/gslibctx.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
@@ -133,6 +133,8 @@ typedef struct {
* all builds. */
void *cal_ctx;
+ void *cms_context; /* Opaque context pointer from underlying CMS in use */
+
gs_callout_list_t *callouts;
/* Stashed args */
@@ -180,7 +182,6 @@ typedef struct gs_lib_ctx_s
* and one in the device */
char *profiledir; /* Directory used in searching for ICC profiles */
int profiledir_len; /* length of directory name (allows for Unicode) */
- void *cms_context; /* Opaque context pointer from underlying CMS in use */
gs_fapi_server **fapi_servers;
char *default_device_list;
int gcsignal;
@@ -210,7 +211,6 @@ void gs_lib_ctx_fin( gs_memory_t *mem );
gs_lib_ctx_t *gs_lib_ctx_get_interp_instance( const gs_memory_t *mem );
void *gs_lib_ctx_get_cms_context( const gs_memory_t *mem );
-void gs_lib_ctx_set_cms_context( const gs_memory_t *mem, void *cms_context );
int gs_lib_ctx_get_act_on_uel( const gs_memory_t *mem );
int gs_lib_ctx_register_callout(gs_memory_t *mem, gs_callout_fn, void *arg);