summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Liddell <chris.liddell@artifex.com>2011-07-25 16:25:20 +0100
committerChris Liddell <chris.liddell@artifex.com>2011-07-25 16:30:15 +0100
commitf62ce181e3a68d7f652d9e903c70bd1a67423782 (patch)
treeb6da908e03607ae3f5bc18216b9229f5a7e87081
parent7dee8c1639a55e5b6ae4051afcfed9caa82e48b5 (diff)
Bug 692367: NULL out pointers for three tables in the context
Add "finalize" methods for gs_name_table, io_device_table and font_dir tables which ensure that the pointers in the lib context are set to NULL when the memory is released. No cluster differences.
-rw-r--r--gs/base/gsfont.c9
-rw-r--r--gs/base/gsiodev.c24
-rw-r--r--gs/base/gsstruct.h18
-rw-r--r--gs/base/gxfcache.h4
-rw-r--r--gs/psi/iname.c13
5 files changed, 61 insertions, 7 deletions
diff --git a/gs/base/gsfont.c b/gs/base/gsfont.c
index ece4c9b2b..9535666bf 100644
--- a/gs/base/gsfont.c
+++ b/gs/base/gsfont.c
@@ -270,6 +270,15 @@ gs_font_dir_alloc2_limits(gs_memory_t * struct_mem, gs_memory_t * bits_mem,
pdir->hash = 42; /* initialize the hash to a randomly picked number */
return pdir;
}
+static void
+gs_font_dir_finalize(void *vptr)
+{
+ gs_font_dir *pdir = vptr;
+ if (pdir == pdir->memory->gs_lib_ctx->font_dir) {
+ pdir->memory->gs_lib_ctx->font_dir = NULL;
+ }
+}
+
/* Allocate and minimally initialize a font. */
gs_font *
diff --git a/gs/base/gsiodev.c b/gs/base/gsiodev.c
index 65b279d05..9b6f0e408 100644
--- a/gs/base/gsiodev.c
+++ b/gs/base/gsiodev.c
@@ -31,9 +31,9 @@ extern_gx_io_device_table();
private_st_io_device();
gs_private_st_ptr(st_io_device_ptr, gx_io_device *, "gx_io_device *",
iodev_ptr_enum_ptrs, iodev_ptr_reloc_ptrs);
-gs_private_st_element(st_io_device_ptr_element, gx_io_device *,
+gs_private_st_element_final(st_io_device_ptr_element, gx_io_device *,
"gx_io_device *[]", iodev_ptr_elt_enum_ptrs, iodev_ptr_elt_reloc_ptrs,
- st_io_device_ptr);
+ st_io_device_ptr,gs_iodev_finalize);
/* Define the OS (%os%) device. */
iodev_proc_fopen(iodev_os_fopen);
@@ -61,7 +61,7 @@ int
gs_iodev_init(gs_memory_t * mem)
{ /* Make writable copies of all IODevices. */
gx_io_device **table =
- gs_alloc_struct_array(mem, gx_io_device_table_count,
+ gs_alloc_struct_array(mem, gx_io_device_table_count + 1,
gx_io_device *, &st_io_device_ptr_element,
"gs_iodev_init(table)");
gs_lib_ctx_t *libctx = gs_lib_ctx_get_interp_instance(mem);
@@ -80,6 +80,14 @@ gs_iodev_init(gs_memory_t * mem)
table[i] = iodev;
memcpy(table[i], gx_io_device_table[i], sizeof(gx_io_device));
}
+ /* FIXME: we allocate an extra pointer in the array and stuff
+ * the memory context in there, as we need access to it in the
+ * finalize method below. We get away it because everywhere that
+ * searches the table uses gx_io_device_table_count, rather than
+ * the actuall allocated length.
+ * A less naff solution would be preferable!
+ */
+ table[gx_io_device_table_count] = (gx_io_device *) mem;
libctx->io_device_table = table;
code = gs_register_struct_root(mem, NULL,
(void **)&libctx->io_device_table,
@@ -102,6 +110,16 @@ gs_iodev_init(gs_memory_t * mem)
return (code < 0 ? code : gs_note_error(gs_error_VMerror));
}
+static void
+gs_iodev_finalize(void *vptr)
+{
+ gx_io_device **table = vptr;
+ gs_memory_t * mem = ((gs_memory_t *)table[gx_io_device_table_count]);
+
+ mem->gs_lib_ctx->io_device_table = NULL;
+}
+
+
/* ------ Default (unimplemented) IODevice procedures ------ */
int
diff --git a/gs/base/gsstruct.h b/gs/base/gsstruct.h
index cd33da11a..bdfc3ff64 100644
--- a/gs/base/gsstruct.h
+++ b/gs/base/gsstruct.h
@@ -620,6 +620,24 @@ extern void reloc_const_bytestring(gs_const_bytestring *pbs, gc_state_t *gcst);
#define gs_private_st_element(stname, stype, sname, penum, preloc, basest)\
gs__st_element(private_st, stname, stype, sname, penum, preloc, basest)
+#define gs__st_element_final(scope_st, stname, stype, sname, penum, preloc, basest, pfinal)\
+ static ENUM_PTRS_BEGIN_PROC(penum) {\
+ uint count = size / (uint)sizeof(stype);\
+ if ( count == 0 ) return 0;\
+ return ENUM_USING(basest, (EV_CONST char *)vptr + (index % count) * sizeof(stype),\
+ sizeof(stype), index / count);\
+ } ENUM_PTRS_END_PROC\
+ static RELOC_PTRS_BEGIN(preloc) {\
+ uint count = size / (uint)sizeof(stype);\
+ for ( ; count; count--, vptr = (char *)vptr + sizeof(stype) )\
+ RELOC_USING(basest, vptr, sizeof(stype));\
+ } RELOC_PTRS_END\
+ gs__st_composite_final(scope_st, stname, stype, sname, penum, preloc,pfinal)
+#define gs_public_st_element_final(stname, stype, sname, penum, preloc, basest,pfinal)\
+ gs__st_element_final(public_st, stname, stype, sname, penum, preloc, basest,pfinal)
+#define gs_private_st_element_final(stname, stype, sname, penum, preloc, basest,pfinal)\
+ gs__st_element_final(private_st, stname, stype, sname, penum, preloc, basest,pfinal)
+
/* A "structure" just consisting of a pointer. */
/* Note that in this case only, stype is a pointer type. */
/* Fortunately, C's bizarre 'const' syntax does what we want here. */
diff --git a/gs/base/gxfcache.h b/gs/base/gxfcache.h
index 3f3b5a73c..f6b97360e 100644
--- a/gs/base/gxfcache.h
+++ b/gs/base/gxfcache.h
@@ -319,8 +319,8 @@ struct gs_font_dir_s {
};
#define private_st_font_dir() /* in gsfont.c */\
- gs_private_st_composite(st_font_dir, gs_font_dir, "gs_font_dir",\
- font_dir_enum_ptrs, font_dir_reloc_ptrs)
+ gs_private_st_composite_final(st_font_dir, gs_font_dir, "gs_font_dir",\
+ font_dir_enum_ptrs, font_dir_reloc_ptrs, gs_font_dir_finalize)
/* Enumerate the pointers in a font directory, except for orig_fonts. */
#define font_dir_do_ptrs(m)\
diff --git a/gs/psi/iname.c b/gs/psi/iname.c
index 96a6e8d8a..2d4764e18 100644
--- a/gs/psi/iname.c
+++ b/gs/psi/iname.c
@@ -37,13 +37,15 @@ static const byte nt_1char_names[NT_1CHAR_SIZE] = {
NT_1CHAR_NAMES_DATA
};
+static void gs_names_finalize(void *);
+
/* Structure descriptors */
gs_private_st_simple(st_name_sub_table, name_sub_table, "name_sub_table");
gs_private_st_composite(st_name_string_sub_table, name_string_sub_table_t,
"name_string_sub_table_t",
name_string_sub_enum_ptrs, name_string_sub_reloc_ptrs);
-gs_private_st_composite(st_name_table, name_table, "name_table",
- name_table_enum_ptrs, name_table_reloc_ptrs);
+gs_private_st_composite_final(st_name_table, name_table, "name_table",
+ name_table_enum_ptrs, name_table_reloc_ptrs,gs_names_finalize);
/* Forward references */
static int name_alloc_sub(name_table *);
@@ -127,6 +129,13 @@ names_init(ulong count, gs_ref_memory_t *imem)
return nt;
}
+static void
+gs_names_finalize(void *vptr)
+{
+ name_table *nt = vptr;
+ nt->memory->gs_lib_ctx->gs_name_table = NULL;
+}
+
/* Get the allocator for the name table. */
gs_memory_t *
names_memory(const name_table * nt)