diff: plug leaks in dirstat

The array of dirstat_file contained in the dirstat_dir structure is
not freed after the processing ends.  Unfortunately, the member that
points at the array, .files, is incremented as the gather_dirstat()
function recursively walks it, and this needs to be plugged by
remembering the beginning of the array before gather_dirstat() mucks
with it and freeing it after we are done.

We can mark t4047 as leak-free.  t4000, which is marked as
leak-free, now can exercise dirstat in it, which will happen next.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Junio C Hamano 2023-05-05 14:19:17 -07:00
parent 34a94897e0
commit 83973981eb
2 changed files with 13 additions and 6 deletions

17
diff.c
View File

@ -2975,13 +2975,18 @@ static void conclude_dirstat(struct diff_options *options,
struct dirstat_dir *dir,
unsigned long changed)
{
/* This can happen even with many files, if everything was renames */
if (!changed)
return;
struct dirstat_file *to_free = dir->files;

/* Show all directories with more than x% of the changes */
QSORT(dir->files, dir->nr, dirstat_compare);
gather_dirstat(options, dir, changed, "", 0);
if (!changed) {
/* This can happen even with many files, if everything was renames */
;
} else {
/* Show all directories with more than x% of the changes */
QSORT(dir->files, dir->nr, dirstat_compare);
gather_dirstat(options, dir, changed, "", 0);
}

free(to_free);
}

static void show_dirstat(struct diff_options *options)

View File

@ -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