git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Rubén Justo" <rjusto@gmail.com>
To: Patrick Steinhardt <ps@pks.im>, git@vger.kernel.org
Subject: Re: [PATCH 10/26] git: refactor alias handling to use a `struct strvec`
Date: Sun, 10 Nov 2024 22:41:14 +0100	[thread overview]
Message-ID: <8b9c998b-9098-47d7-af49-ecea51d5278f@gmail.com> (raw)
In-Reply-To: <93aed59eaf67739e25dee4bd6cc0a3f2a527f345.1730901926.git.ps@pks.im>

On Wed, Nov 06, 2024 at 04:10:47PM +0100, Patrick Steinhardt wrote:
> In `handle_alias()` we use both `argcp` and `argv` as in-out parameters.
> Callers mostly pass through the static array from `main()`, but once we
> handle an alias we replace it with an allocated array that may contain
> some allocated strings. Callers do not handle this scenario at all and
> thus leak memory.
> 
> We could in theory handle the lifetime of `argv` in a hacky fashion by
> letting callers free it in case they see that an alias was handled. But
> while that would likely work, we still wouldn't be able to easily handle
> the lifetime of strings referenced by `argv`.
> 
> Refactor the code to instead use a `struct strvec`, which effectively
> removes the need for us to manually track lifetimes.
> 
> Signed-off-by: Patrick Steinhardt <ps@pks.im>
> ---
>  git.c            | 58 ++++++++++++++++++++++++++----------------------
>  t/t0014-alias.sh |  1 +
>  2 files changed, 33 insertions(+), 26 deletions(-)
> 
> diff --git a/git.c b/git.c
> index c2c1b8e22c2..88356afe5fb 100644
> --- a/git.c
> +++ b/git.c
> @@ -362,7 +362,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
>  	return (*argv) - orig_argv;
>  }
>  
> -static int handle_alias(int *argcp, const char ***argv)
> +static int handle_alias(struct strvec *args)
>  {
>  	int envchanged = 0, ret = 0, saved_errno = errno;
>  	int count, option_count;
> @@ -370,10 +370,10 @@ static int handle_alias(int *argcp, const char ***argv)
>  	const char *alias_command;
>  	char *alias_string;
>  
> -	alias_command = (*argv)[0];
> +	alias_command = args->v[0];
>  	alias_string = alias_lookup(alias_command);
>  	if (alias_string) {
> -		if (*argcp > 1 && !strcmp((*argv)[1], "-h"))
> +		if (args->nr > 1 && !strcmp(args->v[1], "-h"))
>  			fprintf_ln(stderr, _("'%s' is aliased to '%s'"),
>  				   alias_command, alias_string);
>  		if (alias_string[0] == '!') {
> @@ -390,7 +390,7 @@ static int handle_alias(int *argcp, const char ***argv)
>  			child.wait_after_clean = 1;
>  			child.trace2_child_class = "shell_alias";
>  			strvec_push(&child.args, alias_string + 1);
> -			strvec_pushv(&child.args, (*argv) + 1);
> +			strvec_pushv(&child.args, args->v + 1);
>  
>  			trace2_cmd_alias(alias_command, child.args.v);
>  			trace2_cmd_name("_run_shell_alias_");
> @@ -423,15 +423,13 @@ static int handle_alias(int *argcp, const char ***argv)
>  		trace_argv_printf(new_argv,
>  				  "trace: alias expansion: %s =>",
>  				  alias_command);
> -
> -		REALLOC_ARRAY(new_argv, count + *argcp);
> -		/* insert after command name */
> -		COPY_ARRAY(new_argv + count, *argv + 1, *argcp);
> -
>  		trace2_cmd_alias(alias_command, new_argv);
>  
> -		*argv = new_argv;
> -		*argcp += count - 1;
> +		/* Replace the alias with the new arguments. */
> +		strvec_splice(args, 0, 1, new_argv, count);

So, we take advantage here of the `replacement_len` argument for
`strvec_splice()`.  OK. 

> +
> +		free(alias_string);
> +		free(new_argv);
>  
>  		ret = 1;
>  	}
> @@ -800,10 +798,10 @@ static void execv_dashed_external(const char **argv)
>  		exit(128);
>  }
>  
> -static int run_argv(int *argcp, const char ***argv)
> +static int run_argv(struct strvec *args)
>  {
>  	int done_alias = 0;
> -	struct string_list cmd_list = STRING_LIST_INIT_NODUP;
> +	struct string_list cmd_list = STRING_LIST_INIT_DUP;
>  	struct string_list_item *seen;
>  
>  	while (1) {
> @@ -817,8 +815,8 @@ static int run_argv(int *argcp, const char ***argv)
>  		 * process.
>  		 */
>  		if (!done_alias)
> -			handle_builtin(*argcp, *argv);
> -		else if (get_builtin(**argv)) {
> +			handle_builtin(args->nr, args->v);
> +		else if (get_builtin(args->v[0])) {
>  			struct child_process cmd = CHILD_PROCESS_INIT;
>  			int i;
>  
> @@ -834,8 +832,8 @@ static int run_argv(int *argcp, const char ***argv)
>  			commit_pager_choice();
>  
>  			strvec_push(&cmd.args, "git");
> -			for (i = 0; i < *argcp; i++)
> -				strvec_push(&cmd.args, (*argv)[i]);
> +			for (i = 0; i < args->nr; i++)
> +				strvec_push(&cmd.args, args->v[i]);
>  
>  			trace_argv_printf(cmd.args.v, "trace: exec:");
>  
> @@ -850,13 +848,13 @@ static int run_argv(int *argcp, const char ***argv)
>  			i = run_command(&cmd);
>  			if (i >= 0 || errno != ENOENT)
>  				exit(i);
> -			die("could not execute builtin %s", **argv);
> +			die("could not execute builtin %s", args->v[0]);
>  		}
>  
>  		/* .. then try the external ones */
> -		execv_dashed_external(*argv);
> +		execv_dashed_external(args->v);
>  
> -		seen = unsorted_string_list_lookup(&cmd_list, *argv[0]);
> +		seen = unsorted_string_list_lookup(&cmd_list, args->v[0]);
>  		if (seen) {
>  			int i;
>  			struct strbuf sb = STRBUF_INIT;
> @@ -873,14 +871,14 @@ static int run_argv(int *argcp, const char ***argv)
>  			      " not terminate:%s"), cmd_list.items[0].string, sb.buf);
>  		}
>  
> -		string_list_append(&cmd_list, *argv[0]);
> +		string_list_append(&cmd_list, args->v[0]);
>  
>  		/*
>  		 * It could be an alias -- this works around the insanity
>  		 * of overriding "git log" with "git show" by having
>  		 * alias.log = show
>  		 */
> -		if (!handle_alias(argcp, argv))
> +		if (!handle_alias(args))
>  			break;
>  		done_alias = 1;
>  	}
> @@ -892,6 +890,7 @@ static int run_argv(int *argcp, const char ***argv)
>  
>  int cmd_main(int argc, const char **argv)
>  {
> +	struct strvec args = STRVEC_INIT;
>  	const char *cmd;
>  	int done_help = 0;
>  
> @@ -951,25 +950,32 @@ int cmd_main(int argc, const char **argv)
>  	 */
>  	setup_path();
>  
> +	for (size_t i = 0; i < argc; i++)
> +		strvec_push(&args, argv[i]);
> +
>  	while (1) {
> -		int was_alias = run_argv(&argc, &argv);
> +		int was_alias = run_argv(&args);
>  		if (errno != ENOENT)
>  			break;
>  		if (was_alias) {
>  			fprintf(stderr, _("expansion of alias '%s' failed; "
>  					  "'%s' is not a git command\n"),
> -				cmd, argv[0]);
> +				cmd, args.v[0]);
> +			strvec_clear(&args);
>  			exit(1);
>  		}
>  		if (!done_help) {
> -			cmd = argv[0] = help_unknown_cmd(cmd);
> +			strvec_replace(&args, 0, help_unknown_cmd(cmd));
> +			cmd = args.v[0];
>  			done_help = 1;
> -		} else
> +		} else {
>  			break;
> +		}
>  	}
>  
>  	fprintf(stderr, _("failed to run command '%s': %s\n"),
>  		cmd, strerror(errno));
> +	strvec_clear(&args);
>  
>  	return 1;
>  }
> diff --git a/t/t0014-alias.sh b/t/t0014-alias.sh
> index 854d59ec58c..2a6f39ad9c8 100755
> --- a/t/t0014-alias.sh
> +++ b/t/t0014-alias.sh
> @@ -2,6 +2,7 @@
>  
>  test_description='git command aliasing'
>  
> +TEST_PASSES_SANITIZE_LEAK=true
>  . ./test-lib.sh
>  
>  test_expect_success 'nested aliases - internal execution' '
> -- 
> 2.47.0.229.g8f8d6eee53.dirty
> 

  reply	other threads:[~2024-11-10 21:41 UTC|newest]

