aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2024-09-09 19:21:18 -0400
committerJunio C Hamano <gitster@pobox.com>2024-09-09 16:26:11 -0700
commitdb629c61f0be3665a36750fe2353b9ee958b0376 (patch)
treef825574355c43dbded14d148c86d1d64e9a51fc7
parentf046127b6682f98d41bb4d26164da7f1a4a8e8d0 (diff)
downloadgit-db629c61f0be3665a36750fe2353b9ee958b0376.tar.gz
ref-filter: add ref_format_clear() function
After using the ref-filter API, callers should use ref_filter_clear() to free any used memory. However, there's not a matching function to clear the ref_format struct. Traditionally this did not need to be cleaned up, as it was just a way for the caller to store and pass format options as a single unit. Even though the parsing step of some placeholders may allocate data, that's usually inside their "used_atom" structs, which are part of the ref_filter itself. But a few placeholders keep data outside of there. The %(ahead-behind) and %(is-base) parsers both keep a master list of bases, because they perform a single filtering pass outside of the use of any particular atom. And since the format parser does not have access to the ref_filter struct, they store their cross-atom data in the ref_format struct itself. And thus when they are finished, the ref_format also needs to be cleaned up. So let's add a function to do so, and call it from all of the users of the ref-filter API. The %(is-base) case is found by running LSan on t6300. After this patch, the script can now be marked leak-free. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin/branch.c1
-rw-r--r--builtin/for-each-ref.c1
-rw-r--r--builtin/tag.c1
-rw-r--r--builtin/verify-tag.c1
-rw-r--r--ref-filter.c13
-rw-r--r--ref-filter.h3
-rwxr-xr-xt/t6300-for-each-ref.sh1
7 files changed, 21 insertions, 0 deletions
diff --git a/builtin/branch.c b/builtin/branch.c
index 3f870741bf..c98601c6fe 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -878,6 +878,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
string_list_clear(&output, 0);
ref_sorting_release(sorting);
ref_filter_clear(&filter);
+ ref_format_clear(&format);
return 0;
} else if (edit_description) {
const char *branch_name;
diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c
index 5517a4a1c0..c72fa05bcb 100644
--- a/builtin/for-each-ref.c
+++ b/builtin/for-each-ref.c
@@ -104,6 +104,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
filter_and_format_refs(&filter, flags, sorting, &format);
ref_filter_clear(&filter);
+ ref_format_clear(&format);
ref_sorting_release(sorting);
strvec_clear(&vec);
return 0;
diff --git a/builtin/tag.c b/builtin/tag.c
index a1fb218512..607e48e311 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -702,6 +702,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
cleanup:
ref_sorting_release(sorting);
ref_filter_clear(&filter);
+ ref_format_clear(&format);
strbuf_release(&buf);
strbuf_release(&ref);
strbuf_release(&reflog_msg);
diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c
index c731e2f87b..77becf7e75 100644
--- a/builtin/verify-tag.c
+++ b/builtin/verify-tag.c
@@ -65,5 +65,6 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix)
if (format.format)
pretty_print_ref(name, &oid, &format);
}
+ ref_format_clear(&format);
return had_error;
}
diff --git a/ref-filter.c b/ref-filter.c
index 0f51095bbd..ce1bcfad85 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -3621,3 +3621,16 @@ void ref_filter_clear(struct ref_filter *filter)
free_commit_list(filter->unreachable_from);
ref_filter_init(filter);
}
+
+void ref_format_init(struct ref_format *format)
+{
+ struct ref_format blank = REF_FORMAT_INIT;
+ memcpy(format, &blank, sizeof(blank));
+}
+
+void ref_format_clear(struct ref_format *format)
+{
+ string_list_clear(&format->bases, 0);
+ string_list_clear(&format->is_base_tips, 0);
+ ref_format_init(format);
+}
diff --git a/ref-filter.h b/ref-filter.h
index e794b8a676..754038ab07 100644
--- a/ref-filter.h
+++ b/ref-filter.h
@@ -221,4 +221,7 @@ void filter_is_base(struct repository *r,
void ref_filter_init(struct ref_filter *filter);
void ref_filter_clear(struct ref_filter *filter);
+void ref_format_init(struct ref_format *format);
+void ref_format_clear(struct ref_format *format);
+
#endif /* REF_FILTER_H */
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index e8db612f95..b3163629c5 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -5,6 +5,7 @@
test_description='for-each-ref test'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
GNUPGHOME_NOT_USED=$GNUPGHOME
. "$TEST_DIRECTORY"/lib-gpg.sh