diff mbox series

[11/23] builtin/stash: fix various trivial memory leaks

Message ID a4b3ca49c9724b79ca695d0db8e45be663a46434.1721995576.git.ps@pks.im (mailing list archive)
State Superseded
Headers show
Series Memory leak fixes (pt.3) | expand

Commit Message

Patrick Steinhardt July 26, 2024, 12:16 p.m. UTC
There are multiple trivial memory leaks in git-stash(1). Fix those.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 builtin/stash.c                    | 18 ++++++++++++++++--
 t/t2501-cwd-empty.sh               |  1 +
 t/t3903-stash.sh                   |  1 +
 t/t3904-stash-patch.sh             |  2 ++
 t/t3905-stash-include-untracked.sh |  1 +
 t/t7064-wtstatus-pv2.sh            |  1 +
 6 files changed, 22 insertions(+), 2 deletions(-)

Comments

Taylor Blau July 31, 2024, 4:40 p.m. UTC | #1
On Fri, Jul 26, 2024 at 02:16:12PM +0200, Patrick Steinhardt wrote:
> @@ -1892,5 +1895,16 @@ int cmd_stash(int argc, const char **argv, const char *prefix)
>  	/* Assume 'stash push' */
>  	strvec_push(&args, "push");
>  	strvec_pushv(&args, argv);
> -	return !!push_stash(args.nr, args.v, prefix, 1);
> +
> +	/*
> +	 * `push_stash()` ends up modifying the array, which causes memory
> +	 * leaks if we didn't copy the array here.
> +	 */
> +	DUP_ARRAY(args_copy, args.v, args.nr);
> +
> +	ret = !!push_stash(args.nr, args_copy, prefix, 1);
> +
> +	strvec_clear(&args);
> +	free(args_copy);
> +	return ret;
>  }

OK, so this is the same pattern as we saw in the third patch of this
series. I agree with Junio's comments in that sub-thread, but also that
they are out-of-scope for the present series ;-).

Looking good.

Thanks,
Taylor
diff mbox series

Patch

diff --git a/builtin/stash.c b/builtin/stash.c
index 46b981c4dd..7f2f989b69 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -1521,6 +1521,7 @@  static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
 	struct strbuf patch = STRBUF_INIT;
 	struct strbuf stash_msg_buf = STRBUF_INIT;
 	struct strbuf untracked_files = STRBUF_INIT;
+	struct strbuf out = STRBUF_INIT;
 
 	if (patch_mode && keep_index == -1)
 		keep_index = 1;
@@ -1626,7 +1627,6 @@  static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
 			struct child_process cp_add = CHILD_PROCESS_INIT;
 			struct child_process cp_diff = CHILD_PROCESS_INIT;
 			struct child_process cp_apply = CHILD_PROCESS_INIT;
-			struct strbuf out = STRBUF_INIT;
 
 			cp_add.git_cmd = 1;
 			strvec_push(&cp_add.args, "add");
@@ -1718,6 +1718,7 @@  static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
 
 done:
 	strbuf_release(&patch);
+	strbuf_release(&out);
 	free_stash_info(&info);
 	strbuf_release(&stash_msg_buf);
 	strbuf_release(&untracked_files);
@@ -1869,6 +1870,8 @@  int cmd_stash(int argc, const char **argv, const char *prefix)
 		OPT_SUBCOMMAND_F("save", &fn, save_stash, PARSE_OPT_NOCOMPLETE),
 		OPT_END()
 	};
+	const char **args_copy;
+	int ret;
 
 	git_config(git_stash_config, NULL);
 
@@ -1892,5 +1895,16 @@  int cmd_stash(int argc, const char **argv, const char *prefix)
 	/* Assume 'stash push' */
 	strvec_push(&args, "push");
 	strvec_pushv(&args, argv);
-	return !!push_stash(args.nr, args.v, prefix, 1);
+
+	/*
+	 * `push_stash()` ends up modifying the array, which causes memory
+	 * leaks if we didn't copy the array here.
+	 */
+	DUP_ARRAY(args_copy, args.v, args.nr);
+
+	ret = !!push_stash(args.nr, args_copy, prefix, 1);
+
+	strvec_clear(&args);
+	free(args_copy);
+	return ret;
 }
diff --git a/t/t2501-cwd-empty.sh b/t/t2501-cwd-empty.sh
index f6d8d7d03d..8af4e8cfe3 100755
--- a/t/t2501-cwd-empty.sh
+++ b/t/t2501-cwd-empty.sh
@@ -2,6 +2,7 @@ 
 
 test_description='Test handling of the current working directory becoming empty'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success setup '
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index a7f71f8126..e4c0937f61 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -8,6 +8,7 @@  test_description='Test git stash'
 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-unique-files.sh
 
diff --git a/t/t3904-stash-patch.sh b/t/t3904-stash-patch.sh
index 368fc2a6cc..aa5019fd6c 100755
--- a/t/t3904-stash-patch.sh
+++ b/t/t3904-stash-patch.sh
@@ -1,6 +1,8 @@ 
 #!/bin/sh
 
 test_description='stash -p'
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./lib-patch-mode.sh
 
 test_expect_success 'setup' '
diff --git a/t/t3905-stash-include-untracked.sh b/t/t3905-stash-include-untracked.sh
index 1289ae3e07..a1733f45c3 100755
--- a/t/t3905-stash-include-untracked.sh
+++ b/t/t3905-stash-include-untracked.sh
@@ -5,6 +5,7 @@ 
 
 test_description='Test git stash --include-untracked'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'stash save --include-untracked some dirty working directory' '
diff --git a/t/t7064-wtstatus-pv2.sh b/t/t7064-wtstatus-pv2.sh
index 11884d2fc3..06c1301222 100755
--- a/t/t7064-wtstatus-pv2.sh
+++ b/t/t7064-wtstatus-pv2.sh
@@ -4,6 +4,7 @@  test_description='git status --porcelain=v2
 
 This test exercises porcelain V2 output for git status.'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh