]> git.ipfire.org Git - thirdparty/git.git/commitdiff
sequencer API users: fix get_replay_opts() leaks
authorÆvar Arnfjörð Bjarmason <avarab@gmail.com>
Mon, 6 Feb 2023 19:08:08 +0000 (20:08 +0100)
committerJunio C Hamano <gitster@pobox.com>
Tue, 7 Feb 2023 00:03:52 +0000 (16:03 -0800)
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 <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
19 files changed:
builtin/rebase.c
builtin/revert.c
sequencer.c
sequencer.h
t/t3405-rebase-malformed.sh
t/t3412-rebase-root.sh
t/t3419-rebase-patch-id.sh
t/t3423-rebase-reword.sh
t/t3425-rebase-topology-merges.sh
t/t3437-rebase-fixup-options.sh
t/t3438-rebase-broken-files.sh
t/t3501-revert-cherry-pick.sh
t/t3502-cherry-pick-merge.sh
t/t3503-cherry-pick-root.sh
t/t3506-cherry-pick-ff.sh
t/t3511-cherry-pick-x.sh
t/t7402-submodule-rebase.sh
t/t9106-git-svn-commit-diff-clobber.sh
t/t9164-git-svn-dcommit-concurrent.sh

index c97ce642cf3abb83e6cd30b0703cb4d41dea99fd..2ec3ae0b42eabdf9c85eb420a3af03d72923c935 100644 (file)
@@ -297,6 +297,7 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)
        }
 
 cleanup:
+       replay_opts_release(&replay);
        free(revisions);
        free(shortrevisions);
        todo_list_release(&todo_list);
@@ -338,6 +339,7 @@ static int run_sequencer_rebase(struct rebase_options *opts)
                struct replay_opts replay_opts = get_replay_opts(opts);
 
                ret = sequencer_continue(the_repository, &replay_opts);
+               replay_opts_release(&replay_opts);
                break;
        }
        case ACTION_EDIT_TODO:
@@ -553,6 +555,7 @@ static int finish_rebase(struct rebase_options *opts)
 
                replay.action = REPLAY_INTERACTIVE_REBASE;
                ret = sequencer_remove_state(&replay);
+               replay_opts_release(&replay);
        } else {
                strbuf_addstr(&dir, opts->state_dir);
                if (remove_dir_recursively(&dir, 0))
@@ -1324,6 +1327,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
 
                        replay.action = REPLAY_INTERACTIVE_REBASE;
                        ret = sequencer_remove_state(&replay);
+                       replay_opts_release(&replay);
                } else {
                        strbuf_reset(&buf);
                        strbuf_addstr(&buf, options.state_dir);
index f2d86d2a8f999bbad13f51319e1ba3c0e4561d53..1cab16bf3edc2a33fded1f5264920a3a3cb55928 100644 (file)
@@ -251,6 +251,7 @@ int cmd_revert(int argc, const char **argv, const char *prefix)
        if (opts.revs)
                release_revisions(opts.revs);
        free(opts.revs);
+       replay_opts_release(&opts);
        return res;
 }
 
@@ -267,5 +268,6 @@ int cmd_cherry_pick(int argc, const char **argv, const char *prefix)
        free(opts.revs);
        if (res < 0)
                die(_("cherry-pick failed"));
+       replay_opts_release(&opts);
        return res;
 }
index b6392b43204f5a777177cc650687b48488ae6d43..1547fb985979425d80e8d2331717cbdb7aff8015 100644 (file)
@@ -351,7 +351,7 @@ static const char *gpg_sign_opt_quoted(struct replay_opts *opts)
        return buf.buf;
 }
 
-static void replay_opts_release(struct replay_opts *opts)
+void replay_opts_release(struct replay_opts *opts)
 {
        free(opts->gpg_sign);
        free(opts->reflog_action);
@@ -385,8 +385,6 @@ int sequencer_remove_state(struct replay_opts *opts)
                }
        }
 
-       replay_opts_release(opts);
-
        strbuf_reset(&buf);
        strbuf_addstr(&buf, get_dir(opts));
        if (remove_dir_recursively(&buf, 0))
