dir.c: free "ident" and "exclude_per_dir" in "struct untracked_cache"

When the "ident" member of the structure was added in 1e8fef609e7 (untracked cache: guard and disable on system changes, 2015-03-08) this function wasn't updated to free it. Let's do so. Let's also free the "exclude_per_dir" memory we've been leaking since[1], while making sure not to free() the constant ".gitignore" string we add by default[2]. As we now have three struct members we're freeing let's change free_untracked_cache() to return early if "uc" isn't defined. We won't hand it to free() now, but that was just for convenience, once we're dealing with >=2 struct members this pattern is more convenient. 1. f9e6c649589 (untracked cache: load from UNTR index extension, 2015-03-08) 2. 039bc64e886 (core.excludesfile clean-up, 2007-11-14) Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com>

Ævar Arnfjörð Bjarmason committed Nov 8, 2022 at 19:17 UTC 083fd1a264a78b50bc2339d85f4d1113c01a4172
2 files changed +8 -3
dir.c
+7 -3
@@ -3581,8 +3581,12 @@ static void free_untracked(struct untracked_cache_dir *ucd)
3581
3582 void free_untracked_cache(struct untracked_cache *uc)
3583 {
3584 - if (uc)
3585 - free_untracked(uc->root);
3584 + if (!uc)
3585 + return;
3586 +
3587 + free(uc->exclude_per_dir_to_free);
3588 + strbuf_release(&uc->ident);
3589 + free_untracked(uc->root);
3590 free(uc);
3591 }
3592
@@ -3739,7 +3743,7 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long
3743 next + offset + hashsz);
3744 uc->dir_flags = get_be32(next + ouc_offset(dir_flags));
3745 exclude_per_dir = (const char *)next + exclude_per_dir_offset;
3742 - uc->exclude_per_dir = xstrdup(exclude_per_dir);
3746 + uc->exclude_per_dir = uc->exclude_per_dir_to_free = xstrdup(exclude_per_dir);
3747 /* NUL after exclude_per_dir is covered by sizeof(*ouc) */
3748 next += exclude_per_dir_offset + strlen(exclude_per_dir) + 1;
3749 if (next >= end)
dir.h
+1
@@ -188,6 +188,7 @@ struct untracked_cache {
188 struct oid_stat ss_info_exclude;
189 struct oid_stat ss_excludes_file;
190 const char *exclude_per_dir;
191 + char *exclude_per_dir_to_free;
192 struct strbuf ident;
193 /*
194 * dir_struct#flags must match dir_flags or the untracked