Skip to content

Commit 9ff2f06

Browse files
avargitster
authored andcommitted
sequencer API users: fix get_replay_opts() leaks
Make the replay_opts_release() function added in the preceding commit non-static, and use it for freeing the "struct replay_opts" constructed for "rebase" and "revert". To safely call our new replay_opts_release() we'll need to stop calling it in sequencer_remove_state(), and instead call it where we allocate the "struct replay_opts" itself. This is because in e.g. do_interactive_rebase() we construct a "struct replay_opts" with "get_replay_opts()", and then call "complete_action()". If we get far enough in that function without encountering errors we'll call "pick_commits()" which (indirectly) calls sequencer_remove_state() at the end. But if we encounter errors anywhere along the way we'd punt out early, and not free() the memory we allocated. Remembering whether we previously called sequencer_remove_state() would be a hassle. Using a FREE_AND_NULL() pattern would also work, as it would be safe to call replay_opts_release() repeatedly. But let's fix this properly instead, by having the owner of the data free() it. Signed-off-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 6a09c3a commit 9ff2f06

19 files changed

+23
-5
lines changed

builtin/rebase.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)
297297
}
298298

299299
cleanup:
300+
replay_opts_release(&replay);
300301
free(revisions);
301302
free(shortrevisions);
302303
todo_list_release(&todo_list);
@@ -338,6 +339,7 @@ static int run_sequencer_rebase(struct rebase_options *opts)
338339
struct replay_opts replay_opts = get_replay_opts(opts);
339340

340341
ret = sequencer_continue(the_repository, &replay_opts);
342+
replay_opts_release(&replay_opts);
341343
break;
342344
}
343345
case ACTION_EDIT_TODO:
@@ -553,6 +555,7 @@ static int finish_rebase(struct rebase_options *opts)
553555

554556
replay.action = REPLAY_INTERACTIVE_REBASE;
555557
ret = sequencer_remove_state(&replay);
558+
replay_opts_release(&replay);
556559
} else {
557560
strbuf_addstr(&dir, opts->state_dir);
558561
if (remove_dir_recursively(&dir, 0))
@@ -1324,6 +1327,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
13241327

13251328
replay.action = REPLAY_INTERACTIVE_REBASE;
13261329
ret = sequencer_remove_state(&replay);
1330+
replay_opts_release(&replay);
13271331
} else {
13281332
strbuf_reset(&buf);
13291333
strbuf_addstr(&buf, options.state_dir);

builtin/revert.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ int cmd_revert(int argc, const char **argv, const char *prefix)
251251
if (opts.revs)
252252
release_revisions(opts.revs);
253253
free(opts.revs);
254+
replay_opts_release(&opts);
254255
return res;
255256
}
256257

@@ -267,5 +268,6 @@ int cmd_cherry_pick(int argc, const char **argv, const char *prefix)
267268
free(opts.revs);
268269
if (res < 0)
269270
die(_("cherry-pick failed"));
271+
replay_opts_release(&opts);
270272
return res;
271273
}

sequencer.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ static const char *gpg_sign_opt_quoted(struct replay_opts *opts)
351351
return buf.buf;
352352
}
353353

354-
static void replay_opts_release(struct replay_opts *opts)
354+
void replay_opts_release(struct replay_opts *opts)
355355
{
356356
free(opts->gpg_sign);
357357
free(opts->reflog_action);
@@ -385,8 +385,6 @@ int sequencer_remove_state(struct replay_opts *opts)
385385
}
386386
}
387387

388-
replay_opts_release(opts);
389-
390388
strbuf_reset(&buf);
391389
strbuf_addstr(&buf, get_dir(opts));
392390
if (remove_dir_recursively(&buf, 0))

sequencer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ int sequencer_pick_revisions(struct repository *repo,
158158
int sequencer_continue(struct repository *repo, struct replay_opts *opts);
159159
int sequencer_rollback(struct repository *repo, struct replay_opts *opts);
160160
int sequencer_skip(struct repository *repo, struct replay_opts *opts);
161+
void replay_opts_release(struct replay_opts *opts);
161162
int sequencer_remove_state(struct replay_opts *opts);
162163

163164
#define TODO_LIST_KEEP_EMPTY (1U << 0)

t/t3405-rebase-malformed.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ test_description='rebase should handle arbitrary git message'
55
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
66
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
77

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

t/t3412-rebase-root.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Tests if git rebase --root --onto <newparent> can rebase the root commit.
77
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
88
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
99

10+
TEST_PASSES_SANITIZE_LEAK=true
1011
. ./test-lib.sh
1112

1213
log_with_names () {

t/t3419-rebase-patch-id.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ test_description='git rebase - test patch id computation'
55
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
66
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
77

8+
TEST_PASSES_SANITIZE_LEAK=true
89
. ./test-lib.sh
910

1011
scramble () {

t/t3423-rebase-reword.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
test_description='git rebase interactive with rewording'
44

5+
TEST_PASSES_SANITIZE_LEAK=true
56
. ./test-lib.sh
67

78
. "$TEST_DIRECTORY"/lib-rebase.sh

t/t3425-rebase-topology-merges.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#!/bin/sh
22

33
test_description='rebase topology tests with merges'
4+
5+
TEST_PASSES_SANITIZE_LEAK=true
46
. ./test-lib.sh
57
. "$TEST_DIRECTORY"/lib-rebase.sh
68

t/t3437-rebase-fixup-options.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ to the "fixup" command that works with "fixup!", "fixup -C" works with
1414
"amend!" upon --autosquash.
1515
'
1616

17+
TEST_PASSES_SANITIZE_LEAK=true
1718
. ./test-lib.sh
1819

1920
. "$TEST_DIRECTORY"/lib-rebase.sh

0 commit comments

Comments
 (0)