All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick Steinhardt <ps@pks.im>
To: Jeff King <peff@peff.net>
Cc: git@vger.kernel.org
Subject: Re: [PATCH 2/2] submodule--helper: free URL when repository setup fails
Date: Wed, 2 Sep 2026 11:11:23 +0200	[thread overview]
Message-ID: <apfoO5br4MMZv7nR@pks.im> (raw)
In-Reply-To: <20260902055730.GB41747@coredump.intra.peff.net>

On Wed, Sep 02, 2026 at 01:57:30AM -0400, Jeff King wrote:
> If repo setup fails, we'll return an error without freeing the allocated
> url string, leaking the memory. The test suite does trigger this error,
> but never with the leak. We only allocate a url if submodule_from_path()
> returned something, but our tests use other situations, like totally
> nonexistent submodules.
> 
> We can cover this case by asking about a submodule that exists but which
> has not been initialized. The new test fails with SANITIZE=leak.
> 
> The smallest fix would just be a call to free(url), but I think it's a
> little nicer to set up a dedicated out-path for cleanup here. The
> previous commit made it safe to call repo_clear() even if
> repo_submodule_init() fails.

Agreed.

> Signed-off-by: Jeff King <peff@peff.net>
> ---
>  builtin/submodule--helper.c             | 10 +++++++---
>  t/t7426-submodule-get-default-remote.sh | 17 +++++++++++++++++
>  2 files changed, 24 insertions(+), 3 deletions(-)
> 
> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
> index e7cd3225fa..469e3dbcc9 100644
> --- a/builtin/submodule--helper.c
> +++ b/builtin/submodule--helper.c
> @@ -80,6 +80,7 @@ static int get_default_remote_submodule(const char *module_path, char **default_
>  	struct repository subrepo;
>  	const char *remote_name = NULL;
>  	char *url = NULL;
> +	int ret = 0;
>  
>  	sub = submodule_from_path(the_repository, null_oid(the_hash_algo), module_path);
>  	if (sub && sub->url) {

Nit, feel free to ignore: do we want to keep the value uninitialized
and...

> @@ -96,9 +97,11 @@ static int get_default_remote_submodule(const char *module_path, char **default_
>  	}
>  
>  	if (repo_submodule_init(&subrepo, the_repository, module_path,
> -				null_oid(the_hash_algo)) < 0)
> -		return die_message(_("could not get a repository handle for submodule '%s'"),
> +				null_oid(the_hash_algo)) < 0) {
> +		ret = die_message(_("could not get a repository handle for submodule '%s'"),
>  				   module_path);
> +		goto out;
> +	}
>  
>  	/* Look up by URL first */
>  	if (url)
> @@ -108,10 +111,11 @@ static int get_default_remote_submodule(const char *module_path, char **default_
>  
>  	*default_remote = xstrdup(remote_name);
>  

... set it to 0 here? Many compilers would warn in case the value was
uninitialized, which ensures that the return value is being explicitly
set before every `goto out`.

> +out:
>  	repo_clear(&subrepo);
>  	free(url);
>  
> -	return 0;
> +	return ret;
>  }
>  
>  static int module_get_default_remote(int argc, const char **argv, const char *prefix,
> diff --git a/t/t7426-submodule-get-default-remote.sh b/t/t7426-submodule-get-default-remote.sh
> index b842af9a2d..0379c9f044 100755
> --- a/t/t7426-submodule-get-default-remote.sh
> +++ b/t/t7426-submodule-get-default-remote.sh
> @@ -60,6 +60,23 @@ test_expect_success 'get-default-remote fails with non-submodule path' '
>  	)
>  '
>  
> +test_expect_success 'get-default-remote fails with uninitialized submodule' '
> +	test_when_finished "
> +		git -C super config -f .gitmodules --remove-section submodule.uninitialized &&
> +		git -C super update-index --force-remove uninitialized
> +	" &&

I was about to say we could use `test_config` instead, but you're of
course not modifying the normal ".git/config" file but ".gitmodules".

> +	(
> +		cd super &&
> +		git config -f .gitmodules submodule.uninitialized.path uninitialized &&
> +		git config -f .gitmodules submodule.uninitialized.url ../sub &&
> +		head=$(git -C ../sub rev-parse HEAD) &&
> +		git update-index --add --cacheinfo 160000,$head,uninitialized &&
> +		test_must_fail git submodule--helper get-default-remote \
> +			uninitialized 2>err &&
> +		test_grep "could not get a repository handle" err
> +	)
> +'

Thanks!

Patrick

      reply	other threads:[~2026-09-02  9:11 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-02  5:51 [PATCH 0/2] fix a leak in submodule error path Jeff King
2026-09-02  5:55 ` [PATCH 1/2] repository: make repo_clear() idempotent Jeff King
2026-09-02  6:29   ` Jeff King
2026-09-02  6:49     ` Jeff King
2026-09-02  9:11       ` Patrick Steinhardt
2026-09-02 16:29         ` Junio C Hamano
2026-09-03  5:15           ` Patrick Steinhardt
2026-09-02  5:57 ` [PATCH 2/2] submodule--helper: free URL when repository setup fails Jeff King
2026-09-02  9:11   ` Patrick Steinhardt [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=apfoO5br4MMZv7nR@pks.im \
    --to=ps@pks.im \
    --cc=git@vger.kernel.org \
    --cc=peff@peff.net \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.