diff options
author | Chris Liddell <chris.liddell@artifex.com> | 2021-06-18 12:00:17 +0100 |
---|---|---|
committer | Chris Liddell <chris.liddell@artifex.com> | 2021-06-18 13:25:06 +0100 |
commit | e9ac9ec0bfa060aecc23440451c75c859c62206a (patch) | |
tree | 7d15cf71c9822e29b526a181f69c2a26f906c9f1 | |
parent | 2b9fab55953ae02f94ed15b2939c1f4a59dce8be (diff) | |
download | ghostpdl-e9ac9ec0bfa060aecc23440451c75c859c62206a.tar.gz |
Pattern instance life span problem with pdfi in gsgpdf_gs_text_filter_032
When pdfi is called from gs (i.e. using the gs graphics state), the pattern
tile cache exists outside, and lasts beyond the "life", of the pdfi instance.
But pattern instances do not. That causes a crash when Ghostscript runs the
end of job restore, and the garbager tries to access the pattern instance, via
the clist accumulator device in the pattern tile cache.
So, have pdfi remove tile cache entries for relevant patterns when the pattern
instances get freed.
-rw-r--r-- | pdf/pdf_pattern.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/pdf/pdf_pattern.c b/pdf/pdf_pattern.c index a66b6ba52..c0432343c 100644 --- a/pdf/pdf_pattern.c +++ b/pdf/pdf_pattern.c @@ -111,13 +111,32 @@ static void pdfi_free_pattern_context(pdf_pattern_context_t *context) gs_free_object(context->ctx->memory, context, "Free pattern context"); } +static bool +pdfi_pattern_purge_proc(gx_color_tile * ctile, void *proc_data) +{ + gs_id id = (gs_id)proc_data; + if (ctile->id == id) + return true; + return false; +} + void pdfi_pattern_cleanup(gs_memory_t * mem, void *p) { gs_pattern1_instance_t *pinst = (gs_pattern1_instance_t *)p; pdf_pattern_context_t *context; + gx_color_tile *pctile = NULL; context = (pdf_pattern_context_t *)pinst->client_data; + /* If are being called from Ghostscript, the clist pattern accumulator device (in + the tile cache) *can* outlast outlast our pattern instance, so if the pattern + instance is being freed, also remove the entry from the cache + */ + if (gx_pattern_cache_get_entry(context->ctx->pgs, pinst->id, &pctile) == 0 + && gx_pattern_tile_is_clist(pctile)) { + gx_pattern_cache_winnow(gstate_pattern_cache(context->ctx->pgs), pdfi_pattern_purge_proc, (void *)(pctile->id)); + } + if (context != NULL) { pdfi_free_pattern_context(context); pinst->client_data = NULL; |