diff --git a/CHANGELOG.md b/CHANGELOG.md index 57c01110..9c98fdba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ ### Fixed * Crash when starting a selection inside the margins. +* Handle trailing comments in `footrc` ### Security diff --git a/config.c b/config.c index 169b2b40..8da9c258 100644 --- a/config.c +++ b/config.c @@ -822,7 +822,7 @@ parse_config_file(FILE *f, struct config *conf, const char *path) break; } - /* Strip whitespace */ + /* Strip leading whitespace */ char *line = _line; { while (isspace(*line)) @@ -839,11 +839,15 @@ parse_config_file(FILE *f, struct config *conf, const char *path) if (line[0] == '\0' || line[0] == '#') continue; + /* Split up into key/value pair + trailing comment */ + char *key_value = strtok(line, "#"); + char *comment __attribute__((unused)) = strtok(NULL, "\n"); + /* Check for new section */ - if (line[0] == '[') { - char *end = strchr(line, ']'); + if (key_value[0] == '[') { + char *end = strchr(key_value, ']'); if (end == NULL) { - LOG_ERR("%s:%d: syntax error: %s", path, lineno, line); + LOG_ERR("%s:%d: syntax error: %s", path, lineno, key_value); goto err; } @@ -851,13 +855,13 @@ parse_config_file(FILE *f, struct config *conf, const char *path) section = SECTION_COUNT; for (enum section i = 0; i < SECTION_COUNT; i++) { - if (strcmp(&line[1], section_info[i].name) == 0) { + if (strcmp(&key_value[1], section_info[i].name) == 0) { section = i; } } if (section == SECTION_COUNT) { - LOG_ERR("%s:%d: invalid section name: %s", path, lineno, &line[1]); + LOG_ERR("%s:%d: invalid section name: %s", path, lineno, &key_value[1]); goto err; } @@ -865,11 +869,20 @@ parse_config_file(FILE *f, struct config *conf, const char *path) continue; } - char *key = strtok(line, "="); + char *key = strtok(key_value, "="); + if (key == NULL) { + LOG_ERR("%s:%d: syntax error: no key specified", path, lineno); + goto err; + } + char *value = strtok(NULL, "\n"); + if (value == NULL) { + /* Empty value, i.e. "key=" */ + value = key + strlen(key); + } /* Strip trailing whitespace from key (leading stripped earlier) */ - { + if (key[0] != '\0') { assert(!isspace(*key)); char *end = key + strlen(key) - 1; @@ -880,25 +893,28 @@ parse_config_file(FILE *f, struct config *conf, const char *path) if (value == NULL) { if (key != NULL && strlen(key) > 0 && key[0] != '#') { - LOG_ERR("%s:%d: syntax error: %s", path, lineno, line); + LOG_ERR("%s:%d: syntax error: %s", path, lineno, key_value); goto err; } continue; } - /* Strip leading whitespace from value (trailing stripped earlier) */ + /* Strip leading+trailing whitespace from value */ { while (isspace(*value)) value++; - assert(!isspace(*(value + strlen(value) - 1))); + + if (value[0] != '\0') { + char *end = value + strlen(value) - 1; + while (isspace(*end)) + end--; + *(end + 1) = '\0'; + } } - if (key[0] == '#') - continue; - - LOG_DBG("section=%s, key='%s', value='%s'", - section_names[section], key, value); + LOG_DBG("section=%s, key='%s', value='%s', comment='%s'", + section_info[section].name, key, value, comment); parser_fun_t section_parser = section_info[section].fun; assert(section_parser != NULL);