From ebe65a4d481341d38b99e8fb36e66832888bc085 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 1 Sep 2018 11:13:48 +1000 Subject: [PATCH 1/2] Fix crash on reload If sway is reloaded using a bindsym which has multiple commands, it failed to detect the reload command, didn't create a duplicate of the binding and would crash because the reload command frees the bindings. For example: mode system { bindsym r reload, mode default } In this example, the binding->command is "reload, mode default". Fixes #2545 --- sway/commands/bind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sway/commands/bind.c b/sway/commands/bind.c index 8270b958..e73b0aea 100644 --- a/sway/commands/bind.c +++ b/sway/commands/bind.c @@ -310,7 +310,7 @@ void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding) bool reload = false; // if this is a reload command we need to make a duplicate of the // binding since it will be gone after the reload has completed. - if (strcasecmp(binding->command, "reload") == 0) { + if (strncasecmp(binding->command, "reload", 6) == 0) { reload = true; binding_copy = sway_binding_dup(binding); if (!binding_copy) { From 7e81e58e7d1f540e448f3827751f75bf54b1fe9f Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 1 Sep 2018 11:45:48 +1000 Subject: [PATCH 2/2] Allow reload command to exist anywhere in the command string This fixes a crash if you have commands where reload appears in the middle or at the end, such as `bindsym r mode default, reload`. --- common/stringop.c | 14 ++++++++++++++ include/stringop.h | 2 ++ sway/commands/bind.c | 2 +- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/common/stringop.c b/common/stringop.c index d9ae9925..d2c91c24 100644 --- a/common/stringop.c +++ b/common/stringop.c @@ -401,3 +401,17 @@ char *argsep(char **stringp, const char *delim) { found: return start; } + +const char *strcasestr(const char *haystack, const char *needle) { + size_t needle_len = strlen(needle); + const char *pos = haystack; + const char *end = pos + strlen(haystack) - needle_len; + + while (pos <= end) { + if (strncasecmp(pos, needle, needle_len) == 0) { + return pos; + } + ++pos; + } + return NULL; +} diff --git a/include/stringop.h b/include/stringop.h index e7f58011..01bbdaa9 100644 --- a/include/stringop.h +++ b/include/stringop.h @@ -46,4 +46,6 @@ char *cmdsep(char **stringp, const char *delim); // Split string into 2 by delim, handle quotes char *argsep(char **stringp, const char *delim); +const char *strcasestr(const char *haystack, const char *needle); + #endif diff --git a/sway/commands/bind.c b/sway/commands/bind.c index e73b0aea..b134c92f 100644 --- a/sway/commands/bind.c +++ b/sway/commands/bind.c @@ -310,7 +310,7 @@ void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding) bool reload = false; // if this is a reload command we need to make a duplicate of the // binding since it will be gone after the reload has completed. - if (strncasecmp(binding->command, "reload", 6) == 0) { + if (strcasestr(binding->command, "reload")) { reload = true; binding_copy = sway_binding_dup(binding); if (!binding_copy) {