summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2018-09-05 18:07:40 +0100
committerRobin Watts <robin.watts@artifex.com>2018-09-05 19:20:15 +0100
commit2b533271d8bd915593a2f8e1a1f446ee940c7d76 (patch)
treeb15eb5abb50cdf3072fae00c098dab0b70b3b2fd
parenta8c7899267121cb92503fe0f7e7f6ae433c386b1 (diff)
downloadghostpdl-2b533271d8bd915593a2f8e1a1f446ee940c7d76.tar.gz
Fix arg_copy leaks.
When handling -d or -s args, the code currently arg_copies the string it gets back, then uses that copied block to make postscript names from. Here we change the code so that postscript names are made in a slightly different way, so they copy the string content. This means we can free the arg_copied block afterwards, solving the leaks. While we are here, remove a layer of nasty variable hiding macros that do nothing but confuse things.
-rw-r--r--psi/iddict.h2
-rw-r--r--psi/idict.c17
-rw-r--r--psi/idict.h6
-rw-r--r--psi/iinit.c42
-rw-r--r--psi/imain.c6
-rw-r--r--psi/imainarg.c34
-rw-r--r--psi/interp.h4
7 files changed, 77 insertions, 34 deletions
diff --git a/psi/iddict.h b/psi/iddict.h
index 67e6b887c..53d864b54 100644
--- a/psi/iddict.h
+++ b/psi/iddict.h
@@ -29,6 +29,8 @@
dict_put(pdref, key, pvalue, &idict_stack)
#define idict_put_string(pdref, kstr, pvalue)\
dict_put_string(pdref, kstr, pvalue, &idict_stack)
+#define idict_put_string_copy(pdref, kstr, pvalue)\
+ dict_put_string_copy(pdref, kstr, pvalue, &idict_stack)
#define idict_undef(pdref, key)\
dict_undef(pdref, key, &idict_stack)
#define idict_copy(dfrom, dto)\
diff --git a/psi/idict.c b/psi/idict.c
index 978f73d92..01d783712 100644
--- a/psi/idict.c
+++ b/psi/idict.c
@@ -555,6 +555,23 @@ dict_put_string(ref * pdref, const char *kstr, const ref * pvalue,
return dict_put(pdref, &kname, pvalue, pds);
}
+/*
+ * Enter a key-value pair where the key is a C string that must be copied.
+ */
+int
+dict_put_string_copy(ref * pdref, const char *kstr, const ref * pvalue,
+ dict_stack_t *pds)
+{
+ int code;
+ ref kname;
+ dict *pdict = pdref->value.pdict;
+
+ if ((code = name_ref(dict_mem(pdict),
+ (const byte *)kstr, strlen(kstr), &kname, 1)) < 0)
+ return code;
+ return dict_put(pdref, &kname, pvalue, pds);
+}
+
/* Remove an element from a dictionary. */
int
dict_undef(ref * pdref, const ref * pkey, dict_stack_t *pds)
diff --git a/psi/idict.h b/psi/idict.h
index 31d33872b..c18d4f15e 100644
--- a/psi/idict.h
+++ b/psi/idict.h
@@ -125,6 +125,12 @@ int dict_put_string(ref * pdref, const char *kstr, const ref * pvalue,
dict_stack_t *pds);
/*
+ * Enter a key-value pair where the key is a (transient) C string.
+ */
+int dict_put_string_copy(ref * pdref, const char *kstr, const ref * pvalue,
+ dict_stack_t *pds);
+
+/*
* Remove a key-value pair from a dictionary.
* Return any of the same values as dict_put, except for 0 and gs_error_dictfull
* which are converted to gs_error_undefined.
diff --git a/psi/iinit.c b/psi/iinit.c
index 3c4ccdced..1e2c46da8 100644
--- a/psi/iinit.c
+++ b/psi/iinit.c
@@ -105,6 +105,24 @@ i_initial_enter_name(i_ctx_t *i_ctx_p, const char *nstr, const ref * pref)
return i_initial_enter_name_in(i_ctx_p, systemdict, nstr, pref);
}
+/* Enter a name and value into a dictionary. */
+static int
+i_initial_enter_name_copy_in(i_ctx_t *i_ctx_p, ref *pdict, const char *nstr,
+ const ref * pref)
+{
+ int code = idict_put_string_copy(pdict, nstr, pref);
+
+ if (code < 0)
+ lprintf4("initial_enter failed (%d), entering /%s in -dict:%u/%u-\n",
+ code, nstr, dict_length(pdict), dict_maxlength(pdict));
+ return code;
+}
+int
+i_initial_enter_name_copy(i_ctx_t *i_ctx_p, const char *nstr, const ref * pref)
+{
+ return i_initial_enter_name_copy_in(i_ctx_p, systemdict, nstr, pref);
+}
+
/* Remove a name from systemdict. */
void
i_initial_remove_name(i_ctx_t *i_ctx_p, const char *nstr)
@@ -297,7 +315,7 @@ obj_init(i_ctx_t **pi_ctx_p, gs_dual_memory_t *idmem)
}
/* Enter names of referenced initial dictionaries into systemdict. */
- initial_enter_name("systemdict", systemdict);
+ i_initial_enter_name(i_ctx_p, "systemdict", systemdict);
for (i = 0; i < icount; i++) {
ref *idict = &idicts[i];
@@ -314,8 +332,8 @@ obj_init(i_ctx_t **pi_ctx_p, gs_dual_memory_t *idmem)
uint save_space = r_space(systemdict);
r_set_space(systemdict, avm_local);
- code = initial_enter_name(initial_dictionaries[i].name,
- idict);
+ code = i_initial_enter_name(i_ctx_p, initial_dictionaries[i].name,
+ idict);
r_set_space(systemdict, save_space);
if (code < 0)
return code;
@@ -336,9 +354,9 @@ obj_init(i_ctx_t **pi_ctx_p, gs_dual_memory_t *idmem)
make_null(&vnull);
make_true(&vtrue);
make_false(&vfalse);
- if ((code = initial_enter_name("null", &vnull)) < 0 ||
- (code = initial_enter_name("true", &vtrue)) < 0 ||
- (code = initial_enter_name("false", &vfalse)) < 0
+ if ((code = i_initial_enter_name(i_ctx_p, "null", &vnull)) < 0 ||
+ (code = i_initial_enter_name(i_ctx_p, "true", &vtrue)) < 0 ||
+ (code = i_initial_enter_name(i_ctx_p, "false", &vfalse)) < 0
)
return code;
}
@@ -356,7 +374,7 @@ obj_init(i_ctx_t **pi_ctx_p, gs_dual_memory_t *idmem)
if ((code = name_enter_string(imemory, (const char *)gs_error_names[i],
era.value.refs + i)) < 0)
return code;
- return initial_enter_name("ErrorNames", &era);
+ return i_initial_enter_name(i_ctx_p, "ErrorNames", &era);
}
}
@@ -398,11 +416,11 @@ zop_init(i_ctx_t *i_ctx_p)
(const byte *)gs_productfamily);
make_int(&vre, gs_revision);
make_int(&vrd, gs_revisiondate);
- if ((code = initial_enter_name("copyright", &vcr)) < 0 ||
- (code = initial_enter_name("product", &vpr)) < 0 ||
- (code = initial_enter_name("productfamily", &vpf)) < 0 ||
- (code = initial_enter_name("revision", &vre)) < 0 ||
- (code = initial_enter_name("revisiondate", &vrd)) < 0)
+ if ((code = i_initial_enter_name(i_ctx_p, "copyright", &vcr)) < 0 ||
+ (code = i_initial_enter_name(i_ctx_p, "product", &vpr)) < 0 ||
+ (code = i_initial_enter_name(i_ctx_p, "productfamily", &vpf)) < 0 ||
+ (code = i_initial_enter_name(i_ctx_p, "revision", &vre)) < 0 ||
+ (code = i_initial_enter_name(i_ctx_p, "revisiondate", &vrd)) < 0)
return code;
}
diff --git a/psi/imain.c b/psi/imain.c
index 138bfc82b..9fc72bb10 100644
--- a/psi/imain.c
+++ b/psi/imain.c
@@ -264,18 +264,18 @@ int gs_main_init2aux(gs_main_instance * minst) {
/* Set up the array of additional initialization files. */
make_const_string(&ifa, a_readonly | avm_foreign, gs_init_files_sizeof - 2, gs_init_files);
- code = initial_enter_name("INITFILES", &ifa);
+ code = i_initial_enter_name(i_ctx_p, "INITFILES", &ifa);
if (code < 0)
return code;
/* Set up the array of emulator names. */
make_const_string(&ifa, a_readonly | avm_foreign, gs_emulators_sizeof - 2, gs_emulators);
- code = initial_enter_name("EMULATORS", &ifa);
+ code = i_initial_enter_name(i_ctx_p, "EMULATORS", &ifa);
if (code < 0)
return code;
/* Pass the search path. */
- code = initial_enter_name("LIBPATH", &minst->lib_path.list);
+ code = i_initial_enter_name(i_ctx_p, "LIBPATH", &minst->lib_path.list);
if (code < 0)
return code;
diff --git a/psi/imainarg.c b/psi/imainarg.c
index fb16f4b07..9cd62c821 100644
--- a/psi/imainarg.c
+++ b/psi/imainarg.c
@@ -312,9 +312,6 @@ swproc(gs_main_instance * minst, const char *arg, arg_list * pal)
char sw = arg[1];
ref vtrue;
int code = 0;
-#undef initial_enter_name
-#define initial_enter_name(nstr, pvalue)\
- i_initial_enter_name(minst->i_ctx_p, nstr, pvalue)
make_true(&vtrue);
arg += 2; /* skip - and letter */
@@ -603,10 +600,10 @@ run_stdin:
return gs_error_Fatal;
}
make_int(&value, width);
- initial_enter_name("DEVICEWIDTH", &value);
+ i_initial_enter_name(minst->i_ctx_p, "DEVICEWIDTH", &value);
make_int(&value, height);
- initial_enter_name("DEVICEHEIGHT", &value);
- initial_enter_name("FIXEDMEDIA", &vtrue);
+ i_initial_enter_name(minst->i_ctx_p, "DEVICEHEIGHT", &value);
+ i_initial_enter_name(minst->i_ctx_p, "FIXEDMEDIA", &vtrue);
break;
}
case 'h': /* print help */
@@ -705,9 +702,9 @@ run_stdin:
memcpy(str, adef, len);
make_const_string(&value, a_readonly | avm_system, len, str);
ialloc_set_space(idmemory, space);
- initial_enter_name("OutputFile", &value);
- initial_enter_name("NOPAUSE", &vtrue);
- initial_enter_name("BATCH", &vtrue);
+ i_initial_enter_name(minst->i_ctx_p, "OutputFile", &value);
+ i_initial_enter_name(minst->i_ctx_p, "NOPAUSE", &vtrue);
+ i_initial_enter_name(minst->i_ctx_p, "BATCH", &vtrue);
}
break;
case 'P': /* choose whether search '.' first */
@@ -723,7 +720,7 @@ run_stdin:
case 'q': /* quiet startup */
if ((code = gs_main_init1(minst)) < 0)
return code;
- initial_enter_name("QUIET", &vtrue);
+ i_initial_enter_name(minst->i_ctx_p, "QUIET", &vtrue);
break;
case 'r': /* define device resolution */
{
@@ -741,10 +738,10 @@ run_stdin:
/* fall through */
case 2: /* -r<xres>x<yres> */
make_real(&value, xres);
- initial_enter_name("DEVICEXRESOLUTION", &value);
+ i_initial_enter_name(minst->i_ctx_p, "DEVICEXRESOLUTION", &value);
make_real(&value, yres);
- initial_enter_name("DEVICEYRESOLUTION", &value);
- initial_enter_name("FIXEDRESOLUTION", &vtrue);
+ i_initial_enter_name(minst->i_ctx_p, "DEVICEYRESOLUTION", &value);
+ i_initial_enter_name(minst->i_ctx_p, "FIXEDRESOLUTION", &vtrue);
}
break;
}
@@ -772,6 +769,7 @@ run_stdin:
}
if (eqp == adef) {
puts(minst->heap, "Usage: -dNAME, -dNAME=TOKEN, -sNAME=STRING");
+ arg_free((char *)adef, minst->heap);
return gs_error_Fatal;
}
if (eqp == NULL) {
@@ -828,6 +826,7 @@ run_stdin:
code = gs_scan_token(minst->i_ctx_p, &value, &state);
if (code) {
outprintf(minst->heap, "Invalid value for option -d%s, -dNAME= must be followed by a valid token\n", arg);
+ arg_free((char *)adef, minst->heap);
return gs_error_Fatal;
}
if (r_has_type_attrs(&value, t_name,
@@ -847,6 +846,7 @@ run_stdin:
make_false(&value);
else {
outprintf(minst->heap, "Invalid value for option -d%s, use -sNAME= to define string constants\n", arg);
+ arg_free((char *)adef, minst->heap);
return gs_error_Fatal;
}
}
@@ -857,17 +857,21 @@ run_stdin:
if (body == NULL) {
lprintf("Out of memory!\n");
+ arg_free((char *)adef, minst->heap);
return gs_error_Fatal;
}
memcpy(body, eqp, len);
make_const_string(&value, a_readonly | avm_system, len, body);
- if ((code = try_stdout_redirect(minst, adef, eqp)) < 0)
+ if ((code = try_stdout_redirect(minst, adef, eqp)) < 0) {
+ arg_free((char *)adef, minst->heap);
return code;
+ }
}
ialloc_set_space(idmemory, space);
}
/* Enter the name in systemdict. */
- initial_enter_name(adef, &value);
+ i_initial_enter_name_copy(minst->i_ctx_p, adef, &value);
+ arg_free((char *)adef, minst->heap);
break;
}
case 'u': /* undefine name */
diff --git a/psi/interp.h b/psi/interp.h
index 10c037a75..5e5ca583e 100644
--- a/psi/interp.h
+++ b/psi/interp.h
@@ -23,13 +23,9 @@
/* Enter a name and value into systemdict. */
int i_initial_enter_name(i_ctx_t *, const char *, const ref *);
-#define initial_enter_name(nstr, pvalue)\
- i_initial_enter_name(i_ctx_p, nstr, pvalue)
/* Remove a name from systemdict. */
void i_initial_remove_name(i_ctx_t *, const char *);
-#define initial_remove_name(nstr)\
- i_initial_remove_name(i_ctx_p, nstr)
/* ------ interp.c ------ */