diff --git a/sway/commands.c b/sway/commands.c index f6d56bb4e..42105d5f4 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -1401,17 +1401,34 @@ struct cmd_results *handle_command(char *_exec) { head = exec; do { - // Handle criteria + // Extract criteria (valid for this command list only). + criteria = NULL; if (*head == '[') { + ++head; criteria = argsep(&head, "]"); if (head) { ++head; // TODO handle criteria } else { - results = cmd_results_new(CMD_INVALID, NULL, "Unmatched ["); + if (!results) { + results = cmd_results_new(CMD_INVALID, criteria, "Unmatched ["); + } + goto cleanup; } // Skip leading whitespace head += strspn(head, whitespace); + + // TODO: it will yield unexpected results to execute commands + // (on any view) that where meant for certain views only. + if (!results) { + int len = strlen(criteria) + strlen(head) + 4; + char *tmp = malloc(len); + snprintf(tmp, len, "[%s] %s", criteria, head); + results = cmd_results_new(CMD_INVALID, tmp, + "Can't handle criteria string: Refusing to execute command"); + free(tmp); + } + goto cleanup; } // Split command list cmdlist = argsep(&head, ";"); diff --git a/sway/stringop.c b/sway/stringop.c index fe5a97ca1..efa3a2073 100644 --- a/sway/stringop.c +++ b/sway/stringop.c @@ -117,6 +117,7 @@ char **split_args(const char *start, int *argc) { bool in_token = false; bool in_string = false; bool in_char = false; + bool in_brackets = false; // brackets are used for critera bool escaped = false; const char *end = start; if (start) { @@ -129,10 +130,14 @@ char **split_args(const char *start, int *argc) { in_string = !in_string; } else if (*end == '\'' && !in_string && !escaped) { in_char = !in_char; + } else if (*end == '[' && !in_string && !in_char && !in_brackets && !escaped) { + in_brackets = true; + } else if (*end == ']' && !in_string && !in_char && in_brackets && !escaped) { + in_brackets = false; } else if (*end == '\\') { escaped = !escaped; - } else if (*end == '\0' || (!in_string && !in_char && !escaped - && strchr(whitespace, *end))) { + } else if (*end == '\0' || (!in_string && !in_char && !in_brackets + && !escaped && strchr(whitespace, *end))) { goto add_token; } if (*end != '\\') {