summaryrefslogtreecommitdiff
path: root/src/config_file.c
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2017-03-28 09:00:48 +0200
committerPatrick Steinhardt <ps@pks.im>2017-04-04 11:58:46 +0200
commit4467aeac421efd04bc8c814541535c02853e9418 (patch)
treef0f7a8561e9e163ac1d2c9ecfd4a6b05c7940974 /src/config_file.c
parenta25df009ef7f89fb8cbb26fb78e6c2e960a6c18b (diff)
downloadlibgit2-4467aeac421efd04bc8c814541535c02853e9418.tar.gz
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.
Diffstat (limited to 'src/config_file.c')
-rw-r--r--src/config_file.c23
1 files 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)