builtin/rebase: do not assign default backend to non-constant field

The `struct rebase_options::default_backend` field is a non-constant string, but is being assigned a constant via `REBASE_OPTIONS_INIT`. Fix this by using `xstrdup()` to assign the variable and introduce a new function `rebase_options_release()` that releases memory held by the structure, including the newly-allocated variable. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jun 7, 2024 at 08:39 UTC 25a47ffac0c50d3bae4058e6327c7bd799240df9
1 file changed +16 -9
builtin/rebase.c
+16 -9
@@ -135,7 +135,7 @@ struct rebase_options {
135 .type = REBASE_UNSPECIFIED, \
136 .empty = EMPTY_UNSPECIFIED, \
137 .keep_empty = 1, \
138 - .default_backend = "merge", \
138 + .default_backend = xstrdup("merge"), \
139 .flags = REBASE_NO_QUIET, \
140 .git_am_opts = STRVEC_INIT, \
141 .exec = STRING_LIST_INIT_NODUP, \
@@ -151,6 +151,19 @@ struct rebase_options {
151 .strategy_opts = STRING_LIST_INIT_NODUP,\
152 }
153
154 +static void rebase_options_release(struct rebase_options *opts)
155 +{
156 + free(opts->default_backend);
157 + free(opts->reflog_action);
158 + free(opts->head_name);
159 + strvec_clear(&opts->git_am_opts);
160 + free(opts->gpg_sign_opt);
161 + string_list_clear(&opts->exec, 0);
162 + free(opts->strategy);
163 + string_list_clear(&opts->strategy_opts, 0);
164 + strbuf_release(&opts->git_format_patch_opt);
165 +}
166 +
167 static struct replay_opts get_replay_opts(const struct rebase_options *opts)
168 {
169 struct replay_opts replay = REPLAY_OPTS_INIT;
@@ -796,6 +809,7 @@ static int rebase_config(const char *var, const char *value,
809 }
810
811 if (!strcmp(var, "rebase.backend")) {
812 + FREE_AND_NULL(opts->default_backend);
813 return git_config_string(&opts->default_backend, var, value);
814 }
815
@@ -1833,14 +1847,7 @@ run_rebase:
1847 cleanup:
1848 strbuf_release(&buf);
1849 strbuf_release(&revisions);
1836 - free(options.reflog_action);
1837 - free(options.head_name);
1838 - strvec_clear(&options.git_am_opts);
1839 - free(options.gpg_sign_opt);
1840 - string_list_clear(&options.exec, 0);
1841 - free(options.strategy);
1842 - string_list_clear(&options.strategy_opts, 0);
1843 - strbuf_release(&options.git_format_patch_opt);
1850 + rebase_options_release(&options);
1851 free(squash_onto_name);
1852 free(keep_base_onto_name);
1853 return !!ret;