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
>
next prev parent 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).