From 2d102c2bca1a0c50f17108189f134279cad941cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Fri, 4 Mar 2022 19:32:16 +0100 Subject: [PATCH] range-diff: plug memory leak in read_patches() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Amend code added in d9c66f0b5bf (range-diff: first rudimentary implementation, 2018-08-13) to use a "goto cleanup" pattern. This makes for less code, and frees memory that we'd previously leak. The reason for changing free(util) to FREE_AND_NULL(util) is because at the end of the function we append the contents of "util" to a "struct string_list" if it's non-NULL. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- range-diff.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/range-diff.c b/range-diff.c index b2a2961f521596..b72eb9fdbee8d8 100644 --- a/range-diff.c +++ b/range-diff.c @@ -40,6 +40,7 @@ static int read_patches(const char *range, struct string_list *list, char *line, *current_filename = NULL; ssize_t len; size_t size; + int ret = -1; strvec_pushl(&cp.args, "log", "--no-color", "-p", "--no-merges", "--reverse", "--date-order", "--decorate=no", @@ -68,10 +69,10 @@ static int read_patches(const char *range, struct string_list *list, if (strbuf_read(&contents, cp.out, 0) < 0) { error_errno(_("could not read `log` output")); finish_command(&cp); - return -1; + goto cleanup; } if (finish_command(&cp)) - return -1; + goto cleanup; line = contents.buf; size = contents.len; @@ -95,12 +96,9 @@ static int read_patches(const char *range, struct string_list *list, CALLOC_ARRAY(util, 1); if (get_oid(p, &util->oid)) { error(_("could not parse commit '%s'"), p); - free(util); - free(current_filename); + FREE_AND_NULL(util); string_list_clear(list, 1); - strbuf_release(&buf); - strbuf_release(&contents); - return -1; + goto cleanup; } util->matching = -1; in_header = 1; @@ -111,11 +109,8 @@ static int read_patches(const char *range, struct string_list *list, error(_("could not parse first line of `log` output: " "did not start with 'commit ': '%s'"), line); - free(current_filename); string_list_clear(list, 1); - strbuf_release(&buf); - strbuf_release(&contents); - return -1; + goto cleanup; } if (starts_with(line, "diff --git")) { @@ -136,12 +131,9 @@ static int read_patches(const char *range, struct string_list *list, if (len < 0) { error(_("could not parse git header '%.*s'"), orig_len, line); - free(util); - free(current_filename); + FREE_AND_NULL(util); string_list_clear(list, 1); - strbuf_release(&buf); - strbuf_release(&contents); - return -1; + goto cleanup; } strbuf_addstr(&buf, " ## "); if (patch.is_new > 0) @@ -219,6 +211,9 @@ static int read_patches(const char *range, struct string_list *list, strbuf_addch(&buf, '\n'); util->diffsize++; } + + ret = 0; +cleanup: strbuf_release(&contents); if (util) @@ -226,7 +221,7 @@ static int read_patches(const char *range, struct string_list *list, strbuf_release(&buf); free(current_filename); - return 0; + return ret; } static int patch_util_cmp(const void *dummy, const struct patch_util *a,