[gs-commits] ghostpdl branch, master, updated. jbig2dec-0.14-1568-g813d7e9
[email protected] (Robin Watts)
| Newsgroups | gmane.comp.printing.ghostscript.cvs |
|---|---|
| Message-ID | <[email protected]> |
The ghostpdl branch, master has been updated
via 813d7e96c8733f85d59a62732171cf7cedfc087d (commit)
via 8ba95fb06387572160fee5e4c1e51d972401566e (commit)
from ddddd71785d058b036775566d36d6848c9817f80 (commit)
----------------------------------------------------------------------
commit 813d7e96c8733f85d59a62732171cf7cedfc087d
Author: Robin Watts <[email protected]>
Date: Mon Aug 12 16:30:46 2019 +0100
Capture args to feed to pdfwrite.
To facilitate debugging, we want a way to pickle the gs invocation
used into device output (for devices that want it).
We therefore amend the argument processing logic to pass arguments
to gs_lib_ctx, where they will are 'sanitized' and stored in a list.
This list can then be accessed by a device.
We are careful to sanitize the args so as not to reveal paths or
secret passwords/code etc. Essentially we never store any filenames
or string values stored (except for certain whitelisted -s options).
It is likely that we'll want to expand the whitelisted values in
future.
diff --git a/base/gsargs.c b/base/gsargs.c
index d5c261e..9e6ca14 100644
--- a/base/gsargs.c
+++ b/base/gsargs.c
@@ -116,7 +116,7 @@ lead: /* We've just read a byte >= 0x80, presumably a leading byte */
}
/* Initialize an arg list. */
-void
+int
arg_init(arg_list * pal,
const char **argv,
int argc,
@@ -125,18 +125,27 @@ arg_init(arg_list * pal,
int (*get_codepoint)(gp_file *file, const char **astr),
gs_memory_t *memory)
{
+ int code;
+ const char *arg;
+
pal->expand_ats = true;
pal->arg_fopen = arg_fopen;
pal->fopen_data = fopen_data;
pal->get_codepoint = (get_codepoint ? get_codepoint : get_codepoint_utf8);
pal->memory = memory;
- pal->argp = argv + 1;
- pal->argn = argc - 1;
+ pal->argp = argv;
+ pal->argn = argc;
pal->depth = 0;
pal->sources[0].is_file = 0;
pal->sources[0].u.s.memory = NULL;
pal->sources[0].u.s.decoded = 0;
pal->sources[0].u.s.parsed = 0;
+
+ /* Stash the 0th one */
+ code = arg_next(pal, &arg, memory);
+ if (code < 0)
+ return code;
+ return gs_lib_ctx_stash_exe(memory->gs_lib_ctx, arg);
}
/* Push a string onto an arg list. */
diff --git a/base/gsargs.h b/base/gsargs.h
index 9398064..e82835c 100644
--- a/base/gsargs.h
+++ b/base/gsargs.h
@@ -58,13 +58,13 @@ typedef struct arg_list_s {
int codepoint_to_utf8(char *cstr, int rune);
/* Initialize an arg list. */
-void arg_init(arg_list *pal,
- const char **argv,
- int argc,
- gp_file *(*arg_fopen)(const char *fname, void *fopen_data),
- void *fopen_data,
- int (*get_codepoint)(gp_file *file, const char **astr),
- gs_memory_t *mem);
+int arg_init(arg_list *pal,
+ const char **argv,
+ int argc,
+ gp_file *(*arg_fopen)(const char *fname, void *fopen_data),
+ void *fopen_data,
+ int (*get_codepoint)(gp_file *file, const char **astr),
+ gs_memory_t *mem);
/*
* Push a string onto an arg list.
diff --git a/base/gslibctx.c b/base/gslibctx.c
index 923f820..6e57fe0 100644
--- a/base/gslibctx.c
+++ b/base/gslibctx.c
@@ -30,6 +30,7 @@
#ifdef WITH_CAL
#include "cal.h"
#endif
+#include "gsargs.h"
/* Include the extern for the device list. */
extern_gs_lib_device_list();
@@ -385,7 +386,7 @@ void gs_lib_ctx_fin(gs_memory_t *mem)
{
gs_lib_ctx_t *ctx;
gs_memory_t *ctx_mem;
- int refs;
+ int refs, i;
gs_fs_list_t *fs;
if (!mem || !mem->gs_lib_ctx)
@@ -433,6 +434,11 @@ void gs_lib_ctx_fin(gs_memory_t *mem)
gs_free_object(fs->memory, fs, "gs_lib_ctx_fin");
fs = next;
}
+
+ for (i = 0; i < ctx->core->argc; i++)
+ gs_free_object(ctx->core->memory, ctx->core->argv[i], "gs_lib_ctx_arg");
+ gs_free_object(ctx->core->memory, ctx->core->argv, "gs_lib_ctx_args");
+
gs_free_object(ctx->core->memory, ctx->core, "gs_lib_ctx_fin");
}
remove_ctx_pointers(ctx_mem);
@@ -855,3 +861,194 @@ gs_remove_fs(const gs_memory_t *mem,
pfs = &(*pfs)->next;
}
}
+
+int
+gs_lib_ctx_stash_sanitized_arg(gs_lib_ctx_t *ctx, const char *arg)
+{
+ gs_lib_ctx_core_t *core;
+ size_t len;
+ const char *p;
+ int elide = 0;
+
+ if (ctx == NULL || ctx->core == NULL || arg == NULL)
+ return 0;
+
+ /* Sanitize arg */
+ switch(*arg)
+ {
+ case '-':
+ switch (arg[1])
+ {
+ case 0: /* We can let - through unchanged */
+ case 'd': /* We can let -dFoo=<whatever> through unchanged */
+ case 'D': /* We can let -DFoo=<whatever> through unchanged */
+ case 'r': /* We can let -r through unchanged */
+ case 'Z': /* We can let -Z through unchanged */
+ case 'g': /* We can let -g through unchanged */
+ case 'P': /* We can let -P through unchanged */
+ case '-': /* We can let -- through unchanged */
+ case '+': /* We can let -+ through unchanged */
+ case '_': /* We can let -_ through unchanged */
+ case 'u': /* We can let -u through unchanged */
+ case 'q': /* We can let -q through unchanged */
+ break;
+ case 'I': /* Let through the I, but hide anything else */
+ case 'f': /* Let through the I, but hide anything else */
+ if (arg[2] == 0)
+ break;
+ p = arg+2;
+ while (p == 32)
+ p++;
+ elide = 1;
+ break;
+ case 's':
+ case 'S':
+ /* By default, we want to keep the key, but lose the value */
+ p = arg+2;
+ while (*p && *p != '=')
+ p++;
+ if (*p == '=')
+ p++;
+ if (*p == 0)
+ break; /* No value to elide */
+ /* Check for our whitelisted values here */
+ if (!memcmp("DEFAULTPAPERSIZE", arg+2, p-arg-3))
+ break;
+ if (!memcmp("DEVICE", arg+2, p-arg-3))
+ break;
+ if (!memcmp("PAPERSIZE", arg+2, p-arg-3))
+ break;
+ if (!memcmp("SUBSTFONT", arg+2, p-arg-3))
+ break;
+ if (!memcmp("ColorConversionStrategy", arg+2, p-arg-3))
+ break;
+ if (!memcmp("PageList", arg+2, p-arg-3))
+ break;
+ if (!memcmp("ProcessColorModel", arg+2, p-arg-3))
+ break;
+ /* Didn't match a whitelisted value, so elide it. */
+ elide = 1;
+ break;
+ default:
+ /* Shouldn't happen, but elide it just in case */
+ arg = "?";
+ break;
+ }
+ break;
+ case '@':
+ /* Shouldn't happen */
+ default:
+ /* Anything else should be elided */
+ arg = "?";
+ break;
+ }
+
+ core = ctx->core;
+ if (elide)
+ len = p-arg;
+ else
+ len = strlen(arg);
+
+ if (core->arg_max == core->argc) {
+ char **argv;
+ int newlen = core->arg_max * 2;
+ if (newlen == 0)
+ newlen = 4;
+ argv = (char **)gs_alloc_bytes(ctx->core->memory, sizeof(char *) * newlen,
+ "gs_lib_ctx_args");
+ if (argv == NULL)
+ return gs_error_VMerror;
+ if (core->argc > 0) {
+ memcpy(argv, core->argv, sizeof(char *) * core->argc);
+ gs_free_object(ctx->memory, core->argv, "gs_lib_ctx_args");
+ }
+ core->argv = argv;
+ core->arg_max = newlen;
+ }
+
+ core->argv[core->argc] = (char *)gs_alloc_bytes(ctx->core->memory, len+1+elide,
+ "gs_lib_ctx_arg");
+ if (core->argv[core->argc] == NULL)
+ return gs_error_VMerror;
+ memcpy(core->argv[core->argc], arg, len);
+ if (elide) {
+ core->argv[core->argc][len] = '?';
+ }
+ core->argv[core->argc][len+elide] = 0;
+ core->argc++;
+
+ return 0;
+}
+
+int
+gs_lib_ctx_stash_exe(gs_lib_ctx_t *ctx, const char *arg)
+{
+ gs_lib_ctx_core_t *core;
+ size_t len;
+ const char *p, *word;
+ const char *sep = gp_file_name_directory_separator();
+ size_t seplen = strlen(sep);
+
+ if (ctx == NULL || ctx->core == NULL || arg == NULL)
+ return 0;
+
+ /* Sanitize arg */
+ p = arg;
+ word = NULL;
+ for (p = arg; *p; p++) {
+ if (memcmp(sep, p, seplen) == 0) {
+ word = p+seplen;
+ p += seplen-1;
+ }
+#if defined(__WIN32__) || defined(__OS2__) || defined(METRO)
+ if (*p == '\\')
+ word = p+1;
+#endif
+ }
+ len = p - (word ? word : arg) + 1;
+ if (word)
+ len += 5;
+
+ core = ctx->core;
+ if (core->arg_max == core->argc) {
+ char **argv;
+ int newlen = core->arg_max * 2;
+ if (newlen == 0)
+ newlen = 4;
+ argv = (char **)gs_alloc_bytes(ctx->core->memory, sizeof(char *) * newlen,
+ "gs_lib_ctx_args");
+ if (argv == NULL)
+ return gs_error_VMerror;
+ if (core->argc > 0) {
+ memcpy(argv, core->argv, sizeof(char *) * core->argc);
+ gs_free_object(ctx->memory, core->argv, "gs_lib_ctx_args");
+ }
+ core->argv = argv;
+ core->arg_max = newlen;
+ }
+
+ core->argv[core->argc] = (char *)gs_alloc_bytes(ctx->core->memory, len,
+ "gs_lib_ctx_arg");
+ if (core->argv[core->argc] == NULL)
+ return gs_error_VMerror;
+ if (word)
+ strcpy(core->argv[core->argc], "path/");
+ else
+ core->argv[core->argc][0] = 0;
+ strcat(core->argv[core->argc], word ? word : arg);
+ core->argc++;
+
+ return 0;
+}
+
+int gs_lib_ctx_get_args(gs_lib_ctx_t *ctx, const char ***argv)
+{
+ gs_lib_ctx_core_t *core;
+
+ if (ctx == NULL || ctx->core == NULL || argv == NULL)
+ return 0;
+
+ core = ctx->core;
+ *argv = core->argv;
+ return core->argc;
+}
diff --git a/base/gslibctx.h b/base/gslibctx.h
index 5b5397f..f35f85e 100644
--- a/base/gslibctx.h
+++ b/base/gslibctx.h
@@ -115,6 +115,11 @@ typedef struct {
* but that's too hard to arrange, so we live with it in
* all builds. */
void *cal_ctx;
+
+ /* Stashed args */
+ int arg_max;
+ int argc;
+ char **argv;
} gs_lib_ctx_core_t;
typedef struct gs_lib_ctx_s
@@ -261,4 +266,12 @@ gs_add_fs(const gs_memory_t *mem, gs_fs_t *fn, void *secret);
void
gs_remove_fs(const gs_memory_t *mem, gs_fs_t *fn, void *secret);
+int
+gs_lib_ctx_stash_sanitized_arg(gs_lib_ctx_t *ctx, const char *argv);
+
+int
+gs_lib_ctx_stash_exe(gs_lib_ctx_t *ctx, const char *argv);
+
+int gs_lib_ctx_get_args(gs_lib_ctx_t *ctx, const char ***argv);
+
#endif /* GSLIBCTX_H */
diff --git a/pcl/pl/plmain.c b/pcl/pl/plmain.c
index 067d459..e7152a3 100644
--- a/pcl/pl/plmain.c
+++ b/pcl/pl/plmain.c
@@ -180,6 +180,7 @@ pl_main_init_with_args(pl_main_instance_t *inst, int argc, char *argv[])
{
gs_memory_t *mem = inst->memory;
pl_interp_implementation_t *pjli;
+ int code;
gp_init();
/* debug flags we reset this out of gs_lib_init0 which sets these
@@ -210,8 +211,9 @@ pl_main_init_with_args(pl_main_instance_t *inst, int argc, char *argv[])
gs_c_param_list_write(&inst->params, mem);
gs_param_list_set_persistent_keys((gs_param_list *)&inst->params, false);
- arg_init(&inst->args, (const char **)argv, argc, pl_main_arg_fopen, mem,
- inst->get_codepoint, mem);
+ if (arg_init(&inst->args, (const char **)argv, argc, pl_main_arg_fopen, mem,
+ inst->get_codepoint, mem) < 0)
+ return gs_error_Fatal;
/* Create PDL instances, etc */
if (pl_main_languages_init(mem, inst) < 0) {
@@ -973,6 +975,9 @@ handle_dash_c(pl_main_instance_t *pmi, arg_list *pal, char **collected_commands,
((*arg)[0] == '-' && !isdigit((unsigned char)(*arg)[1]))
)
break;
+ code = gs_lib_ctx_stash_sanitized_arg(pmi->memory->gs_lib_ctx, "?");
+ if (code < 0)
+ return code;
arglen = strlen(*arg);
if (*collected_commands == NULL) {
*collected_commands = (char *)gs_alloc_bytes(pmi->memory, arglen+1,
@@ -1339,6 +1344,9 @@ pl_main_process_options(pl_main_instance_t * pmi, arg_list * pal,
while (arg != NULL || (code = arg_next(pal, (const char **)&arg, pmi->memory)) > 0) {
if (*arg != '-') /* Stop when we hit something that isn't an option */
break;
+ code = gs_lib_ctx_stash_sanitized_arg(pmi->memory->gs_lib_ctx, arg);
+ if (code < 0)
+ return code;
if (arg[1] == 0) {
/* Stdin, not an option! */
not_an_arg = 1;
@@ -1466,6 +1474,9 @@ pl_main_process_options(pl_main_instance_t * pmi, arg_list * pal,
dmprintf(pmi->memory, "-f must be followed by a filename\n");
continue;
}
+ code = gs_lib_ctx_stash_sanitized_arg(pmi->memory->gs_lib_ctx, "?");
+ if (code < 0)
+ return code;
goto out;
case 'g':
{
@@ -1517,6 +1528,9 @@ pl_main_process_options(pl_main_instance_t * pmi, arg_list * pal,
code = arg_next(pal, (const char **)&path, pmi->memory);
if (code < 0)
return code;
+ code = gs_lib_ctx_stash_sanitized_arg(pmi->memory->gs_lib_ctx, "?");
+ if (code < 0)
+ return code;
} else
path = arg;
if (path == NULL)
@@ -1617,6 +1631,9 @@ pl_main_process_options(pl_main_instance_t * pmi, arg_list * pal,
code = arg_next(pal, (const char **)&adef, pmi->memory);
if (code < 0)
break;
+ code = gs_lib_ctx_stash_sanitized_arg(pmi->memory->gs_lib_ctx, "?");
+ if (code < 0)
+ return code;
} else
adef = arg;
if (adef == NULL)
@@ -1794,7 +1811,17 @@ pl_main_process_options(pl_main_instance_t * pmi, arg_list * pal,
* a '-', they'll do "-f -blah". The - of the "-blah" must not be accepted
* by the arg processing in the loop below. We use 'not_an_arg' to handle
* this. */
- do {
+ while (1) {
+ if (arg == NULL) {
+ code = arg_next(pal, (const char **)&arg, pmi->memory);
+ if (code < 0)
+ break;
+ if (arg == NULL)
+ break;
+ code = gs_lib_ctx_stash_sanitized_arg(pmi->memory->gs_lib_ctx, arg);
+ if (code < 0)
+ return code;
+ }
if (!not_an_arg && arg[0] == '-' && arg[1] == 'c') {
code = handle_dash_c(pmi, pal, &collected_commands, &arg);
if (code < 0)
@@ -1809,6 +1836,9 @@ pl_main_process_options(pl_main_instance_t * pmi, arg_list * pal,
dmprintf(pmi->memory, "-f must be followed by a filename\n");
continue;
}
+ code = gs_lib_ctx_stash_sanitized_arg(pmi->memory->gs_lib_ctx, "?");
+ if (code < 0)
+ return code;
not_an_arg = 1;
continue;
} else {
@@ -1826,7 +1856,7 @@ pl_main_process_options(pl_main_instance_t * pmi, arg_list * pal,
}
arg = NULL;
not_an_arg = 0;
- } while (arg != NULL || (code = arg_next(pal, (const char **)&arg, pmi->memory)) > 0);
+ }
}
if (code == 0 && collected_commands != NULL) {
diff --git a/psi/imainarg.c b/psi/imainarg.c
index 4e2cdab..d22d3ca 100644
--- a/psi/imainarg.c
+++ b/psi/imainarg.c
@@ -138,10 +138,13 @@ gs_main_init_with_args01(gs_main_instance * minst, int argc, char *argv[])
int code;
int have_dumped_args = 0;
- arg_init(&args, (const char **)argv, argc,
- gs_main_arg_fopen, (void *)minst,
- minst->get_codepoint,
- minst->heap);
+ /* Now we actually process them */
+ code = arg_init(&args, (const char **)argv, argc,
+ gs_main_arg_fopen, (void *)minst,
+ minst->get_codepoint,
+ minst->heap);
+ if (code < 0)
+ return code;
code = gs_main_init0(minst, 0, 0, 0, GS_MAX_LIB_DIRS);
if (code < 0)
return code;
@@ -213,6 +216,9 @@ gs_main_init_with_args01(gs_main_instance * minst, int argc, char *argv[])
}
}
while ((code = arg_next(&args, (const char **)&arg, minst->heap)) > 0) {
+ code = gs_lib_ctx_stash_sanitized_arg(minst->heap->gs_lib_ctx, arg);
+ if (code < 0)
+ return code;
switch (*arg) {
case '-':
code = swproc(minst, arg, &args);
@@ -460,6 +466,7 @@ run_stdin:
char *psarg;
code = arg_next(pal, (const char **)&psarg, minst->heap);
+ /* Don't stash the @ file name */
if (code < 0)
return gs_error_Fatal;
@@ -477,6 +484,9 @@ run_stdin:
code = run_string(minst, "userdict/ARGUMENTS[", 0, minst->user_errors, NULL, NULL);
if (code >= 0)
while ((code = arg_next(pal, (const char **)&arg, minst->heap)) > 0) {
+ code = gs_lib_ctx_stash_sanitized_arg(minst->heap->gs_lib_ctx, arg);
+ if (code < 0)
+ break;
code = runarg(minst, "", arg, "", runInit, minst->user_errors, NULL, NULL);
if (code < 0)
break;
@@ -519,6 +529,9 @@ run_stdin:
(arg[0] == '-' && !isdigit((unsigned char)arg[1]))
)
break;
+ code = gs_lib_ctx_stash_sanitized_arg(minst->heap->gs_lib_ctx, "?");
+ if (code < 0)
+ return code;
code = runarg(minst, "", arg, ".runstring", 0, minst->user_errors, NULL, NULL);
if (code < 0)
return code;
@@ -624,6 +637,9 @@ run_stdin:
code = arg_next(pal, (const char **)&path, minst->heap);
if (code < 0)
return code;
+ code = gs_lib_ctx_stash_sanitized_arg(minst->heap->gs_lib_ctx, "?");
+ if (code < 0)
+ return code;
} else
path = arg;
if (path == NULL)
@@ -689,6 +705,9 @@ run_stdin:
return code;
if (code == 0)
return gs_error_undefinedfilename;
+ code = gs_lib_ctx_stash_sanitized_arg(minst->heap->gs_lib_ctx, "?");
+ if (code < 0)
+ return code;
} else
adef = arg;
if ((code = gs_main_init1(minst)) < 0)
----------------------------------------------------------------------
commit 8ba95fb06387572160fee5e4c1e51d972401566e
Author: Robin Watts <[email protected]>
Date: Wed Aug 14 16:47:36 2019 +0100
Fix gs_lib_ctx memory calls to use the correct memory pointer.
diff --git a/base/gslibctx.c b/base/gslibctx.c
index d4ccb2c..923f820 100644
--- a/base/gslibctx.c
+++ b/base/gslibctx.c
@@ -422,11 +422,11 @@ void gs_lib_ctx_fin(gs_memory_t *mem)
gx_monitor_free((gx_monitor_t *)(ctx->core->monitor));
#endif
#ifdef WITH_CAL
- cal_fin(ctx->core->cal_ctx, mem);
+ cal_fin(ctx->core->cal_ctx, ctx->core->memory);
#endif
- gs_purge_control_paths(ctx_mem, 0);
- gs_purge_control_paths(ctx_mem, 1);
- gs_purge_control_paths(ctx_mem, 2);
+ gs_purge_control_paths(ctx->core->memory, 0);
+ gs_purge_control_paths(ctx->core->memory, 1);
+ gs_purge_control_paths(ctx->core->memory, 2);
fs = ctx->core->fs;
while (fs) {
gs_fs_list_t *next = fs->next;
Summary of changes:
base/gsargs.c | 15 +++-
base/gsargs.h | 14 ++--
base/gslibctx.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
base/gslibctx.h | 13 ++++
pcl/pl/plmain.c | 38 +++++++++--
psi/imainarg.c | 27 ++++++--
6 files changed, 291 insertions(+), 23 deletions(-)