Update shell argument escape.

This commit is contained in:
Christoffer Lerno
2024-09-18 00:13:56 +02:00
committed by Christoffer Lerno
parent ac95e411bc
commit 5e2a06bfd6
4 changed files with 108 additions and 16 deletions

View File

@@ -778,9 +778,7 @@ static char *assemble_linker_command(const char **args, bool extra_quote)
assert(arg != scratch_buffer.str && "Incorrectly passed a scratch buffer string as an argument.");
if (arg == quote_arg)
{
scratch_buffer_append_char('"');
scratch_buffer_append_in_quote(args[++i]);
scratch_buffer_append_char('"');
scratch_buffer_append_cmd_argument(args[++i]);
continue;
}
if (arg == concat_arg)
@@ -791,25 +789,15 @@ static char *assemble_linker_command(const char **args, bool extra_quote)
}
if (arg == concat_file_arg)
{
scratch_buffer_append_char('"');
const char *a = args[++i];
scratch_buffer_append_in_quote(a);
size_t len = strlen(a);
char c = len ? a[len - 1] : '/';
if (c != '/' && !(PLATFORM_WINDOWS && c == '\\'))
{
scratch_buffer_append(PLATFORM_WINDOWS ? "\\\\" : "/");
}
scratch_buffer_append_in_quote(args[++i]);
scratch_buffer_append_char('"');
const char *path = file_append_path_temp(a, args[++i]);
scratch_buffer_append_cmd_argument(path);
continue;
}
if (arg == concat_quote_arg)
{
scratch_buffer_append(args[++i]);
scratch_buffer_append_char('"');
scratch_buffer_append_in_quote(args[++i]);
scratch_buffer_append_char('"');
scratch_buffer_append_cmd_argument(args[++i]);
continue;
}
scratch_buffer_append(arg);

View File

@@ -480,6 +480,31 @@ bool file_exists(const char *path)
return S_ISDIR(st.st_mode) || S_ISREG(st.st_mode) || S_ISREG(st.st_mode);
}
#define PATH_BUFFER_SIZE 16384
static char path_buffer[PATH_BUFFER_SIZE];
const char *file_append_path_temp(const char *path, const char *name)
{
size_t path_len = strlen(path);
if (!path_len) return name;
size_t name_len = strlen(name);
if (path_len + name_len + 1 >= PATH_BUFFER_SIZE) error_exit("Error generating path from %s and %s: buffer max size exceeded.", path, name);
#if PLATFORM_WINDOWS
if (path[path_len - 1] == '\\') goto CONCAT;
if (path[path_len - 1] == '/') goto CONCAT;
sprintf(path_buffer, "%s\\%s", path, name);
path_buffer[name_len + path_len + 1] = 0;
return path_buffer;
#else
if (path[path_len - 1] == '/') goto CONCAT;
sprintf(path_buffer, "%s/%s", path, name);
path_buffer[name_len + path_len + 1] = 0;
#endif
CONCAT:
sprintf(path_buffer, "%s%s", path, name);
path_buffer[name_len + path_len] = 0;
return path_buffer;
}
const char *file_append_path(const char *path, const char *name)
{
size_t path_len = strlen(path);

View File

@@ -88,6 +88,7 @@ void file_find_top_dir();
bool file_has_suffix_in_list(const char *file_name, int name_len, const char **suffix_list, int suffix_count);
void file_add_wildcard_files(const char ***files, const char *path, bool recursive, const char **suffix_list, int suffix_count);
const char *file_append_path(const char *path, const char *name);
const char *file_append_path_temp(const char *path, const char *name);
const char *execute_cmd(const char *cmd, bool ignore_failure, const char *stdin_string);
@@ -162,6 +163,8 @@ void scratch_buffer_append_in_quote(const char *string);
void scratch_buffer_append_char_repeat(char c, size_t count);
void scratch_buffer_append_signed_int(int64_t i);
void scratch_buffer_append_double(double d);
void scratch_buffer_append_shell_escaped(const char *string);
void scratch_buffer_append_cmd_argument(const char *string);
UNUSED void scratch_buffer_append_unsigned_int(uint64_t i);
void scratch_buffer_printf(const char *format, ...);
char *scratch_buffer_to_string(void);

View File

@@ -286,6 +286,7 @@ void str_trim_end(char *str)
}
}
}
char *str_cat(const char *a, const char *b)
{
unsigned a_len = (unsigned)strlen(a);
@@ -320,6 +321,38 @@ void scratch_buffer_append_len(const char *string, size_t len)
scratch_buffer.len += (uint32_t)len;
}
static void scratch_buffer_append_double_quoted(const char *string)
{
scratch_buffer_append_char('"');
size_t len = strlen(string);
for (size_t i = 0; i < len; )
{
char c = string[i++];
switch (c)
{
case '"':
scratch_buffer_append("\\\"");
continue;
case '\\':
{
int backslash_count = 1;
for (; i < len && string[i] == '\\'; i++, backslash_count++) {}
if (i == len || string[i] == '"')
{
scratch_buffer_append_char_repeat('\\', backslash_count * 2);
}
else
{
scratch_buffer_append_char_repeat('\\', backslash_count);
}
continue;
}
}
scratch_buffer_append_char(c);
}
scratch_buffer_append_char('"');
}
#if PLATFORM_WINDOWS
static bool contains_whitespace_or_quotes(const char *string)
{
@@ -340,6 +373,49 @@ static bool contains_whitespace_or_quotes(const char *string)
}
#endif
void scratch_buffer_append_cmd_argument(const char *string)
{
#if PLATFORM_WINDOWS
if (contains_whitespace_or_quotes(string))
{
scratch_buffer_append_double_quoted(string);
}
else
{
scratch_buffer_append(string);
}
#else
scratch_buffer_append_shell_escaped(string);
#endif
}
void scratch_buffer_append_shell_escaped(const char *string)
{
char c;
while ((c = string++[0]) != '\0')
{
if ((unsigned)c < 0x80)
{
switch (c)
{
case LOWER_CHAR_CASE:
case UPPER_CHAR_CASE:
case NUMBER_CHAR_CASE:
case '_':
case '/':
case '.':
case ',':
case '-':
break;
default:
scratch_buffer_append_char('\\');
break;
}
}
scratch_buffer_append_char(c);
}
}
void scratch_buffer_append(const char *string)
{
scratch_buffer_append_len(string, strlen(string));