Skip to content

Commit 4467aea

Browse files
committed
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.
1 parent a25df00 commit 4467aea

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

src/config_file.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,23 +1027,23 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con
10271027
first_quote = strchr(line, '"');
10281028
if (first_quote == NULL) {
10291029
set_parse_error(reader, 0, "Missing quotation marks in section header");
1030-
return -1;
1030+
goto end_error;
10311031
}
10321032

10331033
last_quote = strrchr(line, '"');
10341034
quoted_len = last_quote - first_quote;
10351035

10361036
if (quoted_len == 0) {
10371037
set_parse_error(reader, 0, "Missing closing quotation mark in section header");
1038-
return -1;
1038+
goto end_error;
10391039
}
10401040

10411041
GITERR_CHECK_ALLOC_ADD(&alloc_len, base_name_len, quoted_len);
10421042
GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2);
10431043

10441044
if (git_buf_grow(&buf, alloc_len) < 0 ||
10451045
git_buf_printf(&buf, "%s.", base_name) < 0)
1046-
goto end_parse;
1046+
goto end_error;
10471047

10481048
rpos = 0;
10491049

@@ -1059,8 +1059,7 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con
10591059
switch (c) {
10601060
case 0:
10611061
set_parse_error(reader, 0, "Unexpected end-of-line in section header");
1062-
git_buf_free(&buf);
1063-
return -1;
1062+
goto end_error;
10641063

10651064
case '"':
10661065
goto end_parse;
@@ -1070,8 +1069,7 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con
10701069

10711070
if (c == 0) {
10721071
set_parse_error(reader, rpos, "Unexpected end-of-line in section header");
1073-
git_buf_free(&buf);
1074-
return -1;
1072+
goto end_error;
10751073
}
10761074

10771075
default:
@@ -1083,10 +1081,8 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con
10831081
} while (line + rpos < last_quote);
10841082

10851083
end_parse:
1086-
if (git_buf_oom(&buf)) {
1087-
git_buf_free(&buf);
1088-
return -1;
1089-
}
1084+
if (git_buf_oom(&buf))
1085+
goto end_error;
10901086

10911087
if (line[rpos] != '"' || line[rpos + 1] != ']') {
10921088
set_parse_error(reader, rpos, "Unexpected text after closing quotes");
@@ -1096,6 +1092,11 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con
10961092

10971093
*section_name = git_buf_detach(&buf);
10981094
return 0;
1095+
1096+
end_error:
1097+
git_buf_free(&buf);
1098+
1099+
return -1;
10991100
}
11001101

11011102
static int parse_section_header(struct reader *reader, char **section_out)

0 commit comments

Comments
 (0)