summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSimon Howard2014-04-30 00:24:38 -0400
committerSimon Howard2014-04-30 00:24:38 -0400
commiteebddb1fff7d6b87ef7938881b2e5c9fdb702dad (patch)
tree1ba59c17e948554bdcf9beb6d19ff85bd86ef5b1 /src
parent12bac584e165493f91435ffacb2b4633c593346c (diff)
downloadchocolate-doom-eebddb1fff7d6b87ef7938881b2e5c9fdb702dad.tar.gz
chocolate-doom-eebddb1fff7d6b87ef7938881b2e5c9fdb702dad.tar.bz2
chocolate-doom-eebddb1fff7d6b87ef7938881b2e5c9fdb702dad.zip
system: Escape special characters for Zenity.
When invoking Zenity to display an error message, some characters can have special meanings to the shell. Escape these properly so that the error message is always shown correctly. This fixes #355.
Diffstat (limited to 'src')
-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
//