diff options
author | Robin Watts <Robin.Watts@artifex.com> | 2022-01-19 11:25:34 +0000 |
---|---|---|
committer | Robin Watts <Robin.Watts@artifex.com> | 2022-01-19 14:47:43 +0000 |
commit | 9005cc3889222a4f5f0b77932e82cadf23c31151 (patch) | |
tree | 0633debaa1f1153f8f902f21fd55e60d4646a91d /base | |
parent | 10bc8def15b55415aa2776b675144ebc6ec9b4a8 (diff) | |
download | ghostpdl-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.h | 6 | ||||
-rw-r--r-- | base/gsicc_lcms2.c | 15 | ||||
-rw-r--r-- | base/gsicc_lcms2mt.c | 15 | ||||
-rw-r--r-- | base/gslibctx.c | 40 | ||||
-rw-r--r-- | base/gslibctx.h | 6 |
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); |