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, struct dirstat_dir *dir,
unsigned long changed) unsigned long changed)
{ {
/* This can happen even with many files, if everything was renames */ struct dirstat_file *to_free = dir->files;
if (!changed)
return;


/* Show all directories with more than x% of the changes */ if (!changed) {
QSORT(dir->files, dir->nr, dirstat_compare); /* This can happen even with many files, if everything was renames */
gather_dirstat(options, dir, changed, "", 0); ;
} 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) static void show_dirstat(struct diff_options *options)

View File

@ -1,6 +1,8 @@
#!/bin/sh #!/bin/sh


test_description='diff --dirstat tests' test_description='diff --dirstat tests'

TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh


# set up two commits where the second commit has these files # set up two commits where the second commit has these files