]> git.ipfire.org Git - thirdparty/git.git/commitdiff
diff: plug leaks in dirstat
authorJunio C Hamano <gitster@pobox.com>
Fri, 5 May 2023 21:19:17 +0000 (14:19 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 5 May 2023 21:24:09 +0000 (14:24 -0700)
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>
diff.c
t/t4047-diff-dirstat.sh

diff --git a/diff.c b/diff.c
index e13d0f8b678078bb69218e6b1b94c4ad8728e709..d52db685f70938473b3c83bc2229ec2a8acd323a 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -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;
+
+       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);
+       }
 
-       /* 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)
index 7fec2cb9cd783f5aeff27236c8e54ddb2241e1be..70224c3da1494262eb4b2a46c58e001d74f37a9e 100755 (executable)
@@ -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