Thread overview: 117+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-06 15:10 [PATCH 00/26] Memory leak fixes (pt.10, final) Patrick Steinhardt
2024-11-06 15:10 ` [PATCH 01/26] builtin/blame: fix leaking blame entries with `--incremental` Patrick Steinhardt
2024-11-06 15:10 ` [PATCH 02/26] bisect: fix leaking good/bad terms when reading multipe times Patrick Steinhardt
2024-11-06 15:10 ` [PATCH 03/26] bisect: fix leaking string in `handle_bad_merge_base()` Patrick Steinhardt
2024-11-06 15:10 ` [PATCH 04/26] bisect: fix leaking `current_bad_oid` Patrick Steinhardt
2024-11-06 15:10 ` [PATCH 05/26] bisect: fix multiple leaks in `bisect_next_all()` Patrick Steinhardt
2024-11-06 15:10 ` [PATCH 06/26] bisect: fix leaking commit list items in `check_merge_base()` Patrick Steinhardt
2024-11-06 15:10 ` [PATCH 07/26] bisect: fix various cases where we leak commit list items Patrick Steinhardt
2024-11-06 15:10 ` [PATCH 08/26] line-log: fix leak when rewriting commit parents Patrick Steinhardt
2024-11-06 15:10 ` [PATCH 09/26] strvec: introduce new `strvec_splice()` function Patrick Steinhardt
2024-11-10 21:39   ` Rubén Justo
2024-11-11  9:09     ` Patrick Steinhardt
2024-11-06 15:10 ` [PATCH 10/26] git: refactor alias handling to use a `struct strvec` Patrick Steinhardt
2024-11-10 21:41   ` Rubén Justo [this message]
2024-11-06 15:10 ` [PATCH 11/26] git: refactor builtin " Patrick Steinhardt
2024-11-06 15:10 ` [PATCH 12/26] split-index: fix memory leak in `move_cache_to_base_index()` Patrick Steinhardt
2024-11-10 21:45   ` Rubén Justo
2024-11-06 15:10 ` [PATCH 13/26] builtin/sparse-checkout: fix leaking sanitized patterns Patrick Steinhardt
2024-11-06 15:11 ` [PATCH 14/26] help: refactor to not use globals for reading config Patrick Steinhardt
2024-11-06 15:11 ` [PATCH 15/26] help: fix leaking `struct cmdnames` Patrick Steinhardt
2024-11-10 21:46   ` Rubén Justo
2024-11-11  9:09     ` Patrick Steinhardt
2024-11-06 15:11 ` [PATCH 16/26] help: fix leaking return value from `help_unknown_cmd()` Patrick Steinhardt
2024-11-06 15:11 ` [PATCH 17/26] builtin/help: fix leaks in `check_git_cmd()` Patrick Steinhardt
2024-11-06 15:11 ` [PATCH 18/26] builtin/init-db: fix leaking directory paths Patrick Steinhardt
2024-11-10 21:47   ` Rubén Justo
2024-11-06 15:11 ` [PATCH 19/26] builtin/branch: fix leaking sorting options Patrick Steinhardt
2024-11-10 21:47   ` Rubén Justo
2024-11-06 15:11 ` [PATCH 20/26] t/helper: fix leaking commit graph in "read-graph" subcommand Patrick Steinhardt
2024-11-06 15:11 ` [PATCH 21/26] git-compat-util: drop `UNLEAK()` annotation Patrick Steinhardt
2024-11-10 21:47   ` Rubén Justo
2024-11-11  9:09     ` Patrick Steinhardt
2024-11-06 15:11 ` [PATCH 22/26] t5601: work around leak sanitizer issue Patrick Steinhardt
2024-11-06 15:11 ` [PATCH 23/26] t: mark some tests as leak free Patrick Steinhardt
2024-11-06 15:11 ` [PATCH 24/26] t: remove unneeded !SANITIZE_LEAK prerequisites Patrick Steinhardt
2024-11-06 15:11 ` [PATCH 25/26] test-lib: unconditionally enable leak checking Patrick Steinhardt
2024-11-06 15:11 ` [PATCH 26/26] t: remove TEST_PASSES_SANITIZE_LEAK annotations Patrick Steinhardt
2024-11-10 21:48 ` [PATCH 00/26] Memory leak fixes (pt.10, final) Rubén Justo
2024-11-11  9:09   ` Patrick Steinhardt
2024-11-11 10:38 ` [PATCH v2 00/27] " Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 01/27] builtin/blame: fix leaking blame entries with `--incremental` Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 02/27] bisect: fix leaking good/bad terms when reading multipe times Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 03/27] bisect: fix leaking string in `handle_bad_merge_base()` Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 04/27] bisect: fix leaking `current_bad_oid` Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 05/27] bisect: fix multiple leaks in `bisect_next_all()` Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 06/27] bisect: fix leaking commit list items in `check_merge_base()` Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 07/27] bisect: fix various cases where we leak commit list items Patrick Steinhardt
2024-11-20 10:32     ` Toon Claes
2024-11-20 12:41       ` Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 08/27] line-log: fix leak when rewriting commit parents Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 09/27] strvec: introduce new `strvec_splice()` function Patrick Steinhardt
2024-11-20  8:37     ` Toon Claes
2024-11-20 12:41       ` Patrick Steinhardt
2024-11-20 23:13         ` Junio C Hamano
2024-11-21  8:11           ` Jeff King
2024-11-21  8:22             ` Jeff King
2024-11-21 10:23             ` Doxygen-styled comments [was: Re: [PATCH v2 09/27] strvec: introduce new `strvec_splice()` function] Toon Claes
2024-11-21 10:32               ` Jeff King
2024-11-11 10:38   ` [PATCH v2 10/27] git: refactor alias handling to use a `struct strvec` Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 11/27] git: refactor builtin " Patrick Steinhardt
2024-11-20 10:38     ` Toon Claes
2024-11-11 10:38   ` [PATCH v2 12/27] split-index: fix memory leak in `move_cache_to_base_index()` Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 13/27] builtin/sparse-checkout: fix leaking sanitized patterns Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 14/27] help: refactor to not use globals for reading config Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 15/27] help: fix leaking `struct cmdnames` Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 16/27] help: fix leaking return value from `help_unknown_cmd()` Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 17/27] builtin/help: fix leaks in `check_git_cmd()` Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 18/27] builtin/init-db: fix leaking directory paths Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 19/27] builtin/branch: fix leaking sorting options Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 20/27] t/helper: fix leaking commit graph in "read-graph" subcommand Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 21/27] global: drop `UNLEAK()` annotation Patrick Steinhardt
2024-11-12  8:26     ` Jeff King
2024-11-12  8:53       ` Patrick Steinhardt
2024-11-12  9:03         ` Jeff King
2024-11-11 10:38   ` [PATCH v2 22/27] git-compat-util: drop now-unused `UNLEAK()` macro Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 23/27] t5601: work around leak sanitizer issue Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 24/27] t: mark some tests as leak free Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 25/27] t: remove unneeded !SANITIZE_LEAK prerequisites Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 26/27] test-lib: unconditionally enable leak checking Patrick Steinhardt
2024-11-11 10:38   ` [PATCH v2 27/27] t: remove TEST_PASSES_SANITIZE_LEAK annotations Patrick Steinhardt
2024-11-20 10:40     ` Toon Claes
2024-11-20 12:41       ` Patrick Steinhardt
2024-11-11 23:33   ` [PATCH v2 00/27] Memory leak fixes (pt.10, final) Rubén Justo
2024-11-12  8:06     ` Rubén Justo
2024-11-20 13:39 ` [PATCH v3 " Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 01/27] builtin/blame: fix leaking blame entries with `--incremental` Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 02/27] bisect: fix leaking good/bad terms when reading multipe times Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 03/27] bisect: fix leaking string in `handle_bad_merge_base()` Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 04/27] bisect: fix leaking `current_bad_oid` Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 05/27] bisect: fix multiple leaks in `bisect_next_all()` Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 06/27] bisect: fix leaking commit list items in `check_merge_base()` Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 07/27] bisect: fix various cases where we leak commit list items Patrick Steinhardt
2024-11-25 11:27     ` Jeff King
2024-11-25 12:38       ` Patrick Steinhardt
2024-11-25 13:17         ` Jeff King
2024-11-25 14:08           ` Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 08/27] line-log: fix leak when rewriting commit parents Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 09/27] strvec: introduce new `strvec_splice()` function Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 10/27] git: refactor alias handling to use a `struct strvec` Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 11/27] git: refactor builtin " Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 12/27] split-index: fix memory leak in `move_cache_to_base_index()` Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 13/27] builtin/sparse-checkout: fix leaking sanitized patterns Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 14/27] help: refactor to not use globals for reading config Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 15/27] help: fix leaking `struct cmdnames` Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 16/27] help: fix leaking return value from `help_unknown_cmd()` Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 17/27] builtin/help: fix leaks in `check_git_cmd()` Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 18/27] builtin/init-db: fix leaking directory paths Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 19/27] builtin/branch: fix leaking sorting options Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 20/27] t/helper: fix leaking commit graph in "read-graph" subcommand Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 21/27] global: drop `UNLEAK()` annotation Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 22/27] git-compat-util: drop now-unused `UNLEAK()` macro Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 23/27] t5601: work around leak sanitizer issue Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 24/27] t: mark some tests as leak free Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 25/27] t: remove unneeded !SANITIZE_LEAK prerequisites Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 26/27] test-lib: unconditionally enable leak checking Patrick Steinhardt
2024-11-20 13:39   ` [PATCH v3 27/27] t: remove TEST_PASSES_SANITIZE_LEAK annotations Patrick Steinhardt
2024-11-21 10:32   ` [PATCH v3 00/27] Memory leak fixes (pt.10, final) Toon Claes

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=8b9c998b-9098-47d7-af49-ecea51d5278f@gmail.com \
    --to=rjusto@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=ps@pks.im \
    /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).