From 248df18c24d2a849de984b477ca3913ce7c72441 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 15 Dec 2016 17:39:09 -0500 Subject: [PATCH] Handle allocation failure in commands --- sway/commands.c | 14 ++++++++++++-- sway/commands/assign.c | 3 +++ sway/commands/bar.c | 9 ++++++++- sway/commands/bar/bindsym.c | 3 +++ sway/commands/bar/colors.c | 6 ++++++ sway/commands/bind.c | 23 +++++++++++++++++++---- sway/commands/exec_always.c | 7 ++++--- sway/commands/for_window.c | 3 +++ sway/commands/mode.c | 5 ++++- sway/commands/output.c | 18 +++++++++++++----- sway/commands/set.c | 3 +++ 11 files changed, 78 insertions(+), 16 deletions(-) diff --git a/sway/commands.c b/sway/commands.c index d87d00841..dee03d71d 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -386,7 +386,11 @@ struct cmd_results *handle_command(char *_exec, enum command_context context) { if (!results) { int len = strlen(criteria) + strlen(head) + 4; char *tmp = malloc(len); - snprintf(tmp, len, "[%s] %s", criteria, head); + if (tmp) { + snprintf(tmp, len, "[%s] %s", criteria, head); + } else { + sway_log(L_DEBUG, "Unable to allocate criteria string for cmd result"); + } results = cmd_results_new(CMD_INVALID, tmp, "Can't handle criteria string: Refusing to execute command"); free(tmp); @@ -584,6 +588,10 @@ cleanup: struct cmd_results *cmd_results_new(enum cmd_status status, const char* input, const char *format, ...) { struct cmd_results *results = malloc(sizeof(struct cmd_results)); + if (!results) { + sway_log(L_ERROR, "Unable to allocate command results"); + return NULL; + } results->status = status; if (input) { results->input = strdup(input); // input is the command name @@ -594,7 +602,9 @@ struct cmd_results *cmd_results_new(enum cmd_status status, const char* input, c char *error = malloc(256); va_list args; va_start(args, format); - vsnprintf(error, 256, format, args); + if (error) { + vsnprintf(error, 256, format, args); + } va_end(args); results->error = error; } else { diff --git a/sway/commands/assign.c b/sway/commands/assign.c index 53c599ca1..1824692b3 100644 --- a/sway/commands/assign.c +++ b/sway/commands/assign.c @@ -27,6 +27,9 @@ struct cmd_results *cmd_assign(int argc, char **argv) { snprintf(cmdlist, arglen, "%s%s", movecmd, *argv); struct criteria *crit = malloc(sizeof(struct criteria)); + if (!crit) { + return cmd_results_new(CMD_FAILURE, "assign", "Unable to allocate criteria"); + } crit->crit_raw = strdup(criteria); crit->cmdlist = cmdlist; crit->tokens = create_list(); diff --git a/sway/commands/bar.c b/sway/commands/bar.c index 55cb0d9d2..e8d24084c 100644 --- a/sway/commands/bar.c +++ b/sway/commands/bar.c @@ -32,6 +32,9 @@ struct cmd_results *cmd_bar(int argc, char **argv) { // Create new bar with default values struct bar_config *bar = default_bar_config(); + if (!bar) { + return cmd_results_new(CMD_FAILURE, "bar", "Unable to allocate bar state"); + } // set bar id int i; @@ -39,7 +42,11 @@ struct cmd_results *cmd_bar(int argc, char **argv) { if (bar == config->bars->items[i]) { const int len = 5 + numlen(i); // "bar-" + i + \0 bar->id = malloc(len * sizeof(char)); - snprintf(bar->id, len, "bar-%d", i); + if (bar->id) { + snprintf(bar->id, len, "bar-%d", i); + } else { + return cmd_results_new(CMD_FAILURE, "bar", "Unable to allocate bar ID"); + } break; } } diff --git a/sway/commands/bar/bindsym.c b/sway/commands/bar/bindsym.c index bb81b4a92..5f90b51a8 100644 --- a/sway/commands/bar/bindsym.c +++ b/sway/commands/bar/bindsym.c @@ -26,6 +26,9 @@ struct cmd_results *bar_cmd_bindsym(int argc, char **argv) { return cmd_results_new(CMD_INVALID, "bindsym", "Invalid mouse binding %s", argv[1]); } struct sway_mouse_binding *binding = malloc(sizeof(struct sway_mouse_binding)); + if (!binding) { + return cmd_results_new(CMD_FAILURE, "bindsym", "Unable to allocate binding"); + } binding->button = numbutton; binding->command = join_args(argv + 1, argc - 1); diff --git a/sway/commands/bar/colors.c b/sway/commands/bar/colors.c index f6fb520a0..f87929730 100644 --- a/sway/commands/bar/colors.c +++ b/sway/commands/bar/colors.c @@ -9,6 +9,9 @@ static struct cmd_results *parse_single_color(char **color, const char *cmd_name if (!*color) { *color = malloc(10); + if (!*color) { + return cmd_results_new(CMD_FAILURE, cmd_name, "Unable to allocate color"); + } } error = add_color(cmd_name, *color, argv[0]); @@ -29,6 +32,9 @@ static struct cmd_results *parse_three_colors(char ***colors, const char *cmd_na for (i = 0; i < 3; i++) { if (!*colors[i]) { *(colors[i]) = malloc(10); + if (!*(colors[i])) { + return cmd_results_new(CMD_FAILURE, cmd_name, "Unable to allocate color"); + } } error = add_color(cmd_name, *(colors[i]), argv[i]); if (error) { diff --git a/sway/commands/bind.c b/sway/commands/bind.c index e8bb3ee8c..8282277bd 100644 --- a/sway/commands/bind.c +++ b/sway/commands/bind.c @@ -16,6 +16,10 @@ struct cmd_results *cmd_bindsym(int argc, char **argv) { } struct sway_binding *binding = malloc(sizeof(struct sway_binding)); + if (!binding) { + return cmd_results_new(CMD_FAILURE, "bindsym", + "Unable to allocate binding"); + } binding->keys = create_list(); binding->modifiers = 0; binding->release = false; @@ -46,14 +50,21 @@ struct cmd_results *cmd_bindsym(int argc, char **argv) { continue; } // Check for xkb key - xkb_keysym_t sym = xkb_keysym_from_name(split->items[i], XKB_KEYSYM_CASE_INSENSITIVE); + xkb_keysym_t sym = xkb_keysym_from_name(split->items[i], + XKB_KEYSYM_CASE_INSENSITIVE); if (!sym) { - error = cmd_results_new(CMD_INVALID, "bindsym", "Unknown key '%s'", (char *)split->items[i]); free_sway_binding(binding); - list_free(split); - return error; + free_flat_list(split); + return cmd_results_new(CMD_INVALID, "bindsym", "Unknown key '%s'", + (char *)split->items[i]); } xkb_keysym_t *key = malloc(sizeof(xkb_keysym_t)); + if (!key) { + free_sway_binding(binding); + free_flat_list(split); + return cmd_results_new(CMD_FAILURE, "bindsym", + "Unable to allocate binding"); + } *key = sym; list_add(binding->keys, key); } @@ -82,6 +93,10 @@ struct cmd_results *cmd_bindcode(int argc, char **argv) { } struct sway_binding *binding = malloc(sizeof(struct sway_binding)); + if (!binding) { + return cmd_results_new(CMD_FAILURE, "bindsym", + "Unable to allocate binding"); + } binding->keys = create_list(); binding->modifiers = 0; binding->release = false; diff --git a/sway/commands/exec_always.c b/sway/commands/exec_always.c index 157d48722..1d7cd4946 100644 --- a/sway/commands/exec_always.c +++ b/sway/commands/exec_always.c @@ -39,6 +39,9 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) { pid_t pid; pid_t *child = malloc(sizeof(pid_t)); // malloc'd so that Linux can avoid copying the process space + if (!child) { + return cmd_results_new(CMD_FAILURE, "exec_always", "Unable to allocate child pid"); + } // Fork process if ((pid = fork()) == 0) { // Fork child process again @@ -56,7 +59,7 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) { _exit(0); // Close child process } else if (pid < 0) { free(child); - return cmd_results_new(CMD_FAILURE, "exec_always", "Command failed (sway could not fork)."); + return cmd_results_new(CMD_FAILURE, "exec_always", "fork() failed"); } close(fd[1]); // close write ssize_t s = 0; @@ -73,8 +76,6 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) { pw->pid = child; pw->workspace = strdup(ws->name); pid_workspace_add(pw); - // TODO: keep track of this pid and open the corresponding view on the current workspace - // blocked pending feature in wlc } else { free(child); } diff --git a/sway/commands/for_window.c b/sway/commands/for_window.c index 2ba0ea6c1..8c5722fda 100644 --- a/sway/commands/for_window.c +++ b/sway/commands/for_window.c @@ -14,6 +14,9 @@ struct cmd_results *cmd_for_window(int argc, char **argv) { char *criteria = argv[0], *cmdlist = join_args(argv + 1, argc - 1); struct criteria *crit = malloc(sizeof(struct criteria)); + if (!crit) { + return cmd_results_new(CMD_FAILURE, "for_window", "Unable to allocate criteria"); + } crit->crit_raw = strdup(criteria); crit->cmdlist = cmdlist; crit->tokens = create_list(); diff --git a/sway/commands/mode.c b/sway/commands/mode.c index f9cb271ea..ed3f432f7 100644 --- a/sway/commands/mode.c +++ b/sway/commands/mode.c @@ -30,7 +30,10 @@ struct cmd_results *cmd_mode(int argc, char **argv) { } // Create mode if it doesn't exist if (!mode && mode_make) { - mode = malloc(sizeof*mode); + mode = malloc(sizeof(struct sway_mode)); + if (!mode) { + return cmd_results_new(CMD_FAILURE, "mode", "Unable to allocate mode"); + } mode->name = strdup(mode_name); mode->bindings = create_list(); list_add(config->modes, mode); diff --git a/sway/commands/output.c b/sway/commands/output.c index 6c1c55b53..e150aed2b 100644 --- a/sway/commands/output.c +++ b/sway/commands/output.c @@ -113,12 +113,20 @@ struct cmd_results *cmd_output(int argc, char **argv) { src = p.we_wordv[0]; if (config->reading && *src != '/') { char *conf = strdup(config->current_config); - char *conf_path = dirname(conf); - src = malloc(strlen(conf_path) + strlen(src) + 2); - sprintf(src, "%s/%s", conf_path, p.we_wordv[0]); - free(conf); + if (conf) { + char *conf_path = dirname(conf); + src = malloc(strlen(conf_path) + strlen(src) + 2); + if (src) { + sprintf(src, "%s/%s", conf_path, p.we_wordv[0]); + } else { + sway_log(L_ERROR, "Unable to allocate background source"); + } + free(conf); + } else { + sway_log(L_ERROR, "Unable to allocate background source"); + } } - if (access(src, F_OK) == -1) { + if (!src || access(src, F_OK) == -1) { return cmd_results_new(CMD_INVALID, "output", "Background file unreadable (%s)", src); } for (char *m = mode; *m; ++m) *m = tolower(*m); diff --git a/sway/commands/set.c b/sway/commands/set.c index 1f3249512..8b2938258 100644 --- a/sway/commands/set.c +++ b/sway/commands/set.c @@ -47,6 +47,9 @@ struct cmd_results *cmd_set(int argc, char **argv) { free(var->value); } else { var = malloc(sizeof(struct sway_variable)); + if (!var) { + return cmd_results_new(CMD_FAILURE, "set", "Unable to allocate variable"); + } var->name = strdup(argv[0]); list_add(config->symbols, var); list_qsort(config->symbols, compare_set_qsort);