diff options
author | Chris Liddell <chris.liddell@artifex.com> | 2023-04-21 11:59:37 +0100 |
---|---|---|
committer | Chris Liddell <chris.liddell@artifex.com> | 2023-04-21 13:48:10 +0100 |
commit | b0739b945394ec81a5420cf02e951fae26923dce (patch) | |
tree | e61ed78fea8a01c11f67c836b0234a16fc8f1922 | |
parent | 1b160b94329d28f5c0b7bc682abd6335175bd50e (diff) | |
download | ghostpdl-b0739b945394ec81a5420cf02e951fae26923dce.tar.gz |
Avoid in use names being garbage collected
To maintain interoperability with the Postscript interpreter, pdfi shares
the Postscript name table (when it's built into gs, rather than standalone).
On the basis that the name table is cleaned up only with global VM, and that
global VM is only gc'ed at the end of job (we thought!), we thought adding
names to the table was sufficient.
Turns out, there are circumstances under which global VM (and thus the name
table) do get gc'ed before the end of job, and in that case, names pdfi still
relied upon could disappear.
To avoid that, add the names (as key and value) to a Postscript dictionary,
known to the garbager, at the same time as we add them to the name table.
Came up cluster testing a fix for Bug 706595, with file:
tests_private/comparefiles/Bug691740.pdf
-rw-r--r-- | psi/zpdfops.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/psi/zpdfops.c b/psi/zpdfops.c index 20620334a..af93bd06a 100644 --- a/psi/zpdfops.c +++ b/psi/zpdfops.c @@ -409,6 +409,7 @@ typedef struct pdfctx_s { stream *pdf_stream; bool UsingPDFFile; gsicc_profile_cache_t *profile_cache; + ref names_dict; gs_memory_t *cache_memory; /* The memory allocator used to allocate the working (GC'ed) profile cache */ } pdfctx_t; @@ -454,10 +455,13 @@ gs_private_st_composite_final(st_pdfctx_t, pdfctx_t, "pdfctx_struct",\ static ENUM_PTRS_BEGIN(pdfctx_enum_ptrs) return 0; -ENUM_PTR3(0, pdfctx_t, ps_stream, pdf_stream, profile_cache); + ENUM_PTR3(0, pdfctx_t, ps_stream, pdf_stream, profile_cache); + case 3: + ENUM_RETURN_REF(&((pdfctx_t *)vptr)->names_dict); ENUM_PTRS_END static RELOC_PTRS_BEGIN(pdfctx_reloc_ptrs); +RELOC_REF_VAR(((pdfctx_t *)vptr)->names_dict); RELOC_PTR3(pdfctx_t, ps_stream, pdf_stream, profile_cache); RELOC_PTRS_END @@ -469,6 +473,7 @@ pdfctx_finalize(const gs_memory_t *cmem, void *vptr) * on the same object - hence we null the entries. */ + make_null(&pdfctx->names_dict); if (pdfctx->profile_cache != NULL) { rc_decrement(pdfctx->profile_cache, "free the working profile cache"); pdfctx->profile_cache = NULL; @@ -1188,9 +1193,21 @@ static int zpdfi_glyph_index(gs_font *pfont, byte *str, uint size, uint *glyph) { int code = 0; ref nref; + i_ctx_t *i_ctx_p = get_minst_from_memory(pfont->memory)->i_ctx_p; + os_ptr op = osp; + pdfctx_t *pdfctx; + + check_type(*op - 1, t_pdfctx); + pdfctx = r_ptr(op - 1, pdfctx_t); + code = name_ref(pfont->memory, str, size, &nref, true); if (code < 0) return code; + + code = dict_put(&pdfctx->names_dict, &nref, &nref, &i_ctx_p->dict_stack); + if (code < 0) + return code; + *glyph = name_index(pfont->memory, &nref); return 0; } @@ -1561,6 +1578,10 @@ static int zPDFInit(i_ctx_t *i_ctx_p) goto error; } pdfctx->cache_memory = imemory; + /* The size is arbitrary */ + code = dict_alloc(iimemory, 1, &pdfctx->names_dict); + if (code < 0) + goto error; ctx = pdfi_create_context(cmem); if (ctx == NULL) { |