git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 14/24] builtin/show-branch: fix several memory leaks

From
Patrick Steinhardt <ps@pks.im>
Date
Aug 1, 2024, 10:40 UTC
Message-ID
<20a40e2fd49468f3c406a3124c06cd2b4a9f58eb.1722499961.git.ps@pks.im>
In-Reply-To
<cover.1722499961.git.ps@pks.im>
There are several memory leaks in git-show-branch(1). Fix them.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 builtin/show-branch.c  | 52 +++++++++++++++++++++++++++++-------------
 t/t3202-show-branch.sh |  1 +
 t/t6010-merge-base.sh  |  1 +
 3 files changed, 38 insertions(+), 16 deletions(-)
diff --git a/builtin/show-branch.c b/builtin/show-branch.c
index d72f4cb98d..7d797a880c 100644
--- a/builtin/show-branch.c
+++ b/builtin/show-branch.c
@@ -502,14 +502,14 @@ static int rev_is_head(const char *head, const char *name)
 	return !strcmp(head, name);
 }
 
-static int show_merge_base(struct commit_list *seen, int num_rev)
+static int show_merge_base(const struct commit_list *seen, int num_rev)
 {
 	int all_mask = ((1u << (REV_SHIFT + num_rev)) - 1);
 	int all_revs = all_mask & ~((1u << REV_SHIFT) - 1);
 	int exit_status = 1;
 
-	while (seen) {
-		struct commit *commit = pop_commit(&seen);
+	for (const struct commit_list *s = seen; s; s = s->next) {
+		struct commit *commit = s->item;
 		int flags = commit->object.flags & all_mask;
 		if (!(flags & UNINTERESTING) &&
 		    ((flags & all_revs) == all_revs)) {
@@ -635,7 +635,7 @@ static int parse_reflog_param(const struct option *opt, const char *arg,
 int cmd_show_branch(int ac, const char **av, const char *prefix)
 {
 	struct commit *rev[MAX_REVS], *commit;
-	char *reflog_msg[MAX_REVS];
+	char *reflog_msg[MAX_REVS] = {0};
 	struct commit_list *list = NULL, *seen = NULL;
 	unsigned int rev_mask[MAX_REVS];
 	int num_rev, i, extra = 0;
@@ -692,6 +692,8 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
 			    parse_reflog_param),
 		OPT_END()
 	};
+	const char **args_copy = NULL;
+	int ret;
 
 	init_commit_name_slab(&name_slab);
 
@@ -699,8 +701,9 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
 
 	/* If nothing is specified, try the default first */
 	if (ac == 1 && default_args.nr) {
+		DUP_ARRAY(args_copy, default_args.v, default_args.nr);
 		ac = default_args.nr;
-		av = default_args.v;
+		av = args_copy;
 	}
 
 	ac = parse_options(ac, av, prefix, builtin_show_branch_options,
@@ -780,7 +783,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
 		}
 
 		for (i = 0; i < reflog; i++) {
-			char *logmsg;
+			char *logmsg = NULL;
 			char *nth_desc;
 			const char *msg;
 			char *end;
@@ -790,6 +793,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
 			if (read_ref_at(get_main_ref_store(the_repository),
 					ref, flags, 0, base + i, &oid, &logmsg,
 					&timestamp, &tz, NULL)) {
+				free(logmsg);
 				reflog = i;
 				break;
 			}
@@ -842,7 +846,8 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
 
 	if (!ref_name_cnt) {
 		fprintf(stderr, "No revs to be shown.\n");
-		exit(0);
+		ret = 0;
+		goto out;
 	}
 
 	for (num_rev = 0; ref_name[num_rev]; num_rev++) {
@@ -879,11 +884,15 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
 
 	commit_list_sort_by_date(&seen);
 
-	if (merge_base)
-		return show_merge_base(seen, num_rev);
+	if (merge_base) {
+		ret = show_merge_base(seen, num_rev);
+		goto out;
+	}
 
-	if (independent)
-		return show_independent(rev, num_rev, rev_mask);
+	if (independent) {
+		ret = show_independent(rev, num_rev, rev_mask);
+		goto out;
+	}
 
 	/* Show list; --more=-1 means list-only */
 	if (1 < num_rev || extra < 0) {
@@ -919,8 +928,10 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
 			putchar('\n');
 		}
 	}
-	if (extra < 0)
-		exit(0);
+	if (extra < 0) {
+		ret = 0;
+		goto out;
+	}
 
 	/* Sort topologically */
 	sort_in_topological_order(&seen, sort_order);
@@ -932,8 +943,8 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
 	all_mask = ((1u << (REV_SHIFT + num_rev)) - 1);
 	all_revs = all_mask & ~((1u << REV_SHIFT) - 1);
 
-	while (seen) {
-		struct commit *commit = pop_commit(&seen);
+	for (struct commit_list *l = seen; l; l = l->next) {
+		struct commit *commit = l->item;
 		int this_flag = commit->object.flags;
 		int is_merge_point = ((this_flag & all_revs) == all_revs);
 
@@ -973,6 +984,15 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
 		if (shown_merge_point && --extra < 0)
 			break;
 	}
+
+	ret = 0;
+
+out:
+	for (size_t i = 0; i < ARRAY_SIZE(reflog_msg); i++)
+		free(reflog_msg[i]);
+	free_commit_list(seen);
+	free_commit_list(list);
+	free(args_copy);
 	free(head);
-	return 0;
+	return ret;
 }
diff --git a/t/t3202-show-branch.sh b/t/t3202-show-branch.sh
index a1139f79e2..3b6dad0c46 100755
--- a/t/t3202-show-branch.sh
+++ b/t/t3202-show-branch.sh
@@ -2,6 +2,7 @@
 
 test_description='test show-branch'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'error descriptions on empty repository' '
diff --git a/t/t6010-merge-base.sh b/t/t6010-merge-base.sh
index 44c726ea39..f96ea82e78 100755
--- a/t/t6010-merge-base.sh
+++ b/t/t6010-merge-base.sh
@@ -6,6 +6,7 @@
 test_description='Merge base and parent list computation.
 '
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 M=1130000000
-- 
2.46.0.dirty
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 60 of 72 in “Memory leak fixes (pt.3)”
  1. 00/23 Memory leak fixes (pt.3)Patrick Steinhardt, Jul 26, 2024
  2. 01/23 builtin/replay: plug leaking `advance_name` variablePatrick Steinhardt, Jul 26, 2024
  3. Taylor BlauJul 31, 2024
  4. 02/23 builtin/log: fix leaking branch name when creating cover lettersPatrick Steinhardt, Jul 26, 2024
  5. Karthik NayakJul 30, 2024
  6. Taylor BlauJul 31, 2024
  7. 03/23 builtin/describe: fix memory leak with `--contains=`Patrick Steinhardt, Jul 26, 2024
  8. Karthik NayakJul 30, 2024
  9. Junio C HamanoJul 30, 2024
  10. Patrick SteinhardtJul 31, 2024
  11. Junio C HamanoJul 31, 2024
  12. Taylor BlauJul 31, 2024
  13. 04/23 builtin/describe: fix leaking array when running diff-indexPatrick Steinhardt, Jul 26, 2024
  14. Karthik NayakJul 30, 2024
  15. 05/23 builtin/describe: fix trivial memory leak when describing blobPatrick Steinhardt, Jul 26, 2024
  16. 06/23 builtin/name-rev: fix various trivial memory leaksPatrick Steinhardt, Jul 26, 2024
  17. Junio C HamanoJul 30, 2024
  18. 07/23 builtin/submodule--helper: fix various trivial memory leaksPatrick Steinhardt, Jul 26, 2024
  19. Rubén JustoJul 31, 2024
  20. Patrick SteinhardtAug 1, 2024
  21. 08/23 builtin/ls-remote: fix leaking `pattern` stringsPatrick Steinhardt, Jul 26, 2024
  22. Taylor BlauJul 31, 2024
  23. Patrick SteinhardtAug 1, 2024
  24. 09/23 builtin/remote: fix leaking strings in `branch_list`Patrick Steinhardt, Jul 26, 2024
  25. Taylor BlauJul 31, 2024
  26. 10/23 builtin/remote: fix various trivial memory leaksPatrick Steinhardt, Jul 26, 2024
  27. 11/23 builtin/stash: fix various trivial memory leaksPatrick Steinhardt, Jul 26, 2024
  28. Taylor BlauJul 31, 2024
  29. 12/23 builtin/rev-parse: fix memory leak with `--parseopt`Patrick Steinhardt, Jul 26, 2024
  30. Karthik NayakJul 30, 2024
  31. 13/23 builtin/show-branch: fix several memory leaksPatrick Steinhardt, Jul 26, 2024
  32. 14/23 builtin/credential-store: fix leaking credentialPatrick Steinhardt, Jul 26, 2024
  33. 15/23 builtin/rerere: fix various trivial memory leaksPatrick Steinhardt, Jul 26, 2024
  34. 16/23 builtin/shortlog: fix various trivial memory leaksPatrick Steinhardt, Jul 26, 2024
  35. 17/23 builtin/worktree: fix leaking derived branch namesPatrick Steinhardt, Jul 26, 2024
  36. 18/23 builtin/credential-cache: fix trivial leaksPatrick Steinhardt, Jul 26, 2024
  37. 19/23 t/test-repository: fix leaking repositoryPatrick Steinhardt, Jul 26, 2024
  38. 20/23 object-name: fix leaking commit list itemsPatrick Steinhardt, Jul 26, 2024
  39. 21/23 entry: fix leaking pathnames during delayed checkoutPatrick Steinhardt, Jul 26, 2024
  40. 22/23 convert: fix leaking config stringsPatrick Steinhardt, Jul 26, 2024
  41. 23/23 commit-reach: fix trivial memory leak when computing reachabilityPatrick Steinhardt, Jul 26, 2024
  42. Karthik NayakJul 30, 2024
  43. Patrick SteinhardtJul 31, 2024
  44. Taylor BlauJul 31, 2024
  45. Patrick SteinhardtAug 1, 2024
  46. Taylor BlauAug 1, 2024
  47. 00/24 Memory leak fixes (pt.3)Patrick Steinhardt, Aug 1, 2024
  48. 01/24 builtin/replay: plug leaking `advance_name` variablePatrick Steinhardt, Aug 1, 2024
  49. 02/24 builtin/log: fix leaking branch name when creating cover lettersPatrick Steinhardt, Aug 1, 2024
  50. 03/24 builtin/describe: fix memory leak with `--contains=`Patrick Steinhardt, Aug 1, 2024
  51. 04/24 builtin/describe: fix leaking array when running diff-indexPatrick Steinhardt, Aug 1, 2024
  52. 05/24 builtin/describe: fix trivial memory leak when describing blobPatrick Steinhardt, Aug 1, 2024
  53. 06/24 builtin/name-rev: fix various trivial memory leaksPatrick Steinhardt, Aug 1, 2024
  54. 08/24 builtin/submodule--helper: fix leaking buffer in `is_tip_reachable`Patrick Steinhardt, Aug 1, 2024
  55. 09/24 builtin/ls-remote: fix leaking `pattern` stringsPatrick Steinhardt, Aug 1, 2024
  56. 10/24 builtin/remote: fix leaking strings in `branch_list`Patrick Steinhardt, Aug 1, 2024
  57. 11/24 builtin/remote: fix various trivial memory leaksPatrick Steinhardt, Aug 1, 2024
  58. 12/24 builtin/stash: fix various trivial memory leaksPatrick Steinhardt, Aug 1, 2024
  59. 13/24 builtin/rev-parse: fix memory leak with `--parseopt`Patrick Steinhardt, Aug 1, 2024
  60. 14/24 builtin/show-branch: fix several memory leaksPatrick Steinhardt, Aug 1, 2024
  61. 15/24 builtin/credential-store: fix leaking credentialPatrick Steinhardt, Aug 1, 2024
  62. 16/24 builtin/rerere: fix various trivial memory leaksPatrick Steinhardt, Aug 1, 2024
  63. 17/24 builtin/shortlog: fix various trivial memory leaksPatrick Steinhardt, Aug 1, 2024
  64. 18/24 builtin/worktree: fix leaking derived branch namesPatrick Steinhardt, Aug 1, 2024
  65. 19/24 builtin/credential-cache: fix trivial leaksPatrick Steinhardt, Aug 1, 2024
  66. 20/24 t/test-repository: fix leaking repositoryPatrick Steinhardt, Aug 1, 2024
  67. 21/24 object-name: fix leaking commit list itemsPatrick Steinhardt, Aug 1, 2024
  68. 22/24 entry: fix leaking pathnames during delayed checkoutPatrick Steinhardt, Aug 1, 2024
  69. 23/24 convert: fix leaking config stringsPatrick Steinhardt, Aug 1, 2024
  70. 24/24 commit-reach: fix trivial memory leak when computing reachabilityPatrick Steinhardt, Aug 1, 2024
  71. 07/24 builtin/submodule--helper: fix leaking clone depth parameterPatrick Steinhardt, Aug 1, 2024
  72. Taylor BlauAug 1, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.