config: handle trailing comments and empty values

This commit is contained in:
Daniel Eklöf 2020-07-28 19:55:09 +02:00
parent 698c9b240f
commit eadb5a4a88
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 33 additions and 16 deletions

View file

@ -29,6 +29,7 @@
### Fixed ### Fixed
* Crash when starting a selection inside the margins. * Crash when starting a selection inside the margins.
* Handle trailing comments in `footrc`
### Security ### Security

View file

@ -822,7 +822,7 @@ parse_config_file(FILE *f, struct config *conf, const char *path)
break; break;
} }
/* Strip whitespace */ /* Strip leading whitespace */
char *line = _line; char *line = _line;
{ {
while (isspace(*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] == '#') if (line[0] == '\0' || line[0] == '#')
continue; 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 */ /* Check for new section */
if (line[0] == '[') { if (key_value[0] == '[') {
char *end = strchr(line, ']'); char *end = strchr(key_value, ']');
if (end == NULL) { 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; goto err;
} }
@ -851,13 +855,13 @@ parse_config_file(FILE *f, struct config *conf, const char *path)
section = SECTION_COUNT; section = SECTION_COUNT;
for (enum section i = 0; i < SECTION_COUNT; i++) { 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; section = i;
} }
} }
if (section == SECTION_COUNT) { 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; goto err;
} }
@ -865,11 +869,20 @@ parse_config_file(FILE *f, struct config *conf, const char *path)
continue; 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"); 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) */ /* Strip trailing whitespace from key (leading stripped earlier) */
{ if (key[0] != '\0') {
assert(!isspace(*key)); assert(!isspace(*key));
char *end = key + strlen(key) - 1; 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 (value == NULL) {
if (key != NULL && strlen(key) > 0 && key[0] != '#') { 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; goto err;
} }
continue; continue;
} }
/* Strip leading whitespace from value (trailing stripped earlier) */ /* Strip leading+trailing whitespace from value */
{ {
while (isspace(*value)) while (isspace(*value))
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] == '#') LOG_DBG("section=%s, key='%s', value='%s', comment='%s'",
continue; section_info[section].name, key, value, comment);
LOG_DBG("section=%s, key='%s', value='%s'",
section_names[section], key, value);
parser_fun_t section_parser = section_info[section].fun; parser_fun_t section_parser = section_info[section].fun;
assert(section_parser != NULL); assert(section_parser != NULL);