From 6a3c94a9d0a33887cb5a746d304b65b26f39c389 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 20 Jul 2022 00:24:20 +0200 Subject: [PATCH] Better string escaping, but it's still not good enough to support paths with spaces. --- modules/src/system/syssystem.c | 69 ++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 12 deletions(-) diff --git a/modules/src/system/syssystem.c b/modules/src/system/syssystem.c index c86b0be65..6013ade8d 100644 --- a/modules/src/system/syssystem.c +++ b/modules/src/system/syssystem.c @@ -2,34 +2,79 @@ #include #include "system.h" +#if defined WIN32 + #define ESCAPECHAR '^' + + static int needs_escaping(char c) + { + switch (c) + { + case ' ': + case '"': + case '\'': + case '(': + case ')': + case '^': + return 1; + + default: + return 0; + } + } +#else + #define ESCAPECHAR '\\' + + static int needs_escaping(char c) + { + switch (c) + { + case ' ': + case '"': + case '\'': + case '\\': + case '(': + case ')': + return 1; + + default: + return 0; + } + } +#endif + +static char* append_escaped(char* buffer, const char* word) +{ + for (;;) + { + char c = *word++; + if (!c) + break; + if (needs_escaping(c)) + *buffer++ = ESCAPECHAR; + *buffer++ = c; + } + return buffer; +} + int sys_system(const char* prog, const char* const* arglist) { /* Calculate the maximum length of the command line. */ - int len = strlen(prog); + int len = strlen(prog) * 2 + 1; for (const char* const* arg = arglist+1; *arg; arg++) len += strlen(*arg) * 2 + 1; /* Now actually build the command line. */ char* cmdline = malloc(len + 1); - strcpy(cmdline, prog); - char* p = cmdline + strlen(prog); + char* p = append_escaped(cmdline, prog); for (const char* const* arg = arglist+1; *arg; arg++) { const char* word = *arg; *p++ = ' '; - for (;;) - { - char c = *word++; - if (!c) - break; - if ((c == ' ') || (c == '\"') || (c == '\'')) - *p++ = '\\'; - *p++ = c; - } + p = append_escaped(p, word); } *p = 0;