aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2024-11-05 07:17:17 +0100
committerJunio C Hamano <gitster@pobox.com>2024-11-04 22:37:54 -0800
commitff31b7b941286d91d03ddf4faac22b99149ea4b1 (patch)
tree61a3396d20cc1d83d97b095f9ebb9886b63ac178
parent3f692fe5beb817fbb22754281dfb5ebf8863d0a3 (diff)
downloadgit-ff31b7b941286d91d03ddf4faac22b99149ea4b1.tar.gz
trailer: fix leaking strbufs when formatting trailers
When formatting trailer lines we iterate through each of the trailers and munge their respective token/value pairs according to the trailer options. When formatting a trailer that has its `item->token` pointer set we perform the munging in two local buffers. In the case where we figure out that the value is empty and `trim_empty` is set we just skip over the trailer item. But the buffers are local to the loop and we don't release their contents, leading to a memory leak. Plug this leak by lifting the buffers outside of the loop and releasing them on function return. This fixes the memory leaks, but also optimizes the loop as we don't have to reallocate the buffers on every single iteration. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rwxr-xr-xt/t7513-interpret-trailers.sh1
-rw-r--r--trailer.c12
2 files changed, 8 insertions, 5 deletions
diff --git a/t/t7513-interpret-trailers.sh b/t/t7513-interpret-trailers.sh
index 0f7d8938d9..38d6ccaa00 100755
--- a/t/t7513-interpret-trailers.sh
+++ b/t/t7513-interpret-trailers.sh
@@ -5,6 +5,7 @@
test_description='git interpret-trailers'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# When we want one trailing space at the end of each line, let's use sed
diff --git a/trailer.c b/trailer.c
index 6bafe92b32..8ba350404d 100644
--- a/trailer.c
+++ b/trailer.c
@@ -1111,6 +1111,8 @@ void format_trailers(const struct process_trailer_options *opts,
struct list_head *trailers,
struct strbuf *out)
{
+ struct strbuf tok = STRBUF_INIT;
+ struct strbuf val = STRBUF_INIT;
size_t origlen = out->len;
struct list_head *pos;
struct trailer_item *item;
@@ -1118,9 +1120,9 @@ void format_trailers(const struct process_trailer_options *opts,
list_for_each(pos, trailers) {
item = list_entry(pos, struct trailer_item, list);
if (item->token) {
- struct strbuf tok = STRBUF_INIT;
- struct strbuf val = STRBUF_INIT;
+ strbuf_reset(&tok);
strbuf_addstr(&tok, item->token);
+ strbuf_reset(&val);
strbuf_addstr(&val, item->value);
/*
@@ -1151,9 +1153,6 @@ void format_trailers(const struct process_trailer_options *opts,
if (!opts->separator)
strbuf_addch(out, '\n');
}
- strbuf_release(&tok);
- strbuf_release(&val);
-
} else if (!opts->only_trailers) {
if (opts->separator && out->len != origlen) {
strbuf_addbuf(out, opts->separator);
@@ -1165,6 +1164,9 @@ void format_trailers(const struct process_trailer_options *opts,
strbuf_addch(out, '\n');
}
}
+
+ strbuf_release(&tok);
+ strbuf_release(&val);
}
void format_trailers_from_commit(const struct process_trailer_options *opts,