mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-02-13 23:33:13 +00:00
[Process API] Quoting enhancements (#12946)
This commit is contained in:
@@ -45,10 +45,18 @@ SDL_Process *SDL_CreateProcess(const char * const *args, bool pipe_stdio)
|
||||
SDL_Process *SDL_CreateProcessWithProperties(SDL_PropertiesID props)
|
||||
{
|
||||
const char * const *args = SDL_GetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ARGS_POINTER, NULL);
|
||||
#if defined(SDL_PLATFORM_WINDOWS)
|
||||
const char *cmdline = SDL_GetStringProperty(props, SDL_PROP_PROCESS_CREATE_CMDLINE_STRING, NULL);
|
||||
if ((!args || !args[0] || !args[0][0]) && (!cmdline || !cmdline[0])) {
|
||||
SDL_SetError("Either SDL_PROP_PROCESS_CREATE_ARGS_POINTER or SDL_PROP_PROCESS_CREATE_CMDLINE_STRING must be valid");
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
if (!args || !args[0] || !args[0][0]) {
|
||||
SDL_InvalidParamError("SDL_PROP_PROCESS_CREATE_ARGS_POINTER");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_Process *process = (SDL_Process *)SDL_calloc(1, sizeof(*process));
|
||||
if (!process) {
|
||||
|
||||
@@ -106,9 +106,12 @@ static bool join_arguments(const char * const *args, LPWSTR *args_out)
|
||||
len = 0;
|
||||
for (i = 0; args[i]; i++) {
|
||||
const char *a = args[i];
|
||||
bool quotes = *a == '\0' || SDL_strpbrk(a, " \r\n\t\v") != NULL;
|
||||
|
||||
/* two double quotes to surround an argument with */
|
||||
len += 2;
|
||||
if (quotes) {
|
||||
/* surround the argument with double quote if it is empty or contains whitespaces */
|
||||
len += 2;
|
||||
}
|
||||
|
||||
for (; *a; a++) {
|
||||
switch (*a) {
|
||||
@@ -116,8 +119,8 @@ static bool join_arguments(const char * const *args, LPWSTR *args_out)
|
||||
len += 2;
|
||||
break;
|
||||
case '\\':
|
||||
/* only escape backslashes that precede a double quote */
|
||||
len += (a[1] == '"' || a[1] == '\0') ? 2 : 1;
|
||||
/* only escape backslashes that precede a double quote (including the enclosing double quote) */
|
||||
len += (a[1] == '"' || (quotes && a[1] == '\0')) ? 2 : 1;
|
||||
break;
|
||||
case ' ':
|
||||
case '^':
|
||||
@@ -149,8 +152,11 @@ static bool join_arguments(const char * const *args, LPWSTR *args_out)
|
||||
i_out = 0;
|
||||
for (i = 0; args[i]; i++) {
|
||||
const char *a = args[i];
|
||||
bool quotes = *a == '\0' || SDL_strpbrk(a, " \r\n\t\v") != NULL;
|
||||
|
||||
result[i_out++] = '"';
|
||||
if (quotes) {
|
||||
result[i_out++] = '"';
|
||||
}
|
||||
for (; *a; a++) {
|
||||
switch (*a) {
|
||||
case '"':
|
||||
@@ -163,7 +169,7 @@ static bool join_arguments(const char * const *args, LPWSTR *args_out)
|
||||
break;
|
||||
case '\\':
|
||||
result[i_out++] = *a;
|
||||
if (a[1] == '"' || a[1] == '\0') {
|
||||
if (a[1] == '"' || (quotes && a[1] == '\0')) {
|
||||
result[i_out++] = *a;
|
||||
}
|
||||
break;
|
||||
@@ -188,7 +194,9 @@ static bool join_arguments(const char * const *args, LPWSTR *args_out)
|
||||
break;
|
||||
}
|
||||
}
|
||||
result[i_out++] = '"';
|
||||
if (quotes) {
|
||||
result[i_out++] = '"';
|
||||
}
|
||||
result[i_out++] = ' ';
|
||||
}
|
||||
SDL_assert(i_out == len);
|
||||
@@ -237,6 +245,7 @@ static bool join_env(char **env, LPWSTR *env_out)
|
||||
bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID props)
|
||||
{
|
||||
const char * const *args = SDL_GetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ARGS_POINTER, NULL);
|
||||
const char *cmdline = SDL_GetStringProperty(props, SDL_PROP_PROCESS_CREATE_CMDLINE_STRING, NULL);
|
||||
SDL_Environment *env = SDL_GetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER, SDL_GetEnvironment());
|
||||
char **envp = NULL;
|
||||
const char *working_directory = SDL_GetStringProperty(props, SDL_PROP_PROCESS_CREATE_WORKING_DIRECTORY_STRING, NULL);
|
||||
@@ -286,7 +295,12 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID
|
||||
security_attributes.bInheritHandle = TRUE;
|
||||
security_attributes.lpSecurityDescriptor = NULL;
|
||||
|
||||
if (!join_arguments(args, &createprocess_cmdline)) {
|
||||
if (cmdline) {
|
||||
createprocess_cmdline = WIN_UTF8ToString(cmdline);
|
||||
if (!createprocess_cmdline) {
|
||||
goto done;
|
||||
}
|
||||
} else if (!join_arguments(args, &createprocess_cmdline)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user