diff options
Diffstat (limited to 'src/config_parse.c')
| -rw-r--r-- | src/config_parse.c | 70 |
1 files changed, 36 insertions, 34 deletions
diff --git a/src/config_parse.c b/src/config_parse.c index 149550dcd..d4c1c2bbd 100644 --- a/src/config_parse.c +++ b/src/config_parse.c @@ -315,49 +315,51 @@ done: static int parse_multiline_variable(git_config_parser *reader, git_buf *value, int in_quotes) { - 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) { + char *line = NULL, *proc_line = NULL; + int error; - /* 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; - } + /* Check that the next line exists */ + git_parse_advance_line(&reader->ctx); + line = git__strndup(reader->ctx.line, reader->ctx.line_len); + GITERR_CHECK_ALLOC(line); + + /* + * We've reached the end of the file, there is no continuation. + * (this is not an error). + */ + if (line[0] == '\0') { + error = 0; + goto out; + } - quote_count = strip_comments(line, !!in_quotes); + /* If it was just a comment, pretend it didn't exist */ + quote_count = strip_comments(line, !!in_quotes); + if (line[0] == '\0') + goto next; - /* If it was just a comment, pretend it didn't exist */ - if (line[0] == '\0') { + if ((error = unescape_line(&proc_line, &multiline, + line, in_quotes)) < 0) + goto out; + + /* Add this line to the multiline var */ + if ((error = git_buf_puts(value, proc_line)) < 0) + goto out; + +next: git__free(line); - return parse_multiline_variable(reader, value, quote_count); - /* TODO: unbounded recursion. This **could** be exploitable */ - } + git__free(proc_line); + in_quotes = quote_count; + continue; - if (unescape_line(&proc_line, &multiline, line, in_quotes) < 0) { +out: git__free(line); - return -1; + git__free(proc_line); + return error; } - /* add this line to the multiline var */ - - git_buf_puts(value, proc_line); - git__free(line); - git__free(proc_line); - - /* - * 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); return 0; } |
