submodule: fix cwd leak in `get_superproject_working_tree()`
`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>
Johannes Schindelin committed
Jul 5, 2026 at 08:24 UTC
add15d11ac1d882fe1a36e3f7a936fb92943ecca
1 file changed
+10
-9
submodule.c
+10
-9
index fd91201a92..92dfb0fc2d 100644
--- a/submodule.c
+++ b/submodule.c
@@ -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;
}