index 888c18aad7188e48985eb5c994b13853dc30c137..3bcdfa1b5865fc5209141870076b7325edfa36d4 100644 (file)
@@ -158,6 +158,7 @@ int sequencer_pick_revisions(struct repository *repo,
 int sequencer_continue(struct repository *repo, struct replay_opts *opts);
 int sequencer_rollback(struct repository *repo, struct replay_opts *opts);
 int sequencer_skip(struct repository *repo, struct replay_opts *opts);
+void replay_opts_release(struct replay_opts *opts);
 int sequencer_remove_state(struct replay_opts *opts);
 
 #define TODO_LIST_KEEP_EMPTY (1U << 0)
index 2524331861869d6b9ee9f80082c09d2ed089e8fe..8979bc340734f860f56c49a4380366dca1d46ee8 100755 (executable)
@@ -5,6 +5,7 @@ test_description='rebase should handle arbitrary git message'
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/lib-rebase.sh
 
index 58371d8a5477f47d53384a84ad0dae14457128d9..e75b3d0e07cb13b5d8b4fd3b83b07c35eeddce49 100755 (executable)
@@ -7,6 +7,7 @@ Tests if git rebase --root --onto <newparent> can rebase the root commit.
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 log_with_names () {
index 7181f176b8136504b4a9bc5e962cf358b00ffbba..6c61f240cf9874bbdb0190739b66a1c0ed99289f 100755 (executable)
@@ -5,6 +5,7 @@ test_description='git rebase - test patch id computation'
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 scramble () {
index 4859bb8f722314df2fdb67aa51a4419009ce22ec..2fab703d615485020f0692bdc2d39748ba0f72d4 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='git rebase interactive with rewording'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 . "$TEST_DIRECTORY"/lib-rebase.sh
index 63acc1ea4dab43e5fc1f9eb26b031f49e3d9a432..a16428bdf54ab9157dfefb7cc9797e4c5dd86e1e 100755 (executable)
@@ -1,6 +1,8 @@
 #!/bin/sh
 
 test_description='rebase topology tests with merges'
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/lib-rebase.sh
 
index c023fefd681ba62b8296925b2051cffe365e63ac..274699dadb891873cda74fe824bb011d59fc2d87 100755 (executable)
@@ -14,6 +14,7 @@ to the "fixup" command that works with "fixup!", "fixup -C" works with
 "amend!" upon --autosquash.
 '
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 . "$TEST_DIRECTORY"/lib-rebase.sh
index b92a3ce46b8cc044e44adfa9cc807c2d2ddb4af2..c614c4f2e4ba285ba7ffc6b7b4384b69f0b9a851 100755 (executable)
@@ -1,6 +1,8 @@
 #!/bin/sh
 
 test_description='rebase behavior when on-disk files are broken'
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'set up conflicting branches' '
index 1f4cfc37449186c52a36cbe19f2631df759643e3..2f3e3e2416921c28b27b75dc9f76c20b40401d4d 100755 (executable)
@@ -13,6 +13,7 @@ test_description='test cherry-pick and revert with renames
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success setup '
index 5495eacfec11a904ba24d69439cb1b98b5a353ec..1b2c0d6aca64e05a85ffd6568be17bb5897a297e 100755 (executable)
@@ -11,6 +11,7 @@ test_description='cherry picking and reverting a merge
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success setup '
index 95fe4feaeee98f6432b39ee3a4817f05da5d649b..76d393dc8a307ebef13dfab5e4eb3d88a7a7cd69 100755 (executable)
@@ -5,6 +5,7 @@ test_description='test cherry-picking (and reverting) a root commit'
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success setup '
index 7e11bd4a4c5c41c9e326244f598bdc9bb4e4e3ba..b71bad17b853c566caac5828c19453da9c862647 100755 (executable)
@@ -5,6 +5,7 @@ test_description='test cherry-picking with --ff option'
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success setup '
index 84a587daf3af0356244c58c6472e202875679200..dd5d92ef302124aeb9d6fe02642489875a9e1b22 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='Test cherry-pick -x and -s'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 pristine_detach () {
index ebeca12a71115f60d10fa3ffa4725b1c7080f6f0..b19792b326901bbb8c00c20f07dbb38b322a9e74 100755 (executable)
@@ -5,6 +5,7 @@
 
 test_description='Test rebasing, stashing, etc. with submodules'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success setup '
index 3cab0b9720a6544ade5caf91a3f678ad577cc3b0..bca496c40e0a22011465083d6b36aa32e48e86b5 100755 (executable)
@@ -3,7 +3,6 @@
 # Copyright (c) 2006 Eric Wong
 test_description='git svn commit-diff clobber'
 
-TEST_FAILS_SANITIZE_LEAK=true
 . ./lib-git-svn.sh
 
 test_expect_success 'initialize repo' '
index 1465156072e32a75fb759784e65f9f7e2ca4c84a..c8e6c0733f41cf90a41941a3ad3550efb7ea56f1 100755 (executable)
@@ -5,7 +5,6 @@
 
 test_description='concurrent git svn dcommit'
 
-TEST_FAILS_SANITIZE_LEAK=true
 . ./lib-git-svn.sh