summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/i_system.c59
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
//