From a03113e80332fba6c77f43b21d398caad50b4b89 Mon Sep 17 00:00:00 2001 From: Nelson Elhage Date: Sat, 25 Aug 2018 17:04:39 +0000 Subject: config: convert unbounded recursion into a loop --- src/config_parse.c | 65 +++++++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 35 deletions(-) diff --git a/src/config_parse.c b/src/config_parse.c index eed6cf3a2..d40d47feb 100644 --- a/src/config_parse.c +++ b/src/config_parse.c @@ -317,48 +317,43 @@ static int parse_multiline_variable(git_config_parser *reader, git_buf *value, i { char *line = NULL, *proc_line = NULL; int quote_count; - bool multiline; + bool multiline = true; - /* Check that the next line exists */ - git_parse_advance_line(&reader->ctx); - line = git__strndup(reader->ctx.line, reader->ctx.line_len); - if (line == NULL) - return -1; + while (multiline) { + /* Check that the next line exists */ + git_parse_advance_line(&reader->ctx); + line = git__strndup(reader->ctx.line, reader->ctx.line_len); + if (line == NULL) + return -1; - /* We've reached the end of the file, there is no continuation. - * (this is not an error). - */ - if (line[0] == '\0') { - git__free(line); - return 0; - } - - quote_count = strip_comments(line, !!in_quotes); + /* We've reached the end of the file, there is no continuation. + * (this is not an error). + */ + if (line[0] == '\0') { + git__free(line); + return 0; + } - /* If it was just a comment, pretend it didn't exist */ - if (line[0] == '\0') { - git__free(line); - return parse_multiline_variable(reader, value, quote_count); - /* TODO: unbounded recursion. This **could** be exploitable */ - } + quote_count = strip_comments(line, !!in_quotes); - if (unescape_line(&proc_line, &multiline, line, in_quotes) < 0) { - git__free(line); - return -1; - } - /* add this line to the multiline var */ + /* If it was just a comment, pretend it didn't exist */ + if (line[0] == '\0') { + in_quotes = quote_count; + continue; + } - git_buf_puts(value, proc_line); - git__free(line); - git__free(proc_line); + if (unescape_line(&proc_line, &multiline, line, in_quotes) < 0) { + git__free(line); + return -1; + } + /* add this line to the multiline var */ - /* - * If we need to continue reading the next line, let's just - * keep putting stuff in the buffer - */ - if (multiline) - return parse_multiline_variable(reader, value, quote_count); + git_buf_puts(value, proc_line); + git__free(line); + git__free(proc_line); + in_quotes = quote_count; + } return 0; } -- cgit v1.2.1