summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2023-05-15 13:59:04 -0700
committerJunio C Hamano <gitster@pobox.com>2023-05-15 13:59:05 -0700
commit1e1dcb2a423cad350e8f20fdcc957064e5cff528 (patch)
treed32cc86771285117dec8eeda9ac45b1f931fc5e9
parentcd2b740ca95291b81b8e75000d2ee76b4f735877 (diff)
parent83973981eb475ce90f829f8a5bd6ea99cd3bbd8e (diff)
downloadgit-1e1dcb2a423cad350e8f20fdcc957064e5cff528.tar.gz
Merge branch 'jc/dirstat-plug-leaks'
"git diff --dirstat" leaked memory, which has been plugged. * jc/dirstat-plug-leaks: diff: plug leaks in dirstat diff: refactor common tail part of dirstat computation
-rw-r--r--diff.c34
-rwxr-xr-xt/t4047-diff-dirstat.sh2
2 files changed, 22 insertions, 14 deletions
diff --git a/diff.c b/diff.c
index 71513d92e8..3c88c37908 100644
--- a/diff.c
+++ b/diff.c
@@ -3007,6 +3007,24 @@ static int dirstat_compare(const void *_a, const void *_b)
return strcmp(a->name, b->name);
}
+static void conclude_dirstat(struct diff_options *options,
+ struct dirstat_dir *dir,
+ unsigned long changed)
+{
+ 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);
+ }
+
+ free(to_free);
+}
+
static void show_dirstat(struct diff_options *options)
{
int i;
@@ -3096,13 +3114,7 @@ found_damage:
dir.nr++;
}
- /* This can happen even with many files, if everything was renames */
- if (!changed)
- return;
-
- /* Show all directories with more than x% of the changes */
- QSORT(dir.files, dir.nr, dirstat_compare);
- gather_dirstat(options, &dir, changed, "", 0);
+ conclude_dirstat(options, &dir, changed);
}
static void show_dirstat_by_line(struct diffstat_t *data, struct diff_options *options)
@@ -3140,13 +3152,7 @@ static void show_dirstat_by_line(struct diffstat_t *data, struct diff_options *o
dir.nr++;
}
- /* This can happen even with many files, if everything was renames */
- if (!changed)
- return;
-
- /* Show all directories with more than x% of the changes */
- QSORT(dir.files, dir.nr, dirstat_compare);
- gather_dirstat(options, &dir, changed, "", 0);
+ conclude_dirstat(options, &dir, changed);
}
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