Skip to content

Commit a03113e

Browse files
committed
config: convert unbounded recursion into a loop
1 parent 8856337 commit a03113e

File tree

1 file changed

+30
-35
lines changed

1 file changed

+30
-35
lines changed

src/config_parse.c

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -317,48 +317,43 @@ static int parse_multiline_variable(git_config_parser *reader, git_buf *value, i
317317
{
318318
char *line = NULL, *proc_line = NULL;
319319
int quote_count;
320-
bool multiline;
320+
bool multiline = true;
321321

322-
/* Check that the next line exists */
323-
git_parse_advance_line(&reader->ctx);
324-
line = git__strndup(reader->ctx.line, reader->ctx.line_len);
325-
if (line == NULL)
326-
return -1;
322+
while (multiline) {
323+
/* Check that the next line exists */
324+
git_parse_advance_line(&reader->ctx);
325+
line = git__strndup(reader->ctx.line, reader->ctx.line_len);
326+
if (line == NULL)
327+
return -1;
327328

328-
/* We've reached the end of the file, there is no continuation.
329-
* (this is not an error).
330-
*/
331-
if (line[0] == '\0') {
332-
git__free(line);
333-
return 0;
334-
}
335-
336-
quote_count = strip_comments(line, !!in_quotes);
329+
/* We've reached the end of the file, there is no continuation.
330+
* (this is not an error).
331+
*/
332+
if (line[0] == '\0') {
333+
git__free(line);
334+
return 0;
335+
}
337336

338-
/* If it was just a comment, pretend it didn't exist */
339-
if (line[0] == '\0') {
340-
git__free(line);
341-
return parse_multiline_variable(reader, value, quote_count);
342-
/* TODO: unbounded recursion. This **could** be exploitable */
343-
}
337+
quote_count = strip_comments(line, !!in_quotes);
344338

345-
if (unescape_line(&proc_line, &multiline, line, in_quotes) < 0) {
346-
git__free(line);
347-
return -1;
348-
}
349-
/* add this line to the multiline var */
339+
/* If it was just a comment, pretend it didn't exist */
340+
if (line[0] == '\0') {
341+
in_quotes = quote_count;
342+
continue;
343+
}
350344

351-
git_buf_puts(value, proc_line);
352-
git__free(line);
353-
git__free(proc_line);
345+
if (unescape_line(&proc_line, &multiline, line, in_quotes) < 0) {
346+
git__free(line);
347+
return -1;
348+
}
349+
/* add this line to the multiline var */
354350

355-
/*
356-
* If we need to continue reading the next line, let's just
357-
* keep putting stuff in the buffer
358-
*/
359-
if (multiline)
360-
return parse_multiline_variable(reader, value, quote_count);
351+
git_buf_puts(value, proc_line);
352+
git__free(line);
353+
git__free(proc_line);
361354

355+
in_quotes = quote_count;
356+
}
362357
return 0;
363358
}
364359

0 commit comments

Comments
 (0)