The dirstat_dir structure holds a list of files that had "damages" and is used to summarize the change by directory. It was allocated, used, and then left behind, leaking. Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx> --- diff.c | 14 ++++++++++++-- t/t4047-diff-dirstat.sh | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/diff.c b/diff.c index 648f6717a5..03d0cfc700 100644 --- a/diff.c +++ b/diff.c @@ -2977,6 +2977,7 @@ static void show_dirstat(struct diff_options *options) unsigned long changed; struct dirstat_dir dir; struct diff_queue_struct *q = &diff_queued_diff; + struct dirstat_file *to_free; dir.files = NULL; dir.alloc = 0; @@ -3060,13 +3061,17 @@ static void show_dirstat(struct diff_options *options) dir.nr++; } + to_free = dir.files; + /* This can happen even with many files, if everything was renames */ if (!changed) - return; + goto free_return; /* Show all directories with more than x% of the changes */ QSORT(dir.files, dir.nr, dirstat_compare); gather_dirstat(options, &dir, changed, "", 0); +free_return: + free(to_free); } static void show_dirstat_by_line(struct diffstat_t *data, struct diff_options *options) @@ -3074,6 +3079,7 @@ static void show_dirstat_by_line(struct diffstat_t *data, struct diff_options *o int i; unsigned long changed; struct dirstat_dir dir; + struct dirstat_file *to_free; if (data->nr == 0) return; @@ -3104,13 +3110,17 @@ static void show_dirstat_by_line(struct diffstat_t *data, struct diff_options *o dir.nr++; } + to_free = dir.files; + /* This can happen even with many files, if everything was renames */ if (!changed) - return; + goto free_return; /* Show all directories with more than x% of the changes */ QSORT(dir.files, dir.nr, dirstat_compare); gather_dirstat(options, &dir, changed, "", 0); +free_return: + free(to_free); } static void free_diffstat_file(struct diffstat_file *f) diff --git a/t/t4047-diff-dirstat.sh b/t/t4047-diff-dirstat.sh index 7fec2cb9cd..70224c3da1 100755 --- a/t/t4047-diff-dirstat.sh +++ b/t/t4047-diff-dirstat.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='diff --dirstat tests' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # set up two commits where the second commit has these files -- 2.42.0-rc2