]> git.ipfire.org Git - thirdparty/git.git/commitdiff
dir: release untracked cache data
authorPatrick Steinhardt <ps@pks.im>
Tue, 5 Nov 2024 06:17:35 +0000 (07:17 +0100)
committerJunio C Hamano <gitster@pobox.com>
Tue, 5 Nov 2024 06:37:55 +0000 (22:37 -0800)
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>
dir.c

diff --git a/dir.c b/dir.c
index e3ddd5b529647580b77ec1db54c59ce04ea6f9ac..cb9782fa11f54c071740b0786d127dff9d34e231 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -1056,6 +1056,8 @@ static void do_invalidate_gitignore(struct untracked_cache_dir *dir)
 {
        int i;
        dir->valid = 0;
+       for (size_t i = 0; i < dir->untracked_nr; i++)
+               free(dir->untracked[i]);
        dir->untracked_nr = 0;
        for (i = 0; i < dir->dirs_nr; i++)
                do_invalidate_gitignore(dir->dirs[i]);
@@ -1083,6 +1085,8 @@ static void invalidate_directory(struct untracked_cache *uc,
                uc->dir_invalidated++;
 
        dir->valid = 0;
+       for (size_t i = 0; i < dir->untracked_nr; i++)
+               free(dir->untracked[i]);
        dir->untracked_nr = 0;
        for (i = 0; i < dir->dirs_nr; i++)
                dir->dirs[i]->recurse = 0;
@@ -3573,6 +3577,8 @@ static void write_one_dir(struct untracked_cache_dir *untracked,
         * for safety..
         */
        if (!untracked->valid) {
+               for (size_t i = 0; i < untracked->untracked_nr; i++)
+                       free(untracked->untracked[i]);
                untracked->untracked_nr = 0;
                untracked->check_only = 0;
        }
@@ -3905,6 +3911,8 @@ static void invalidate_one_directory(struct untracked_cache *uc,
 {
        uc->dir_invalidated++;
        ucd->valid = 0;
+       for (size_t i = 0; i < ucd->untracked_nr; i++)
+               free(ucd->untracked[i]);
        ucd->untracked_nr = 0;
 }