Skip to content

Commit fdf972a

Browse files
pks-tgitster
authored andcommitted
builtin/revert: fix leaking gpg_sign and strategy config
We leak the config values when `gpg_sign` or `strategy` options are being overridden via the command line. To fix this we need to free the old value, which requires us to figure out whether the value was changed via an option in the first place. The easy way to do this, which is to initialize local variables with `NULL`, doesn't work because we cannot tell the case where the user has passed e.g. `--no-gpg-sign`. Instead, we use a sentinel value for both values that we can compare against to check whether the user has passed the option. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 58888c0 commit fdf972a

File tree

2 files changed

+14
-4
lines changed

2 files changed

+14
-4
lines changed

builtin/revert.c

+13-4
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ static int run_sequencer(int argc, const char **argv, const char *prefix,
110110
const char * const * usage_str = revert_or_cherry_pick_usage(opts);
111111
const char *me = action_name(opts);
112112
const char *cleanup_arg = NULL;
113+
const char sentinel_value;
114+
const char *strategy = &sentinel_value;
115+
const char *gpg_sign = &sentinel_value;
113116
enum empty_action empty_opt = EMPTY_COMMIT_UNSPECIFIED;
114117
int cmd = 0;
115118
struct option base_options[] = {
@@ -125,10 +128,10 @@ static int run_sequencer(int argc, const char **argv, const char *prefix,
125128
OPT_CALLBACK('m', "mainline", opts, N_("parent-number"),
126129
N_("select mainline parent"), option_parse_m),
127130
OPT_RERERE_AUTOUPDATE(&opts->allow_rerere_auto),
128-
OPT_STRING(0, "strategy", &opts->strategy, N_("strategy"), N_("merge strategy")),
131+
OPT_STRING(0, "strategy", &strategy, N_("strategy"), N_("merge strategy")),
129132
OPT_STRVEC('X', "strategy-option", &opts->xopts, N_("option"),
130133
N_("option for merge strategy")),
131-
{ OPTION_STRING, 'S', "gpg-sign", &opts->gpg_sign, N_("key-id"),
134+
{ OPTION_STRING, 'S', "gpg-sign", &gpg_sign, N_("key-id"),
132135
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
133136
OPT_END()
134137
};
@@ -240,8 +243,14 @@ static int run_sequencer(int argc, const char **argv, const char *prefix,
240243
usage_with_options(usage_str, options);
241244

242245
/* These option values will be free()d */
243-
opts->gpg_sign = xstrdup_or_null(opts->gpg_sign);
244-
opts->strategy = xstrdup_or_null(opts->strategy);
246+
if (gpg_sign != &sentinel_value) {
247+
free(opts->gpg_sign);
248+
opts->gpg_sign = xstrdup_or_null(gpg_sign);
249+
}
250+
if (strategy != &sentinel_value) {
251+
free(opts->strategy);
252+
opts->strategy = xstrdup_or_null(strategy);
253+
}
245254
if (!opts->strategy && getenv("GIT_TEST_MERGE_ALGORITHM"))
246255
opts->strategy = xstrdup(getenv("GIT_TEST_MERGE_ALGORITHM"));
247256
free(options);

t/t3514-cherry-pick-revert-gpg.sh

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
test_description='test {cherry-pick,revert} --[no-]gpg-sign'
77

8+
TEST_PASSES_SANITIZE_LEAK=true
89
. ./test-lib.sh
910
. "$TEST_DIRECTORY/lib-gpg.sh"
1011

0 commit comments

Comments
 (0)