[Process API] Quoting enhancements (#12946)

This commit is contained in:
Takase
2025-05-13 00:17:21 +08:00
committed by GitHub
parent 9a6f70d75a
commit f6c1e81394
5 changed files with 217 additions and 9 deletions

View File

@@ -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) {

View File

@@ -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;
}