summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Liddell <chris.liddell@artifex.com>2016-02-03 09:07:57 +0000
committerChris Liddell <chris.liddell@artifex.com>2016-02-04 09:04:57 +0000
commit8a3b3487d4946e0b66388c2602d70a5ed45193ff (patch)
tree2412e3ff14bde98eaf05299977ebc5aad159a65d
parentf8e77523b98f0e95e0d93fa282d6955f8f537eea (diff)
downloadghostpdl-8a3b3487d4946e0b66388c2602d70a5ed45193ff.tar.gz
Don't use stack allocation for text enum
Text (and show) enumeators can no longer be safely allocated on the stack since we need the memory manager's metadata to check the type (show or text) we're dealing with (to correctly handle an error condition without crashing).
-rw-r--r--base/gstext.c19
-rw-r--r--base/gxtext.h7
-rw-r--r--pcl/pl/plfapi.c40
3 files changed, 51 insertions, 15 deletions
diff --git a/base/gstext.c b/base/gstext.c
index 514740f2f..83838f923 100644
--- a/base/gstext.c
+++ b/base/gstext.c
@@ -195,6 +195,25 @@ gs_text_enum_init(gs_text_enum_t *pte, const gs_text_enum_procs_t *procs,
return code;
}
+gs_text_enum_t *
+gs_text_enum_alloc(gs_memory_t * mem, gs_imager_state * pis, client_name_t cname)
+{
+ gs_text_enum_t *penum;
+
+ rc_alloc_struct_1(penum, gs_text_enum_t, &st_gs_text_enum, mem,
+ return 0, cname);
+ penum->rc.free = rc_free_text_enum;
+
+ /* Initialize pointers for GC */
+ penum->text.operation = 0; /* no pointers relevant */
+ penum->dev = 0;
+ penum->pis = pis;
+ penum->fapi_log2_scale.x = penum->fapi_log2_scale.y = -1;
+ penum->fapi_glyph_shift.x = penum->fapi_glyph_shift.y = 0;
+ penum->fstack.depth = -1;
+ return penum;
+}
+
/*
* Copy the dynamically changing elements from one enumerator to another.
* This is useful primarily for enumerators that sometimes pass the
diff --git a/base/gxtext.h b/base/gxtext.h
index 9d6737235..8ee3cfe9b 100644
--- a/base/gxtext.h
+++ b/base/gxtext.h
@@ -185,6 +185,13 @@ int gs_text_enum_init(gs_text_enum_t *pte,
const gx_clip_path *pcpath,
gs_memory_t *mem);
+/* Allocate a text enumerator.
+ * This is primarily intended for code avoiding the device API, such
+ * as that purely for retrieving metrics
+ */
+gs_text_enum_t *
+gs_text_enum_alloc(gs_memory_t * mem, gs_imager_state * pis, client_name_t cname);
+
/*
* Copy the dynamically changing elements from one enumerator to another.
* This is useful primarily for enumerators that sometimes pass the
diff --git a/pcl/pl/plfapi.c b/pcl/pl/plfapi.c
index 4ddd3c688..1b36a04f5 100644
--- a/pcl/pl/plfapi.c
+++ b/pcl/pl/plfapi.c
@@ -465,12 +465,13 @@ pl_fapi_get_mtype_font_scaleFactor(gs_font * pfont, uint * scaleFactor)
}
static text_enum_proc_is_width_only(pl_show_text_is_width_only);
+static text_enum_proc_release(pl_text_release);
static const gs_text_enum_procs_t null_text_procs = {
NULL, NULL,
pl_show_text_is_width_only, NULL,
NULL, NULL,
- NULL
+ pl_text_release
};
static bool
@@ -479,6 +480,13 @@ pl_show_text_is_width_only(const gs_text_enum_t *pte)
return(true);
}
+void pl_text_release(gs_text_enum_t *pte, client_name_t cname)
+{
+ (void)pte;
+ (void)cname;
+ return;
+}
+
static int
pl_fapi_set_cache_metrics(gs_text_enum_t * penum, const gs_font_base * pbfont,
const gs_string * char_name, int cid,
@@ -498,7 +506,7 @@ pl_fapi_char_metrics(const pl_font_t * plfont, const void *vpgs,
gs_char char_code, float metrics[4])
{
int code = 0;
- gs_text_enum_t penum1;
+ gs_text_enum_t *penum1;
gs_font *pfont = plfont->pfont;
gs_font_base *pbfont = (gs_font_base *) pfont;
gs_text_params_t text;
@@ -563,25 +571,27 @@ pl_fapi_char_metrics(const pl_font_t * plfont, const void *vpgs,
text.data.chars = buf;
text.size = 1;
- if ((code = gs_text_enum_init(&penum1, &null_text_procs,
- NULL, NULL, &text, pfont,
- NULL, NULL, NULL, pfont->memory)) >= 0) {
+ if ((penum1 = gs_text_enum_alloc(pfont->memory, (gs_imager_state *)pgs,
+ "pl_fapi_char_metrics")) != NULL) {
- penum1.pis = (gs_imager_state *)pgs;
+ if ((code = gs_text_enum_init(penum1, &null_text_procs,
+ NULL, (gs_imager_state *)pgs, &text, pfont,
+ NULL, NULL, NULL, pfont->memory)) >= 0) {
- code = gs_fapi_do_char(pfont, pgs, &penum1, plfont->font_file, false,
- NULL, NULL, char_code, glyph, 0);
+ code = gs_fapi_do_char(pfont, pgs, penum1, plfont->font_file, false,
+ NULL, NULL, char_code, glyph, 0);
- if (code >= 0 || code == gs_error_unknownerror) {
- metrics[0] = metrics[1] = 0;
- metrics[2] = penum1.returned.total_width.x;
- metrics[3] = penum1.returned.total_width.y;
- if (code < 0)
- code = 0;
+ if (code >= 0 || code == gs_error_unknownerror) {
+ metrics[0] = metrics[1] = 0;
+ metrics[2] = penum1->returned.total_width.x;
+ metrics[3] = penum1->returned.total_width.y;
+ if (code < 0)
+ code = 0;
+ }
}
+ rc_decrement(penum1, "pl_fapi_char_metrics");
}
pfont->FontMatrix = fmat;
-
I->ff.fapi_set_cache = tmp_ff.fapi_set_cache;
}
return (code);