summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Liddell <chris.liddell@artifex.com>2023-04-21 11:59:37 +0100
committerChris Liddell <chris.liddell@artifex.com>2023-04-21 13:48:10 +0100
commitb0739b945394ec81a5420cf02e951fae26923dce (patch)
treee61ed78fea8a01c11f67c836b0234a16fc8f1922
parent1b160b94329d28f5c0b7bc682abd6335175bd50e (diff)
downloadghostpdl-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.c23
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) {