diff mbox series

[v2,1/5] diff: --dirstat leakfix

Message ID 20230817222949.3835424-2-gitster@pobox.com (mailing list archive)
State Superseded
Headers show
Series fix interactions with "-w" and "--exit-code" | expand

Commit Message

Junio C Hamano Aug. 17, 2023, 10:29 p.m. UTC
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@pobox.com>
---
 diff.c                  | 14 ++++++++++++--
 t/t4047-diff-dirstat.sh |  2 ++
 2 files changed, 14 insertions(+), 2 deletions(-)
diff mbox series

Patch

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