dir: release untracked cache data
There are several cases where we invalidate untracked cache directory entries where we do not free the underlying data, but reset the number of entries. This causes us to leak memory because `free_untracked()` will not iterate over any potential entries which we still had in the array. Fix this issue by freeing old entries. The leak is exposed by t7519, but plugging it alone does not make the whole test suite pass. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Nov 5, 2024 at 07:17 UTC
e4ba54d47b675e0613a2644f37c0b4f57a833a44
1 file changed
+8
dir.c
+8
@@ -1056,6 +1056,8 @@ static void do_invalidate_gitignore(struct untracked_cache_dir *dir)
1056
{
1057
int i;
1058
dir->valid = 0;
1059
+ for (size_t i = 0; i < dir->untracked_nr; i++)
1060
+ free(dir->untracked[i]);
1061
dir->untracked_nr = 0;
1062
for (i = 0; i < dir->dirs_nr; i++)
1063
do_invalidate_gitignore(dir->dirs[i]);
@@ -1083,6 +1085,8 @@ static void invalidate_directory(struct untracked_cache *uc,
1085
uc->dir_invalidated++;
1086
1087
dir->valid = 0;
1088
+ for (size_t i = 0; i < dir->untracked_nr; i++)
1089
+ free(dir->untracked[i]);
1090
dir->untracked_nr = 0;
1091
for (i = 0; i < dir->dirs_nr; i++)
1092
dir->dirs[i]->recurse = 0;
@@ -3573,6 +3577,8 @@ static void write_one_dir(struct untracked_cache_dir *untracked,
3577
* for safety..
3578
*/
3579
if (!untracked->valid) {
3580
+ for (size_t i = 0; i < untracked->untracked_nr; i++)
3581
+ free(untracked->untracked[i]);
3582
untracked->untracked_nr = 0;
3583
untracked->check_only = 0;
3584
}
@@ -3905,6 +3911,8 @@ static void invalidate_one_directory(struct untracked_cache *uc,
3911
{
3912
uc->dir_invalidated++;
3913
ucd->valid = 0;
3914
+ for (size_t i = 0; i < ucd->untracked_nr; i++)
3915
+ free(ucd->untracked[i]);
3916
ucd->untracked_nr = 0;
3917
}
3918