diff options
-rw-r--r-- | src/i_system.c | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/src/i_system.c b/src/i_system.c index 5b6989bf..5aa57348 100644 --- a/src/i_system.c +++ b/src/i_system.c @@ -262,6 +262,7 @@ void I_Quit (void) exit(0); } +#if !defined(_WIN32) && !defined(__MACOSX__) #define ZENITY_BINARY "/usr/bin/zenity" // returns non-zero if zenity is available @@ -271,11 +272,56 @@ static int ZenityAvailable(void) return system(ZENITY_BINARY " --help >/dev/null 2>&1") == 0; } +// Escape special characters in the given string so that they can be +// safely enclosed in shell quotes. + +static char *EscapeShellString(char *string) +{ + char *result; + char *r, *s; + + // In the worst case, every character might be escaped. + result = malloc(strlen(string) * 2 + 3); + r = result; + + // Enclosing quotes. + *r = '"'; + ++r; + + for (s = string; *s != '\0'; ++s) + { + // From the bash manual: + // + // "Enclosing characters in double quotes preserves the literal + // value of all characters within the quotes, with the exception + // of $, `, \, and, when history expansion is enabled, !." + // + // Therefore, escape these characters by prefixing with a backslash. + + if (strchr("$`\\!", *s) != NULL) + { + *r = '\\'; + ++r; + } + + *r = *s; + ++r; + } + + // Enclosing quotes. + *r = '"'; + ++r; + *r = '\0'; + + return result; +} + // Open a native error box with a message using zenity static int ZenityErrorBox(char *message) { - int *result; + int result; + char *escaped_message; char *errorboxpath; static size_t errorboxpath_size; @@ -284,17 +330,24 @@ static int ZenityErrorBox(char *message) return 0; } - errorboxpath_size = strlen(ZENITY_BINARY) + strlen(message) + 19; + escaped_message = EscapeShellString(message); + + errorboxpath_size = strlen(ZENITY_BINARY) + strlen(escaped_message) + 19; errorboxpath = malloc(errorboxpath_size); - M_snprintf(errorboxpath, errorboxpath_size, "%s --error --text=\"%s\"", ZENITY_BINARY, message); + M_snprintf(errorboxpath, errorboxpath_size, "%s --error --text=%s", + ZENITY_BINARY, escaped_message); result = system(errorboxpath); free(errorboxpath); + free(escaped_message); return result; } +#endif /* !defined(_WIN32) && !defined(__MACOSX__) */ + + // // I_Error // |