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
@@ -2627,13 +2627,12 @@ int get_superproject_working_tree(struct strbuf *buf)
2627 * We might have a superproject, but it is harder
2628 * to determine.
2629 */
2630 - return 0;
2630 + goto out;
2631
2632 if (!strbuf_realpath(&one_up, "../", 0))
2633 - return 0;
2633 + goto out;
2634
2635 subpath = relative_path(cwd, one_up.buf, &sb);
2636 - strbuf_release(&one_up);
2636
2637 prepare_submodule_repo_env(&cp.env);
2638 strvec_pop(&cp.env);
@@ -2678,20 +2677,22 @@ int get_superproject_working_tree(struct strbuf *buf)
2677 ret = 1;
2678 free(super_wt);
2679 }
2681 - free(cwd);
2682 - strbuf_release(&sb);
2680
2681 code = finish_command(&cp);
2682
2683 if (code == 128)
2684 /* '../' is not a git repository */
2688 - return 0;
2689 - if (code == 0 && len == 0)
2685 + ret = 0;
2686 + else if (code == 0 && len == 0)
2687 /* There is an unrelated git repository at '../' */
2691 - return 0;
2692 - if (code)
2688 + ret = 0;
2689 + else if (code)
2690 die(_("ls-tree returned unexpected return code %d"), code);
2691
2692 +out:
2693 + strbuf_release(&sb);
2694 + strbuf_release(&one_up);
2695 + free(cwd);
2696 return ret;
2697 }
2698