]> git.ipfire.org Git - thirdparty/git.git/commitdiff
builtin/worktree: fix leaking derived branch names
authorPatrick Steinhardt <ps@pks.im>
Thu, 1 Aug 2024 10:40:46 +0000 (12:40 +0200)
committerJunio C Hamano <gitster@pobox.com>
Thu, 1 Aug 2024 15:47:37 +0000 (08:47 -0700)
There are several heuristics that git-worktree(1) uses to derive the
name of the newly created branch when not given explicitly. These
heuristics all allocate a new string, but we only end up freeing that
string in a subset of cases.

Fix the remaining cases where we didn't yet free the derived branch
names. While at it, also free `opt_track`, which is being populated via
an `OPT_PASSTHRU()`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/worktree.c
t/t2400-worktree-add.sh
t/t9902-completion.sh

index 1d51e54fcdc189ef6457991f8f47016c7e56a9e0..cec3ada6b04851237f2ddd2ccc4749748d54f771 100644 (file)
@@ -769,7 +769,7 @@ static int add(int ac, const char **av, const char *prefix)
        char *branch_to_free = NULL;
        char *new_branch_to_free = NULL;
        const char *new_branch = NULL;
-       const char *opt_track = NULL;
+       char *opt_track = NULL;
        const char *lock_reason = NULL;
        int keep_locked = 0;
        int used_new_branch_options;
@@ -846,7 +846,7 @@ static int add(int ac, const char **av, const char *prefix)
        if (opts.orphan && !new_branch) {
                int n;
                const char *s = worktree_basename(path, &n);
-               new_branch = xstrndup(s, n);
+               new_branch = new_branch_to_free = xstrndup(s, n);
        } else if (opts.orphan) {
                ; /* no-op */
        } else if (opts.detach) {
@@ -875,7 +875,7 @@ static int add(int ac, const char **av, const char *prefix)
                        remote = unique_tracking_name(branch, &oid, NULL);
                        if (remote) {
                                new_branch = branch;
-                               branch = remote;
+                               branch = new_branch_to_free = remote;
                        }
                }
 
@@ -923,6 +923,7 @@ static int add(int ac, const char **av, const char *prefix)
 
        ret = add_worktree(path, branch, &opts);
        free(path);
+       free(opt_track);
        free(branch_to_free);
        free(new_branch_to_free);
        return ret;
index ba320dc4171aa7884591067c00853a955d84f4e8..cfc4aeb1798c6d023909cec771e5b74e983af5ea 100755 (executable)
@@ -6,6 +6,7 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
 TEST_CREATE_REPO_NO_TEMPLATE=1
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 . "$TEST_DIRECTORY"/lib-rebase.sh
index 932d5ad75916980ad9fbbe62906ce540f99603d4..cc6aa9f0cd36e3c39fa3ba93a450407fb89ce658 100755 (executable)
@@ -16,6 +16,7 @@ test_untraceable=UnfortunatelyYes
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./lib-bash.sh
 
 complete ()