Skip to content

Commit bc63e1e

Browse files
committed
config_parse: refactor error handling when parsing multiline variables
The current error handling for the multiline variable parser is a bit fragile, as each error condition has its own code to clear memory. Instead, unify error handling as far as possible to avoid this repetitive code. While at it, make use of `GITERR_CHECK_ALLOC` to correctly handle OOM situations and verify that the buffer we print into does not run out of memory either.
1 parent 38b8525 commit bc63e1e

File tree

1 file changed

+25
-19
lines changed

1 file changed

+25
-19
lines changed

src/config_parse.c

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -315,46 +315,52 @@ static int unescape_line(
315315

316316
static int parse_multiline_variable(git_config_parser *reader, git_buf *value, int in_quotes)
317317
{
318-
char *line = NULL, *proc_line = NULL;
319318
int quote_count;
320319
bool multiline = true;
321320

322321
while (multiline) {
322+
char *line = NULL, *proc_line = NULL;
323+
int error;
324+
323325
/* Check that the next line exists */
324326
git_parse_advance_line(&reader->ctx);
325327
line = git__strndup(reader->ctx.line, reader->ctx.line_len);
326-
if (line == NULL)
327-
return -1;
328+
GITERR_CHECK_ALLOC(line);
328329

329-
/* We've reached the end of the file, there is no continuation.
330+
/*
331+
* We've reached the end of the file, there is no continuation.
330332
* (this is not an error).
331333
*/
332334
if (line[0] == '\0') {
333-
git__free(line);
334-
return 0;
335+
error = 0;
336+
goto out;
335337
}
336338

339+
/* If it was just a comment, pretend it didn't exist */
337340
quote_count = strip_comments(line, !!in_quotes);
341+
if (line[0] == '\0')
342+
goto next;
338343

339-
/* If it was just a comment, pretend it didn't exist */
340-
if (line[0] == '\0') {
341-
git__free(line);
342-
in_quotes = quote_count;
343-
continue;
344-
}
344+
if ((error = unescape_line(&proc_line, &multiline,
345+
line, in_quotes)) < 0)
346+
goto out;
345347

346-
if (unescape_line(&proc_line, &multiline, line, in_quotes) < 0) {
347-
git__free(line);
348-
return -1;
349-
}
350-
/* add this line to the multiline var */
348+
/* Add this line to the multiline var */
349+
if ((error = git_buf_puts(value, proc_line)) < 0)
350+
goto out;
351351

352-
git_buf_puts(value, proc_line);
352+
next:
353353
git__free(line);
354354
git__free(proc_line);
355-
356355
in_quotes = quote_count;
356+
continue;
357+
358+
out:
359+
git__free(line);
360+
git__free(proc_line);
361+
return error;
357362
}
363+
358364
return 0;
359365
}
360366

0 commit comments

Comments
 (0)