[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(-)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.