Commit 695067f7d65ff6de2162917ce3092a2307020e59

Patrick Steinhardt 2018-09-06T11:54:01

Merge pull request #4792 from nelhage/multiline-leak config: Fix a leak parsing multi-line config entries

diff --git a/src/config_parse.c b/src/config_parse.c
index d40d47f..282aabe 100644
--- a/src/config_parse.c
+++ b/src/config_parse.c
@@ -315,45 +315,52 @@ 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 = true;
 
 	while (multiline) {
+		char *line = NULL, *proc_line = NULL;
+		int error;
+
 		/* 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;
+		GITERR_CHECK_ALLOC(line);
 
-		/* We've reached the end of the file, there is no continuation.
+		/*
+		 * 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;
+			error = 0;
+			goto out;
 		}
 
+		/* 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') {
-			in_quotes = quote_count;
-			continue;
-		}
+		if ((error = unescape_line(&proc_line, &multiline,
+					   line, in_quotes)) < 0)
+			goto out;
 
-		if (unescape_line(&proc_line, &multiline, line, in_quotes) < 0) {
-			git__free(line);
-			return -1;
-		}
-		/* add this line to the multiline var */
+		/* Add this line to the multiline var */
+		if ((error = git_buf_puts(value, proc_line)) < 0)
+			goto out;
 
-		git_buf_puts(value, proc_line);
+next:
 		git__free(line);
 		git__free(proc_line);
-
 		in_quotes = quote_count;
+		continue;
+
+out:
+		git__free(line);
+		git__free(proc_line);
+		return error;
 	}
+
 	return 0;
 }