]> git.ipfire.org Git - thirdparty/git.git/commitdiff
submodule: fix cwd leak in `get_superproject_working_tree()`
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Sun, 5 Jul 2026 08:24:24 +0000 (08:24 +0000)
committerJunio C Hamano <gitster@pobox.com>
Sun, 5 Jul 2026 16:12:10 +0000 (09:12 -0700)
`get_superproject_working_tree()` allocates cwd via `xgetcwd()` at the
top of the function, but two early-return paths (when not inside a work
tree, and when strbuf_realpath for "../" fails) return 0 without freeing
it.

Redirect these early returns through a cleanup label that frees cwd
before returning.

Pointed out by Coverity.

Assisted-by: Claude Opus 4.6
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
submodule.c

index fd91201a92d7b006d94155e85713644872af8eeb..92dfb0fc2d341f9aef2ce25aa0f45e2b0c2195dd 100644 (file)
@@ -2627,13 +2627,12 @@ int get_superproject_working_tree(struct strbuf *buf)
                 * We might have a superproject, but it is harder
                 * to determine.
                 */
-               return 0;
+               goto out;
 
        if (!strbuf_realpath(&one_up, "../", 0))
-               return 0;
+               goto out;
 
        subpath = relative_path(cwd, one_up.buf, &sb);
-       strbuf_release(&one_up);
 
        prepare_submodule_repo_env(&cp.env);
        strvec_pop(&cp.env);
@@ -2678,20 +2677,22 @@ int get_superproject_working_tree(struct strbuf *buf)
                ret = 1;
                free(super_wt);
        }
-       free(cwd);
-       strbuf_release(&sb);
 
        code = finish_command(&cp);
 
        if (code == 128)
                /* '../' is not a git repository */
-               return 0;
-       if (code == 0 && len == 0)
+               ret = 0;
+       else if (code == 0 && len == 0)
                /* There is an unrelated git repository at '../' */
-               return 0;
-       if (code)
+               ret = 0;
+       else if (code)
                die(_("ls-tree returned unexpected return code %d"), code);
 
+out:
+       strbuf_release(&sb);
+       strbuf_release(&one_up);
+       free(cwd);
        return ret;
 }