From: Junio C Hamano <gitster@pobox.com>
To: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Cc: git@vger.kernel.org, Jonathan Tan <jonathantanmy@google.com>
Subject: Re: [PATCH] ls-remote & transport API: release "struct transport_ls_refs_options"
Date: Sun, 06 Feb 2022 18:11:39 -0800 [thread overview]
Message-ID: <xmqqwni7h1d0.fsf@gitster.g> (raw)
In-Reply-To: <patch-1.1-e80e8f64eae-20220205T000809Z-avarab@gmail.com> ("Ævar Arnfjörð Bjarmason"'s message of "Sat, 5 Feb 2022 01:08:14 +0100")
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> Fix a memory leak in codepaths that use the "struct
> transport_ls_refs_options" API. Since the introduction of the struct
> in 39835409d10 (connect, transport: encapsulate arg in struct,
> 2021-02-05) the caller has been responsible for freeing it.
>
> That commit in turn migrated code originally added in
> 402c47d9391 (clone: send ref-prefixes when using protocol v2,
> 2018-07-20) and b4be74105fe (ls-remote: pass ref prefixes when
> requesting a remote's refs, 2018-03-15). Only some of those codepaths
> were releasing the allocated resources of the struct, now all of them
> will.
>
> Mark the "t/t5511-refspec.sh" test as passing when git is compiled
> with SANITIZE=leak. They'll now be listed as running under the
> "GIT_TEST_PASSING_SANITIZE_LEAK=true" test mode (the "linux-leaks" CI
> target). Previously 24/47 tests would fail.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
> builtin/clone.c | 13 ++++++-------
> builtin/fetch.c | 2 +-
> builtin/ls-remote.c | 3 ++-
> connect.c | 4 ++--
> t/t5511-refspec.sh | 1 +
> transport.c | 8 +++++++-
> transport.h | 10 +++++++---
> 7 files changed, 26 insertions(+), 15 deletions(-)
This ...
> +void transport_ls_refs_options_release(struct transport_ls_refs_options *opts)
> +{
> + strvec_clear(&opts->ref_prefixes);
> + free((char *)opts->unborn_head_target);
> +}
> +
... addition is very much welcomed. And instead of different code
paths doing "we used this member, so clear only that" ad-hoc, making
them all call it makes it very much pleasant read.
> diff --git a/builtin/clone.c b/builtin/clone.c
> index 727e16e0aea..8564e5f603f 100644
> --- a/builtin/clone.c
> +++ b/builtin/clone.c
> @@ -1233,7 +1233,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
> }
> else {
> const char *branch;
> - char *ref;
> + const char *ref;
> + char *ref_free = NULL;
>
> if (option_branch)
> die(_("Remote branch %s not found in upstream %s"),
> @@ -1250,17 +1251,16 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
> skip_prefix(transport_ls_refs_options.unborn_head_target,
> "refs/heads/", &branch)) {
> ref = transport_ls_refs_options.unborn_head_target;
> - transport_ls_refs_options.unborn_head_target = NULL;
> create_symref("HEAD", ref, reflog_msg.buf);
> } else {
> branch = git_default_branch_name(0);
> - ref = xstrfmt("refs/heads/%s", branch);
> + ref_free = xstrfmt("refs/heads/%s", branch);
> + ref = ref_free;
> }
>
> if (!option_bare)
> install_branch_config(0, branch, remote_name, ref);
> -
> - free(ref);
> + free(ref_free);
> }
It is a bit unfortunate that "ref" has to be sometimes a borrowed
pointer and some other times own the storage, only to allow us write
the call that uses the variable only once. But under the
constraints of the current code, I think this is the best we could
do.
In our code base, we would usually call the auxiliary variable
"to_free", because its "ref"-ness does not matter and its sole
reason to exist is to be the "other owner" of the piece of memory,
to relieve the "ref" variable from the responsibility of releasing
resources. With it, "ref" consistently borrows from somebody else,
either "to_free", or the .unborn_head_target member, and does not
have to be (and should not be) freed itself.
prev parent reply other threads:[~2022-02-07 2:11 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-05 0:08 [PATCH] ls-remote & transport API: release "struct transport_ls_refs_options" Ævar Arnfjörð Bjarmason
2022-02-07 2:11 ` Junio C Hamano [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xmqqwni7h1d0.fsf@gitster.g \
--to=gitster@pobox.com \
--cc=avarab@gmail.com \
--cc=git@vger.kernel.org \
--cc=jonathantanmy@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).