am: don't pass strvec to apply_parse_options()

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> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Dec 13, 2022 at 07:47 UTC a658e881c138c8bc398d1d4b9b6db9e29b16673c
1 file changed +11 -1
builtin/am.c
+11 -1
@@ -1476,6 +1476,7 @@ static int run_apply(const struct am_state *state, const char *index_file)
1476 int res, opts_left;
1477 int force_apply = 0;
1478 int options = 0;
1479 + const char **apply_argv;
1480
1481 if (init_apply_state(&apply_state, the_repository, NULL))
1482 BUG("init_apply_state() failed");
@@ -1483,7 +1484,15 @@ static int run_apply(const struct am_state *state, const char *index_file)
1484 strvec_push(&apply_opts, "apply");
1485 strvec_pushv(&apply_opts, state->git_apply_opts.v);
1486
1486 - opts_left = apply_parse_options(apply_opts.nr, apply_opts.v,
1487 + /*
1488 + * Build a copy that apply_parse_options() can rearrange.
1489 + * apply_opts.v keeps referencing the allocated strings for
1490 + * strvec_clear() to release.
1491 + */
1492 + ALLOC_ARRAY(apply_argv, apply_opts.nr);
1493 + COPY_ARRAY(apply_argv, apply_opts.v, apply_opts.nr);
1494 +
1495 + opts_left = apply_parse_options(apply_opts.nr, apply_argv,
1496 &apply_state, &force_apply, &options,
1497 NULL);
1498
@@ -1513,6 +1522,7 @@ static int run_apply(const struct am_state *state, const char *index_file)
1522 strvec_clear(&apply_paths);
1523 strvec_clear(&apply_opts);
1524 clear_apply_state(&apply_state);
1525 + free(apply_argv);
1526
1527 if (res)
1528 return res;