From: "René Scharfe" <l.s.r@web.de>
To: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Cc: Git List <git@vger.kernel.org>, Junio C Hamano <gitster@pobox.com>
Subject: Re: [PATCH] am: don't pass strvec to apply_parse_options()
Date: Tue, 13 Dec 2022 19:31:13 +0100 [thread overview]
Message-ID: <2d0d77a4-f6ac-1fa7-bddb-9083579d8dd7@web.de> (raw)
In-Reply-To: <221213.86mt7r4ru2.gmgdl@evledraar.gmail.com>
Am 13.12.22 um 09:37 schrieb Ævar Arnfjörð Bjarmason:
>
> On Tue, Dec 13 2022, René Scharfe wrote:
>
>> apply_parse_options() passes the array of argument strings to
>> parse_options(), which removes recognized options. The removed strings
>> are not freed, though.
>>
>> Make a copy of the strvec to pass to the function to retain the pointers
>> of its strings, so we release them all at the end.
>>
>> Signed-off-by: René Scharfe <l.s.r@web.de>
>> ---
>> builtin/am.c | 12 +++++++++++-
>> 1 file changed, 11 insertions(+), 1 deletion(-)
>>
>> diff --git a/builtin/am.c b/builtin/am.c
>> index 30c9b3a9cd..dddf1b9af0 100644
>> --- a/builtin/am.c
>> +++ b/builtin/am.c
>> @@ -1476,6 +1476,7 @@ static int run_apply(const struct am_state *state, const char *index_file)
>> int res, opts_left;
>> int force_apply = 0;
>> int options = 0;
>> + const char **apply_argv;
>>
>> if (init_apply_state(&apply_state, the_repository, NULL))
>> BUG("init_apply_state() failed");
>> @@ -1483,7 +1484,15 @@ static int run_apply(const struct am_state *state, const char *index_file)
>> strvec_push(&apply_opts, "apply");
>> strvec_pushv(&apply_opts, state->git_apply_opts.v);
>>
>> - opts_left = apply_parse_options(apply_opts.nr, apply_opts.v,
>> + /*
>> + * Build a copy that apply_parse_options() can rearrange.
>> + * apply_opts.v keeps referencing the allocated strings for
>> + * strvec_clear() to release.
>> + */
>> + ALLOC_ARRAY(apply_argv, apply_opts.nr);
>> + COPY_ARRAY(apply_argv, apply_opts.v, apply_opts.nr);
>> +
>> + opts_left = apply_parse_options(apply_opts.nr, apply_argv,
>> &apply_state, &force_apply, &options,
>> NULL);
>>
>> @@ -1513,6 +1522,7 @@ static int run_apply(const struct am_state *state, const char *index_file)
>> strvec_clear(&apply_paths);
>> strvec_clear(&apply_opts);
>> clear_apply_state(&apply_state);
>> + free(apply_argv);
>>
>> if (res)
>> return res;
>
> I don't mind this going in, but it really feels like a bit of a dirty
> hack.
>
> We have widespread leaks all over the place due to this
> idiom. I.e. parse_options() and a couple of other APIs expect that they
> can munge the "argv", which is fine if it arrives via main(), but not if
> we're editing our own strvecs.
Where? A quick "git grep 'parse_options.*nr'" turns up only this place
as one that passes a strvec to parse_options.
> I think less of a hack is to teach the eventual parse_options() that
> when it munges it it should free() it. I did that for the revisions API
> in f92dbdbc6a8 (revisions API: don't leak memory on argv elements that
> need free()-ing, 2022-08-02).
>
> What do you think?
Generating string lists and then parsing them is weird. When calls have
to cross a process boundary then we have no choice, but in-process we
shouldn't have to lower our request to an intermediate text format. git
am does it anyway because it writes its options to a file and reads them
back when it resumes with --continue, IIUC.
I hope that is and will be the only place that uses parse_options() with
a strvec -- and then we don't have to change that function.
If this pattern is used more widely then we could package the copying
done by this patch somehow, e.g. by adding a strvec_parse_options()
that wraps the real thing.
If we have to change parse_options() at all then I'd prefer it to not
free() anything (to keep it usable with main()'s parameters), but to
reorder in a non-destructive way. That would mean keeping the NULL
sentinel where it is, and making sure all callers use only the returned
argc to determine which arguments parse_options() didn't recognize.
René
next prev parent reply other threads:[~2022-12-13 18:31 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-13 6:47 [PATCH] am: don't pass strvec to apply_parse_options() René Scharfe
2022-12-13 8:37 ` Ævar Arnfjörð Bjarmason
2022-12-13 18:31 ` René Scharfe [this message]
2022-12-14 8:44 ` Ævar Arnfjörð Bjarmason
2022-12-15 9:11 ` [RFC PATCH 0/5] strvec: add a "nodup" mode, fix memory leaks Ævar Arnfjörð Bjarmason
2022-12-15 9:11 ` [RFC PATCH 1/5] builtin/annotate.c: simplify for strvec API Ævar Arnfjörð Bjarmason
2022-12-17 12:45 ` René Scharfe
2022-12-15 9:11 ` [RFC PATCH 2/5] various: add missing strvec_clear() Ævar Arnfjörð Bjarmason
2022-12-15 9:11 ` [RFC PATCH 3/5] strvec API: add a "STRVEC_INIT_NODUP" Ævar Arnfjörð Bjarmason
2022-12-17 12:45 ` René Scharfe
2022-12-15 9:11 ` [RFC PATCH 4/5] strvec API users: fix leaks by using "STRVEC_INIT_NODUP" Ævar Arnfjörð Bjarmason
2022-12-17 12:45 ` René Scharfe
2022-12-15 9:11 ` [RFC PATCH 5/5] strvec API users: fix more " Ævar Arnfjörð Bjarmason
2022-12-17 12:45 ` René Scharfe
2022-12-17 12:45 ` [RFC PATCH 0/5] strvec: add a "nodup" mode, fix memory leaks René Scharfe
2022-12-17 13:13 ` Jeff King
2022-12-19 9:20 ` Ævar Arnfjörð Bjarmason
2023-01-07 13:21 ` Jeff King
2022-12-17 12:46 ` [PATCH] am: don't pass strvec to apply_parse_options() René Scharfe
2022-12-17 13:24 ` Jeff King
2022-12-17 16:07 ` René Scharfe
2022-12-17 21:53 ` Jeff King
2022-12-18 2:42 ` Junio C Hamano
2022-12-20 1:29 ` Junio C Hamano
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=2d0d77a4-f6ac-1fa7-bddb-9083579d8dd7@web.de \
--to=l.s.r@web.de \
--cc=avarab@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.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).