diff --git a/parser-specs/config.spec b/parser-specs/config.spec index 53828221..4aa320bf 100644 --- a/parser-specs/config.spec +++ b/parser-specs/config.spec @@ -17,7 +17,8 @@ state INITIAL: end -> error -> '#' -> IGNORE_LINE - 'set' -> IGNORE_LINE + 'set ' -> IGNORE_LINE + 'set ' -> IGNORE_LINE 'set_from_resource' -> IGNORE_LINE bindtype = 'bindsym', 'bindcode', 'bind' -> BINDING 'bar' -> BARBRACE diff --git a/src/config_parser.c b/src/config_parser.c index e72923d6..c88e9d1e 100644 --- a/src/config_parser.c +++ b/src/config_parser.c @@ -235,7 +235,7 @@ static void next_state(const cmdp_token *token) { * */ static const char *start_of_line(const char *walk, const char *beginning) { - while (*walk != '\n' && *walk != '\r' && walk >= beginning) { + while (walk >= beginning && *walk != '\n' && *walk != '\r') { walk--; } @@ -903,6 +903,8 @@ bool parse_file(const char *f, bool use_nagbar) { fread(current_config, 1, stbuf.st_size, fstr); rewind(fstr); + bool invalid_sets = false; + while (!feof(fstr)) { if (!continuation) continuation = buffer; @@ -916,6 +918,7 @@ bool parse_file(const char *f, bool use_nagbar) { } /* sscanf implicitly strips whitespace. */ + value[0] = '\0'; const bool skip_line = (sscanf(buffer, "%511s %4095[^\n]", key, value) < 1 || strlen(key) < 3); const bool comment = (key[0] == '#'); value[4095] = '\n'; @@ -936,26 +939,28 @@ bool parse_file(const char *f, bool use_nagbar) { continue; } - if (strcasecmp(key, "set") == 0) { + if (strcasecmp(key, "set") == 0 && *value != '\0') { char v_key[512]; - char v_value[4096]; + char v_value[4096] = {'\0'}; if (sscanf(value, "%511s %4095[^\n]", v_key, v_value) < 1) { ELOG("Failed to parse variable specification '%s', skipping it.\n", value); + invalid_sets = true; continue; } if (v_key[0] != '$') { ELOG("Malformed variable assignment, name has to start with $\n"); + invalid_sets = true; continue; } upsert_variable(&variables, v_key, v_value); continue; } else if (strcasecmp(key, "set_from_resource") == 0) { - char res_name[512]; + char res_name[512] = {'\0'}; char v_key[512]; - char fallback[4096]; + char fallback[4096] = {'\0'}; /* Ensure that this string is terminated. For example, a user might * want a variable to be empty if the resource can't be found and @@ -967,11 +972,13 @@ bool parse_file(const char *f, bool use_nagbar) { if (sscanf(value, "%511s %511s %4095[^\n]", v_key, res_name, fallback) < 1) { ELOG("Failed to parse resource specification '%s', skipping it.\n", value); + invalid_sets = true; continue; } if (v_key[0] != '$') { ELOG("Malformed variable assignment, name has to start with $\n"); + invalid_sets = true; continue; } @@ -1087,12 +1094,12 @@ bool parse_file(const char *f, bool use_nagbar) { check_for_duplicate_bindings(context); reorder_bindings(); - if (use_nagbar && (context->has_errors || context->has_warnings)) { + if (use_nagbar && (context->has_errors || context->has_warnings || invalid_sets)) { ELOG("FYI: You are using i3 version %s\n", i3_version); if (version == 3) ELOG("Please convert your configfile first, then fix any remaining errors (see above).\n"); - start_config_error_nagbar(f, context->has_errors); + start_config_error_nagbar(f, context->has_errors || invalid_sets); } bool has_errors = context->has_errors; diff --git a/testcases/t/201-config-parser.t b/testcases/t/201-config-parser.t index 159de046..fb3130d5 100644 --- a/testcases/t/201-config-parser.t +++ b/testcases/t/201-config-parser.t @@ -446,8 +446,7 @@ hide_edge_border both client.focused #4c7899 #285577 #ffffff #2e9ef4 EOT -my $expected_all_tokens = "ERROR: CONFIG: Expected one of these tokens: , '#', '" . join("', '", qw( - set +my $expected_all_tokens = "ERROR: CONFIG: Expected one of these tokens: , '#', '" . join("', '", 'set ', 'set ', qw( set_from_resource bindsym bindcode