From 4467aeac421efd04bc8c814541535c02853e9418 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 28 Mar 2017 09:00:48 +0200 Subject: [PATCH] config_file: handle errors other than OOM while parsing section headers The current code in `parse_section_header_ext` is only prepared to properly handle out-of-memory conditions for the `git_buf` structure. While very unlikely and probably caused by a programming error, it is also possible to run into error conditions other than out-of-memory previous to reaching the actual parsing loop. In these cases, we will run into undefined behavior as the `rpos` variable is only initialized after these triggerable errors, but we use it in the cleanup-routine. Fix the issue by unifying the function's cleanup code with an `end_error` section, which will not use the `rpos` variable. --- src/config_file.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/config_file.c b/src/config_file.c index 50c5a3d82..7df43c85f 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -1027,7 +1027,7 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con first_quote = strchr(line, '"'); if (first_quote == NULL) { set_parse_error(reader, 0, "Missing quotation marks in section header"); - return -1; + goto end_error; } last_quote = strrchr(line, '"'); @@ -1035,7 +1035,7 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con if (quoted_len == 0) { set_parse_error(reader, 0, "Missing closing quotation mark in section header"); - return -1; + goto end_error; } GITERR_CHECK_ALLOC_ADD(&alloc_len, base_name_len, quoted_len); @@ -1043,7 +1043,7 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con if (git_buf_grow(&buf, alloc_len) < 0 || git_buf_printf(&buf, "%s.", base_name) < 0) - goto end_parse; + goto end_error; rpos = 0; @@ -1059,8 +1059,7 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con switch (c) { case 0: set_parse_error(reader, 0, "Unexpected end-of-line in section header"); - git_buf_free(&buf); - return -1; + goto end_error; case '"': goto end_parse; @@ -1070,8 +1069,7 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con if (c == 0) { set_parse_error(reader, rpos, "Unexpected end-of-line in section header"); - git_buf_free(&buf); - return -1; + goto end_error; } default: @@ -1083,10 +1081,8 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con } while (line + rpos < last_quote); end_parse: - if (git_buf_oom(&buf)) { - git_buf_free(&buf); - return -1; - } + if (git_buf_oom(&buf)) + goto end_error; if (line[rpos] != '"' || line[rpos + 1] != ']') { set_parse_error(reader, rpos, "Unexpected text after closing quotes"); @@ -1096,6 +1092,11 @@ end_parse: *section_name = git_buf_detach(&buf); return 0; + +end_error: + git_buf_free(&buf); + + return -1; } static int parse_section_header(struct reader *reader, char **section_out)