{"thread":{"id":"59011","subject":"[PATCH 00/20] leak fixes: various simple leak fixes","startedAt":"2022-12-28T18:00:31Z","lastAt":"2023-02-07T03:40:25Z","messageCount":193,"participants":["Ævar Arnfjörð Bjarmason","René Scharfe","Eric Sunshine","Junio C Hamano","Jeff King","Elijah Newren"],"isPatch":true,"patchVersion":1,"patchTotal":20},"messages":[{"id":"469585","messageId":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":null,"subject":"[PATCH 00/20] leak fixes: various simple leak fixes","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:00Z","receivedAt":"2022-12-28T18:00:31Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"This is a follow-up to the ab/various-leak-fixes topic merged in\n9ea1378d046 (Merge branch 'ab/various-leak-fixes', 2022-12-14). Like\nthat topic this is mixed collection of various leak fixes, all of\nwhich should be simple to review & reason about.\n\nWith this series we'll all 32 more tests to the linux-leaks CI job, as\nthey're now leak-free, out of those 11 are made leak-free in this\ntopic, the others are already leak-free, but aren't being tested in\nCI.\n\nÆvar Arnfjörð Bjarmason (20):\n  t6021: mark as passing with SANITIZE=leak\n  tests: mark tests as passing with SANITIZE=leak\n  bundle.c: don't leak the \"args\" in the \"struct child_process\"\n  commit-graph: use free() instead of UNLEAK()\n  clone: use free() instead of UNLEAK()\n  archive.c: call clear_pathspec() in write_archive()\n  stash: fix a \"struct pathspec\" leak\n  reset: fix cmd_reset() leaks with a clear_pathspec() call\n  name-rev: don't xstrdup() an already dup'd string\n  repack: fix leaks on error with \"goto cleanup\"\n  worktree: fix a trivial leak in prune_worktrees()\n  http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()\n  commit-graph: fix a parse_options_concat() leak\n  show-branch: free() allocated \"head\" before return\n  builtin/merge.c: always free \"struct strbuf msg\"\n  builtin/merge.c: free \"&buf\" on \"Your local changes...\" error\n  connected.c: free(new_pack) in check_connected()\n  object-file.c: free the \"t.tag\" in check_tag()\n  grep.c: make it easier to extend free_grep_patterns()\n  grep API: plug memory leaks by freeing \"header_list\"\n\n archive.c                                  |  1 +\n builtin/clone.c                            |  5 +++--\n builtin/commit-graph.c                     | 10 ++++++----\n builtin/merge.c                            |  5 ++++-\n builtin/name-rev.c                         |  3 ++-\n builtin/repack.c                           | 13 +++++++------\n builtin/reset.c                            | 11 ++++++++---\n builtin/show-branch.c                      |  1 +\n builtin/stash.c                            |  9 ++++++---\n builtin/worktree.c                         |  6 +++---\n bundle.c                                   |  6 ++++--\n connected.c                                | 13 +++++++------\n grep.c                                     | 15 ++++++++++-----\n http-backend.c                             |  7 +++++--\n object-file.c                              |  1 +\n t/t0023-crlf-am.sh                         |  1 +\n t/t1301-shared-repo.sh                     |  1 +\n t/t1302-repo-version.sh                    |  1 +\n t/t1304-default-acl.sh                     |  1 +\n t/t1408-packed-refs.sh                     |  1 +\n t/t1410-reflog.sh                          |  1 +\n t/t2401-worktree-prune.sh                  |  1 +\n t/t2406-worktree-repair.sh                 |  1 +\n t/t3210-pack-refs.sh                       |  1 +\n t/t3800-mktag.sh                           |  1 +\n t/t4152-am-subjects.sh                     |  2 ++\n t/t4254-am-corrupt.sh                      |  2 ++\n t/t4256-am-format-flowed.sh                |  1 +\n t/t4257-am-interactive.sh                  |  2 ++\n t/t5001-archive-attr.sh                    |  1 +\n t/t5004-archive-corner-cases.sh            |  2 ++\n t/t5302-pack-index.sh                      |  2 ++\n t/t5317-pack-objects-filter-objects.sh     |  1 +\n t/t5330-no-lazy-fetch-with-commit-graph.sh |  1 +\n t/t5403-post-checkout-hook.sh              |  1 +\n t/t5502-quickfetch.sh                      |  1 +\n t/t5604-clone-reference.sh                 |  1 +\n t/t5613-info-alternate.sh                  |  2 ++\n t/t6011-rev-list-with-bad-commit.sh        |  1 +\n t/t6014-rev-list-all.sh                    |  1 +\n t/t6021-rev-list-exclude-hidden.sh         |  1 +\n t/t6439-merge-co-error-msgs.sh             |  1 +\n t/t7105-reset-patch.sh                     |  2 ++\n t/t7106-reset-unborn-branch.sh             |  2 ++\n t/t7107-reset-pathspec-file.sh             |  1 +\n t/t7403-submodule-sync.sh                  |  1 +\n t/t7701-repack-unpack-unreachable.sh       |  1 +\n 47 files changed, 108 insertions(+), 38 deletions(-)\n\n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469586","messageId":"patch-01.20-84393ca3139-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 01/20] t6021: mark as passing with SANITIZE=leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:01Z","receivedAt":"2022-12-28T18:00:33Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"This test was recently added in 8c1bc2a71a7 (revision: add new\nparameter to exclude hidden refs, 2022-11-17), but wasn't marked as\npassing with \"SANITIZE=leak\".\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n t/t6021-rev-list-exclude-hidden.sh | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/t/t6021-rev-list-exclude-hidden.sh b/t/t6021-rev-list-exclude-hidden.sh\nindex 32b2b094138..11c50b7c0dd 100755\n--- a/t/t6021-rev-list-exclude-hidden.sh\n+++ b/t/t6021-rev-list-exclude-hidden.sh\n@@ -2,6 +2,7 @@\n \n test_description='git rev-list --exclude-hidden test'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469587","messageId":"patch-02.20-2ad81be0d7a-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 02/20] tests: mark tests as passing with SANITIZE=leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:02Z","receivedAt":"2022-12-28T18:00:34Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the \"ab/various-leak-fixes\" topic was merged in [1] only\nt6021 (which was fixed in the preceding commit) would fail if the\ntests were run in the \"GIT_TEST_PASSING_SANITIZE_LEAK=check\" mode,\ni.e. to check whether we marked all leak-free tests with\n\"TEST_PASSES_SANITIZE_LEAK=true\".\n\nSince then we've had various tests starting to pass under\nSANITIZE=leak. Let's mark those as passing, this is when they started\nto pass, narrowed down with \"git bisect\":\n\n- t5317-pack-objects-filter-objects.sh: In\n  faebba436e6 (list-objects-filter: plug pattern_list leak, 2022-12-01).\n\n- t3210-pack-refs.sh, t5613-info-alternate.sh,\n  t7403-submodule-sync.sh: In 189e97bc4ba (diff: remove parseopts member\n  from struct diff_options, 2022-12-01).\n\n- t1408-packed-refs.sh: In ab91f6b7c42 (Merge branch\n  'rs/diff-parseopts', 2022-12-19).\n\n- t0023-crlf-am.sh, t4152-am-subjects.sh, t4254-am-corrupt.sh,\n  t4256-am-format-flowed.sh, t4257-am-interactive.sh,\n  t5403-post-checkout-hook.sh: In a658e881c13 (am: don't pass strvec to\n  apply_parse_options(), 2022-12-13)\n\n- t1301-shared-repo.sh, t1302-repo-version.sh: In b07a819c05f (reflog:\n  clear leftovers in reflog_expiry_cleanup(), 2022-12-13).\n\n- t1304-default-acl.sh, t1410-reflog.sh,\n  t5330-no-lazy-fetch-with-commit-graph.sh, t5502-quickfetch.sh,\n  t5604-clone-reference.sh, t6014-rev-list-all.sh,\n  t7701-repack-unpack-unreachable.sh: In b0c61be3209 (Merge branch\n  'rs/reflog-expiry-cleanup', 2022-12-26)\n\n1. 9ea1378d046 (Merge branch 'ab/various-leak-fixes', 2022-12-14)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n t/t0023-crlf-am.sh                         | 1 +\n t/t1301-shared-repo.sh                     | 1 +\n t/t1302-repo-version.sh                    | 1 +\n t/t1304-default-acl.sh                     | 1 +\n t/t1408-packed-refs.sh                     | 1 +\n t/t1410-reflog.sh                          | 1 +\n t/t3210-pack-refs.sh                       | 1 +\n t/t4152-am-subjects.sh                     | 2 ++\n t/t4254-am-corrupt.sh                      | 2 ++\n t/t4256-am-format-flowed.sh                | 1 +\n t/t4257-am-interactive.sh                  | 2 ++\n t/t5317-pack-objects-filter-objects.sh     | 1 +\n t/t5330-no-lazy-fetch-with-commit-graph.sh | 1 +\n t/t5403-post-checkout-hook.sh              | 1 +\n t/t5502-quickfetch.sh                      | 1 +\n t/t5604-clone-reference.sh                 | 1 +\n t/t5613-info-alternate.sh                  | 2 ++\n t/t6014-rev-list-all.sh                    | 1 +\n t/t7403-submodule-sync.sh                  | 1 +\n t/t7701-repack-unpack-unreachable.sh       | 1 +\n 20 files changed, 24 insertions(+)\n\ndiff --git a/t/t0023-crlf-am.sh b/t/t0023-crlf-am.sh\nindex f9bbb91f64e..575805513a3 100755\n--- a/t/t0023-crlf-am.sh\n+++ b/t/t0023-crlf-am.sh\n@@ -2,6 +2,7 @@\n \n test_description='Test am with auto.crlf'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n cat >patchfile <<\\EOF\ndiff --git a/t/t1301-shared-repo.sh b/t/t1301-shared-repo.sh\nindex 93a2f91f8a5..a1251f65100 100755\n--- a/t/t1301-shared-repo.sh\n+++ b/t/t1301-shared-repo.sh\n@@ -8,6 +8,7 @@ test_description='Test shared repository initialization'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Remove a default ACL from the test dir if possible.\ndiff --git a/t/t1302-repo-version.sh b/t/t1302-repo-version.sh\nindex 0acabb6d11b..83c327ac2c8 100755\n--- a/t/t1302-repo-version.sh\n+++ b/t/t1302-repo-version.sh\n@@ -5,6 +5,7 @@\n \n test_description='Test repository version check'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh\nindex c69ae41306c..31b89dd9693 100755\n--- a/t/t1304-default-acl.sh\n+++ b/t/t1304-default-acl.sh\n@@ -9,6 +9,7 @@ test_description='Test repository with default ACL'\n # => this must come before . ./test-lib.sh\n umask 077\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # We need an arbitrary other user give permission to using ACLs. root\ndiff --git a/t/t1408-packed-refs.sh b/t/t1408-packed-refs.sh\nindex 41ba1f1d7fc..9469c79a585 100755\n--- a/t/t1408-packed-refs.sh\n+++ b/t/t1408-packed-refs.sh\n@@ -5,6 +5,7 @@ test_description='packed-refs entries are covered by loose refs'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh\nindex aa59954f6c5..6c45965b1e4 100755\n--- a/t/t1410-reflog.sh\n+++ b/t/t1410-reflog.sh\n@@ -7,6 +7,7 @@ test_description='Test prune and reflog expiration'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n check_have () {\ndiff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh\nindex 577f32dc71f..07a0ff93def 100755\n--- a/t/t3210-pack-refs.sh\n+++ b/t/t3210-pack-refs.sh\n@@ -12,6 +12,7 @@ semantic is still the same.\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'enable reflogs' '\ndiff --git a/t/t4152-am-subjects.sh b/t/t4152-am-subjects.sh\nindex 4c68245acad..9f2edba1f83 100755\n--- a/t/t4152-am-subjects.sh\n+++ b/t/t4152-am-subjects.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test subject preservation with format-patch | am'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n make_patches() {\ndiff --git a/t/t4254-am-corrupt.sh b/t/t4254-am-corrupt.sh\nindex 54be7da1611..45f1d4f95e5 100755\n--- a/t/t4254-am-corrupt.sh\n+++ b/t/t4254-am-corrupt.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git am with corrupt input'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n make_mbox_with_nul () {\ndiff --git a/t/t4256-am-format-flowed.sh b/t/t4256-am-format-flowed.sh\nindex 2369c4e17ad..1015273bc82 100755\n--- a/t/t4256-am-format-flowed.sh\n+++ b/t/t4256-am-format-flowed.sh\n@@ -2,6 +2,7 @@\n \n test_description='test format=flowed support of git am'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t4257-am-interactive.sh b/t/t4257-am-interactive.sh\nindex aed8f4de3d6..f26d7fd2dbd 100755\n--- a/t/t4257-am-interactive.sh\n+++ b/t/t4257-am-interactive.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='am --interactive tests'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'set up patches to apply' '\ndiff --git a/t/t5317-pack-objects-filter-objects.sh b/t/t5317-pack-objects-filter-objects.sh\nindex 5b707d911b5..b26d476c646 100755\n--- a/t/t5317-pack-objects-filter-objects.sh\n+++ b/t/t5317-pack-objects-filter-objects.sh\n@@ -5,6 +5,7 @@ test_description='git pack-objects using object filtering'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Test blob:none filter.\ndiff --git a/t/t5330-no-lazy-fetch-with-commit-graph.sh b/t/t5330-no-lazy-fetch-with-commit-graph.sh\nindex 2cc7fd7a476..5eb28f0512d 100755\n--- a/t/t5330-no-lazy-fetch-with-commit-graph.sh\n+++ b/t/t5330-no-lazy-fetch-with-commit-graph.sh\n@@ -2,6 +2,7 @@\n \n test_description='test for no lazy fetch with the commit-graph'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup: prepare a repository with a commit' '\ndiff --git a/t/t5403-post-checkout-hook.sh b/t/t5403-post-checkout-hook.sh\nindex 978f240cdac..cfaae547398 100755\n--- a/t/t5403-post-checkout-hook.sh\n+++ b/t/t5403-post-checkout-hook.sh\n@@ -7,6 +7,7 @@ test_description='Test the post-checkout hook.'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5502-quickfetch.sh b/t/t5502-quickfetch.sh\nindex b160f8b7fb7..7b3ff21b984 100755\n--- a/t/t5502-quickfetch.sh\n+++ b/t/t5502-quickfetch.sh\n@@ -5,6 +5,7 @@ test_description='test quickfetch from local'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh\nindex 2734e37e880..dc86dea1333 100755\n--- a/t/t5604-clone-reference.sh\n+++ b/t/t5604-clone-reference.sh\n@@ -7,6 +7,7 @@ test_description='test clone --reference'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n base_dir=$(pwd)\ndiff --git a/t/t5613-info-alternate.sh b/t/t5613-info-alternate.sh\nindex 895f46bb911..7708cbafa98 100755\n--- a/t/t5613-info-alternate.sh\n+++ b/t/t5613-info-alternate.sh\n@@ -4,6 +4,8 @@\n #\n \n test_description='test transitive info/alternate entries'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'preparing first repository' '\ndiff --git a/t/t6014-rev-list-all.sh b/t/t6014-rev-list-all.sh\nindex c9bedd29cba..16b8bd1d090 100755\n--- a/t/t6014-rev-list-all.sh\n+++ b/t/t6014-rev-list-all.sh\n@@ -2,6 +2,7 @@\n \n test_description='--all includes detached HEADs'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n \ndiff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh\nindex ea92ef52a5e..ff09443a0a4 100755\n--- a/t/t7403-submodule-sync.sh\n+++ b/t/t7403-submodule-sync.sh\n@@ -11,6 +11,7 @@ These tests exercise the \"git submodule sync\" subcommand.\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t7701-repack-unpack-unreachable.sh b/t/t7701-repack-unpack-unreachable.sh\nindex b7ac4f598a8..ebb267855fe 100755\n--- a/t/t7701-repack-unpack-unreachable.sh\n+++ b/t/t7701-repack-unpack-unreachable.sh\n@@ -5,6 +5,7 @@ test_description='git repack works correctly'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n fsha1=\n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469588","messageId":"patch-03.20-a8b373ddef9-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 03/20] bundle.c: don't leak the \"args\" in the \"struct child_process\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:03Z","receivedAt":"2022-12-28T18:00:40Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a leak that's been here since 7366096de9d (bundle API: change\n\"flags\" to be \"extra_index_pack_args\", 2021-09-05), if can't verify\nthe bundle we didn't call child_process_clear() to clear the \"args\".\n\nBut rather than doing that let's verify the bundle before we start\npreparing the process we're going to spawn, if we get an error we\ndon't need to push anything to the \"args\".\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n bundle.c | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/bundle.c b/bundle.c\nindex 4ef7256aa11..9ebb10a8f72 100644\n--- a/bundle.c\n+++ b/bundle.c\n@@ -627,6 +627,10 @@ int unbundle(struct repository *r, struct bundle_header *header,\n \t     enum verify_bundle_flags flags)\n {\n \tstruct child_process ip = CHILD_PROCESS_INIT;\n+\n+\tif (verify_bundle(r, header, flags))\n+\t\treturn -1;\n+\n \tstrvec_pushl(&ip.args, \"index-pack\", \"--fix-thin\", \"--stdin\", NULL);\n \n \t/* If there is a filter, then we need to create the promisor pack. */\n@@ -638,8 +642,6 @@ int unbundle(struct repository *r, struct bundle_header *header,\n \t\tstrvec_clear(extra_index_pack_args);\n \t}\n \n-\tif (verify_bundle(r, header, flags))\n-\t\treturn -1;\n \tip.in = bundle_fd;\n \tip.no_stdout = 1;\n \tip.git_cmd = 1;\n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469589","messageId":"patch-04.20-5be87f9720c-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 04/20] commit-graph: use free() instead of UNLEAK()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:04Z","receivedAt":"2022-12-28T18:00:42Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"In 0bfb48e6723 (builtin/commit-graph.c: UNLEAK variables, 2018-10-03)\nthis was made to UNLEAK(), but we can just as easily free() the memory\ninstead.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/commit-graph.c | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/commit-graph.c b/builtin/commit-graph.c\nindex e8f77f535f3..b6e5726b082 100644\n--- a/builtin/commit-graph.c\n+++ b/builtin/commit-graph.c\n@@ -67,6 +67,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix)\n \tint fd;\n \tstruct stat st;\n \tint flags = 0;\n+\tint ret;\n \n \tstatic struct option builtin_commit_graph_verify_options[] = {\n \t\tOPT_BOOL(0, \"shallow\", &opts.shallow,\n@@ -111,8 +112,9 @@ static int graph_verify(int argc, const char **argv, const char *prefix)\n \tif (!graph)\n \t\treturn !!open_ok;\n \n-\tUNLEAK(graph);\n-\treturn verify_commit_graph(the_repository, graph, flags);\n+\tret = verify_commit_graph(the_repository, graph, flags);\n+\tfree(graph);\n+\treturn ret;\n }\n \n extern int read_replace_refs;\n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469590","messageId":"patch-05.20-49e6714939d-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 05/20] clone: use free() instead of UNLEAK()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:05Z","receivedAt":"2022-12-28T18:00:56Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change an UNLEAK() added in 0c4542738e6 (clone: free or UNLEAK further\npointers when finished, 2021-03-14) to use a \"to_free\" pattern\ninstead. In this case the \"repo\" can be either this absolute_pathdup()\nvalue, or in the \"else if\" branch seen in the context the the\n\"argv[0]\" argument to \"main()\".\n\nWe can only free() the value in the former case, hence the \"to_free\"\npattern.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/clone.c | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex f518bb2dc1f..48156a4f2c2 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -892,6 +892,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tint is_bundle = 0, is_local;\n \tint reject_shallow = 0;\n \tconst char *repo_name, *repo, *work_tree, *git_dir;\n+\tchar *repo_to_free = NULL;\n \tchar *path = NULL, *dir, *display_repo = NULL;\n \tint dest_exists, real_dest_exists = 0;\n \tconst struct ref *refs, *remote_head;\n@@ -949,7 +950,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tpath = get_repo_path(repo_name, &is_bundle);\n \tif (path) {\n \t\tFREE_AND_NULL(path);\n-\t\trepo = absolute_pathdup(repo_name);\n+\t\trepo = repo_to_free = absolute_pathdup(repo_name);\n \t} else if (strchr(repo_name, ':')) {\n \t\trepo = repo_name;\n \t\tdisplay_repo = transport_anonymize_url(repo);\n@@ -1392,7 +1393,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tfree(unborn_head);\n \tfree(dir);\n \tfree(path);\n-\tUNLEAK(repo);\n+\tfree(repo_to_free);\n \tjunk_mode = JUNK_LEAVE_ALL;\n \n \ttransport_ls_refs_options_release(&transport_ls_refs_options);\n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469591","messageId":"patch-07.20-e5a0134d1bb-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 07/20] stash: fix a \"struct pathspec\" leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:07Z","receivedAt":"2022-12-28T18:00:56Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Call clear_pathspec() on the pathspec initialized in\npush_stash(). Initializing that structure in this way is already done\nby a few other callers, and now we have:\n\n\t$ git grep -e 'struct pathspec.* = { 0 }' -e memset.pathspec\n\tadd-interactive.c:              struct pathspec ps_selected = { 0 };\n\tbuiltin/sparse-checkout.c:              struct pathspec p = { 0 };\n\tbuiltin/stash.c:        struct pathspec ps = { 0 };\n\tpathspec.c:     memset(pathspec, 0, sizeof(*pathspec));\n\twt-status.c:                    struct pathspec ps = { 0 };\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/stash.c | 9 ++++++---\n 1 file changed, 6 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/stash.c b/builtin/stash.c\nindex bb0fd861434..e82fb69c2b3 100644\n--- a/builtin/stash.c\n+++ b/builtin/stash.c\n@@ -1708,7 +1708,7 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n \tint pathspec_file_nul = 0;\n \tconst char *stash_msg = NULL;\n \tconst char *pathspec_from_file = NULL;\n-\tstruct pathspec ps;\n+\tstruct pathspec ps = { 0 };\n \tstruct option options[] = {\n \t\tOPT_BOOL('k', \"keep-index\", &keep_index,\n \t\t\t N_(\"keep index\")),\n@@ -1727,6 +1727,7 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n \t\tOPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),\n \t\tOPT_END()\n \t};\n+\tint ret;\n \n \tif (argc) {\n \t\tforce_assume = !strcmp(argv[0], \"-p\");\n@@ -1766,8 +1767,10 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n \t\tdie(_(\"the option '%s' requires '%s'\"), \"--pathspec-file-nul\", \"--pathspec-from-file\");\n \t}\n \n-\treturn do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n-\t\t\t     include_untracked, only_staged);\n+\tret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n+\t\t\t    include_untracked, only_staged);\n+\tclear_pathspec(&ps);\n+\treturn ret;\n }\n \n static int push_stash_unassumed(int argc, const char **argv, const char *prefix)\n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469592","messageId":"patch-06.20-bc45aee530c-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 06/20] archive.c: call clear_pathspec() in write_archive()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:06Z","receivedAt":"2022-12-28T18:00:56Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Plug a leak in the \"struct archiver_args\", and clear_pathspec() the\n\"pathspec\" member that the \"parse_pathspec_arg()\" call in this\nfunction populates.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n archive.c                       | 1 +\n t/t5001-archive-attr.sh         | 1 +\n t/t5004-archive-corner-cases.sh | 2 ++\n 3 files changed, 4 insertions(+)\n\ndiff --git a/archive.c b/archive.c\nindex 941495f5d78..a2d813e50db 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -710,6 +710,7 @@ int write_archive(int argc, const char **argv, const char *prefix,\n \n \tstring_list_clear_func(&args.extra_files, extra_file_info_clear);\n \tfree(args.refname);\n+\tclear_pathspec(&args.pathspec);\n \n \treturn rc;\n }\ndiff --git a/t/t5001-archive-attr.sh b/t/t5001-archive-attr.sh\nindex 2f6eef5e372..04d300eeda7 100755\n--- a/t/t5001-archive-attr.sh\n+++ b/t/t5001-archive-attr.sh\n@@ -3,6 +3,7 @@\n test_description='git archive attribute tests'\n \n TEST_CREATE_REPO_NO_TEMPLATE=1\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n SUBSTFORMAT='%H (%h)%n'\ndiff --git a/t/t5004-archive-corner-cases.sh b/t/t5004-archive-corner-cases.sh\nindex ae508e21623..9f2c6da80e8 100755\n--- a/t/t5004-archive-corner-cases.sh\n+++ b/t/t5004-archive-corner-cases.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test corner cases of git-archive'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # the 10knuls.tar file is used to test for an empty git generated tar\n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469593","messageId":"patch-08.20-21670099c84-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 08/20] reset: fix cmd_reset() leaks with a clear_pathspec() call","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:08Z","receivedAt":"2022-12-28T18:01:00Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Add clear_pathspec() calls to cmd_reset(), including to the codepaths\nwhere we'd return early.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/reset.c                | 11 ++++++++---\n t/t7105-reset-patch.sh         |  2 ++\n t/t7106-reset-unborn-branch.sh |  2 ++\n t/t7107-reset-pathspec-file.sh |  1 +\n 4 files changed, 13 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/reset.c b/builtin/reset.c\nindex fea20a9ba0b..e9c10618cd3 100644\n--- a/builtin/reset.c\n+++ b/builtin/reset.c\n@@ -390,7 +390,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \t\tif (reset_type != NONE)\n \t\t\tdie(_(\"options '%s' and '%s' cannot be used together\"), \"--patch\", \"--{hard,mixed,soft}\");\n \t\ttrace2_cmd_mode(\"patch-interactive\");\n-\t\treturn run_add_interactive(rev, \"--patch=reset\", &pathspec);\n+\t\tupdate_ref_status = run_add_interactive(rev, \"--patch=reset\", &pathspec);\n+\t\tgoto cleanup;\n \t}\n \n \t/* git reset tree [--] paths... can be used to\n@@ -439,8 +440,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \t\t\t\t       LOCK_DIE_ON_ERROR);\n \t\tif (reset_type == MIXED) {\n \t\t\tint flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;\n-\t\t\tif (read_from_tree(&pathspec, &oid, intent_to_add))\n-\t\t\t\treturn 1;\n+\t\t\tif (read_from_tree(&pathspec, &oid, intent_to_add)) {\n+\t\t\t\tupdate_ref_status = 1;\n+\t\t\t\tgoto cleanup;\n+\t\t\t}\n \t\t\tthe_index.updated_skipworktree = 1;\n \t\t\tif (!no_refresh && get_git_work_tree()) {\n \t\t\t\tuint64_t t_begin, t_delta_in_ms;\n@@ -488,5 +491,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \n \tdiscard_index(&the_index);\n \n+cleanup:\n+\tclear_pathspec(&pathspec);\n \treturn update_ref_status;\n }\ndiff --git a/t/t7105-reset-patch.sh b/t/t7105-reset-patch.sh\nindex fc2a6cf5c7a..9b46da7aaa7 100755\n--- a/t/t7105-reset-patch.sh\n+++ b/t/t7105-reset-patch.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git reset --patch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./lib-patch-mode.sh\n \n test_expect_success PERL 'setup' '\ndiff --git a/t/t7106-reset-unborn-branch.sh b/t/t7106-reset-unborn-branch.sh\nindex ecb85c3b823..a0b67a0b843 100755\n--- a/t/t7106-reset-unborn-branch.sh\n+++ b/t/t7106-reset-unborn-branch.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git reset should work on unborn branch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7107-reset-pathspec-file.sh b/t/t7107-reset-pathspec-file.sh\nindex 523efbecde1..af5ea406db3 100755\n--- a/t/t7107-reset-pathspec-file.sh\n+++ b/t/t7107-reset-pathspec-file.sh\n@@ -2,6 +2,7 @@\n \n test_description='reset --pathspec-from-file'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_tick\n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469594","messageId":"patch-12.20-9be5b0c7836-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 12/20] http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:12Z","receivedAt":"2022-12-28T18:01:03Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us ever since\n2f4038ab337 (Git-aware CGI to provide dumb HTTP transport,\n2009-10-30). In this case we're not calling regerror() after a failed\nregexec(), and don't otherwise use \"re\" afterwards.\n\nWe can therefore simplify this code by calling regfree() right after\nthe regexec(). An alternative fix would be to add a regfree() to both\nthe \"return\" and \"break\" path in this for-loop.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n http-backend.c | 7 +++++--\n 1 file changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/http-backend.c b/http-backend.c\nindex 6eb3b2fe51c..9bb63c458b1 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -759,10 +759,14 @@ int cmd_main(int argc, const char **argv)\n \t\tstruct service_cmd *c = &services[i];\n \t\tregex_t re;\n \t\tregmatch_t out[1];\n+\t\tint ret;\n \n \t\tif (regcomp(&re, c->pattern, REG_EXTENDED))\n \t\t\tdie(\"Bogus regex in service table: %s\", c->pattern);\n-\t\tif (!regexec(&re, dir, 1, out, 0)) {\n+\t\tret = regexec(&re, dir, 1, out, 0);\n+\t\tregfree(&re);\n+\n+\t\tif (!ret) {\n \t\t\tsize_t n;\n \n \t\t\tif (strcmp(method, c->method))\n@@ -774,7 +778,6 @@ int cmd_main(int argc, const char **argv)\n \t\t\tdir[out[0].rm_so] = 0;\n \t\t\tbreak;\n \t\t}\n-\t\tregfree(&re);\n \t}\n \n \tif (!cmd)\n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469595","messageId":"patch-09.20-77fcdeb9284-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 09/20] name-rev: don't xstrdup() an already dup'd string","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:09Z","receivedAt":"2022-12-28T18:01:08Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When \"add_to_tip_table()\" is called with a non-zero\n\"shorten_unambiguous\" we always return an xstrdup()'d string, which\nwe'd then xstrdup() again, leaking memory. See [1] and [2] for how\nthis leak came about.\n\n1. 98c5c4ad015 (name-rev: allow to specify a subpath for --refs\n   option, 2013-06-18)\n2. b23e0b9353e (name-rev: allow converting the exact object name at\n   the tip of a ref, 2013-07-07)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/name-rev.c | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/name-rev.c b/builtin/name-rev.c\nindex 15535e914a6..24f4438eb01 100644\n--- a/builtin/name-rev.c\n+++ b/builtin/name-rev.c\n@@ -313,7 +313,8 @@ static void add_to_tip_table(const struct object_id *oid, const char *refname,\n \n \tALLOC_GROW(tip_table.table, tip_table.nr + 1, tip_table.alloc);\n \toidcpy(&tip_table.table[tip_table.nr].oid, oid);\n-\ttip_table.table[tip_table.nr].refname = xstrdup(refname);\n+\ttip_table.table[tip_table.nr].refname = shorten_unambiguous ? refname :\n+\t\txstrdup(refname);\n \ttip_table.table[tip_table.nr].commit = commit;\n \ttip_table.table[tip_table.nr].taggerdate = taggerdate;\n \ttip_table.table[tip_table.nr].from_tag = from_tag;\n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469596","messageId":"patch-10.20-81555cce790-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 10/20] repack: fix leaks on error with \"goto cleanup\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:10Z","receivedAt":"2022-12-28T18:01:12Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change cmd_repack() to \"goto cleanup\" rather than \"return ret\" on\nerror, when we returned we'd potentially skip cleaning up the\nstring_lists and other data we'd allocated in this function.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/repack.c                    | 13 +++++++------\n t/t6011-rev-list-with-bad-commit.sh |  1 +\n 2 files changed, 8 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/repack.c b/builtin/repack.c\nindex c1402ad038f..f6493795318 100644\n--- a/builtin/repack.c\n+++ b/builtin/repack.c\n@@ -948,7 +948,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \n \tret = start_command(&cmd);\n \tif (ret)\n-\t\treturn ret;\n+\t\tgoto cleanup;\n \n \tif (geometry) {\n \t\tFILE *in = xfdopen(cmd.in, \"w\");\n@@ -977,7 +977,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \tfclose(out);\n \tret = finish_command(&cmd);\n \tif (ret)\n-\t\treturn ret;\n+\t\tgoto cleanup;\n \n \tif (!names.nr && !po_args.quiet)\n \t\tprintf_ln(_(\"Nothing new to pack.\"));\n@@ -1007,7 +1007,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\t\t\t       &existing_nonkept_packs,\n \t\t\t\t       &existing_kept_packs);\n \t\tif (ret)\n-\t\t\treturn ret;\n+\t\t\tgoto cleanup;\n \n \t\tif (delete_redundant && expire_to) {\n \t\t\t/*\n@@ -1039,7 +1039,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\t\t\t\t       &existing_nonkept_packs,\n \t\t\t\t\t       &existing_kept_packs);\n \t\t\tif (ret)\n-\t\t\t\treturn ret;\n+\t\t\t\tgoto cleanup;\n \t\t}\n \t}\n \n@@ -1115,7 +1115,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\tstring_list_clear(&include, 0);\n \n \t\tif (ret)\n-\t\t\treturn ret;\n+\t\t\tgoto cleanup;\n \t}\n \n \treprepare_packed_git(the_repository);\n@@ -1172,10 +1172,11 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\twrite_midx_file(get_object_directory(), NULL, NULL, flags);\n \t}\n \n+cleanup:\n \tstring_list_clear(&names, 1);\n \tstring_list_clear(&existing_nonkept_packs, 0);\n \tstring_list_clear(&existing_kept_packs, 0);\n \tclear_pack_geometry(geometry);\n \n-\treturn 0;\n+\treturn ret;\n }\ndiff --git a/t/t6011-rev-list-with-bad-commit.sh b/t/t6011-rev-list-with-bad-commit.sh\nindex bad02cf5b83..b2e422cf0f7 100755\n--- a/t/t6011-rev-list-with-bad-commit.sh\n+++ b/t/t6011-rev-list-with-bad-commit.sh\n@@ -2,6 +2,7 @@\n \n test_description='git rev-list should notice bad commits'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Note:\n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469597","messageId":"patch-11.20-ee05254eb6a-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 11/20] worktree: fix a trivial leak in prune_worktrees()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:11Z","receivedAt":"2022-12-28T18:01:28Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"We were leaking both the \"struct strbuf\" in prune_worktrees(), as well\nas the \"path\" we got from should_prune_worktree(). Since these were\nthe only two uses of the \"struct string_list\" let's change it to a\n\"DUP\" and push these to it with \"string_list_append_nodup()\".\n\nFor the string_list_append_nodup() we could also string_list_append()\nthe main_path.buf, and then strbuf_release(&main_path) right away. But\ndoing it this way avoids an allocation, as we already have the \"struct\nstrbuf\" prepared for appending to \"kept\".\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/worktree.c         | 6 +++---\n t/t2401-worktree-prune.sh  | 1 +\n t/t2406-worktree-repair.sh | 1 +\n 3 files changed, 5 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex 591d659faea..865ce9be22b 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -173,7 +173,7 @@ static void prune_worktrees(void)\n {\n \tstruct strbuf reason = STRBUF_INIT;\n \tstruct strbuf main_path = STRBUF_INIT;\n-\tstruct string_list kept = STRING_LIST_INIT_NODUP;\n+\tstruct string_list kept = STRING_LIST_INIT_DUP;\n \tDIR *dir = opendir(git_path(\"worktrees\"));\n \tstruct dirent *d;\n \tif (!dir)\n@@ -184,14 +184,14 @@ static void prune_worktrees(void)\n \t\tif (should_prune_worktree(d->d_name, &reason, &path, expire))\n \t\t\tprune_worktree(d->d_name, reason.buf);\n \t\telse if (path)\n-\t\t\tstring_list_append(&kept, path)->util = xstrdup(d->d_name);\n+\t\t\tstring_list_append_nodup(&kept, path)->util = xstrdup(d->d_name);\n \t}\n \tclosedir(dir);\n \n \tstrbuf_add_absolute_path(&main_path, get_git_common_dir());\n \t/* massage main worktree absolute path to match 'gitdir' content */\n \tstrbuf_strip_suffix(&main_path, \"/.\");\n-\tstring_list_append(&kept, strbuf_detach(&main_path, NULL));\n+\tstring_list_append_nodup(&kept, strbuf_detach(&main_path, NULL));\n \tprune_dups(&kept);\n \tstring_list_clear(&kept, 1);\n \ndiff --git a/t/t2401-worktree-prune.sh b/t/t2401-worktree-prune.sh\nindex 3d28c7f06b2..568a47ec426 100755\n--- a/t/t2401-worktree-prune.sh\n+++ b/t/t2401-worktree-prune.sh\n@@ -5,6 +5,7 @@ test_description='prune $GIT_DIR/worktrees'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success initialize '\ndiff --git a/t/t2406-worktree-repair.sh b/t/t2406-worktree-repair.sh\nindex 5c44453e1c1..8970780efcc 100755\n--- a/t/t2406-worktree-repair.sh\n+++ b/t/t2406-worktree-repair.sh\n@@ -2,6 +2,7 @@\n \n test_description='test git worktree repair'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469598","messageId":"patch-13.20-78f12259ac5-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 13/20] commit-graph: fix a parse_options_concat() leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:13Z","receivedAt":"2022-12-28T18:01:28Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the parse_options_concat() was added to this file in\n84e4484f128 (commit-graph: use parse_options_concat(), 2021-08-23) we\nwouldn't free() it if we returned early in these cases.\n\nSince \"result\" is 0 by default we can \"goto cleanup\" in both cases,\nand only need to set \"result\" if write_commit_graph_reachable() fails.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/commit-graph.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/commit-graph.c b/builtin/commit-graph.c\nindex b6e5726b082..c76faffde4b 100644\n--- a/builtin/commit-graph.c\n+++ b/builtin/commit-graph.c\n@@ -269,8 +269,8 @@ static int graph_write(int argc, const char **argv, const char *prefix)\n \n \tif (opts.reachable) {\n \t\tif (write_commit_graph_reachable(odb, flags, &write_opts))\n-\t\t\treturn 1;\n-\t\treturn 0;\n+\t\t\tresult = 1;\n+\t\tgoto cleanup;\n \t}\n \n \tif (opts.stdin_packs) {\n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469599","messageId":"patch-14.20-9df41b090b4-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 14/20] show-branch: free() allocated \"head\" before return","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:14Z","receivedAt":"2022-12-28T18:01:28Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Stop leaking the \"head\" variable, which we've been leaking since it\nwas originally added in [1], and in its current form since [2]\n\n1. ed378ec7e85 (Make ref resolution saner, 2006-09-11)\n2. d9e557a320b (show-branch: store resolved head in heap buffer,\n   2017-02-14).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/show-branch.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/show-branch.c b/builtin/show-branch.c\nindex c013abaf942..358ac3e519a 100644\n--- a/builtin/show-branch.c\n+++ b/builtin/show-branch.c\n@@ -956,5 +956,6 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)\n \t\tif (shown_merge_point && --extra < 0)\n \t\t\tbreak;\n \t}\n+\tfree(head);\n \treturn 0;\n }\n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469600","messageId":"patch-16.20-95d59b914d0-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 16/20] builtin/merge.c: free \"&buf\" on \"Your local changes...\" error","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:16Z","receivedAt":"2022-12-28T18:01:39Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Plug a memory leak introduced in [1], since that change didn't follow\nthe \"goto done\" pattern introduced in [2] we'd leak the \"&buf\" memory.\n\n1. e4cdfe84a0d (merge: abort if index does not match HEAD for trivial\n   merges, 2022-07-23)\n2. d5a35c114ab (Copy resolve_ref() return value for longer use,\n   2011-11-13)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/merge.c                | 3 ++-\n t/t6439-merge-co-error-msgs.sh | 1 +\n 2 files changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 8f78f326dbe..e29b456f92c 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -1623,7 +1623,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t\terror(_(\"Your local changes to the following files would be overwritten by merge:\\n  %s\"),\n \t\t\t\t      sb.buf);\n \t\t\t\tstrbuf_release(&sb);\n-\t\t\t\treturn 2;\n+\t\t\t\tret = 2;\n+\t\t\t\tgoto done;\n \t\t\t}\n \n \t\t\t/* See if it is really trivial. */\ndiff --git a/t/t6439-merge-co-error-msgs.sh b/t/t6439-merge-co-error-msgs.sh\nindex 52cf0c87690..0cbec57cdab 100755\n--- a/t/t6439-merge-co-error-msgs.sh\n+++ b/t/t6439-merge-co-error-msgs.sh\n@@ -5,6 +5,7 @@ test_description='unpack-trees error messages'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n \n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469601","messageId":"patch-17.20-ae2f4931315-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 17/20] connected.c: free(new_pack) in check_connected()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:17Z","receivedAt":"2022-12-28T18:01:45Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us since this code was introduced\nin c6807a40dcd (clone: open a shortcut for connectivity check,\n2013-05-26). We'd never free() the \"new_pack\" that we'd potentially\nallocate. Since it's initialized to \"NULL\" it's safe to call free()\nhere unconditionally.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n connected.c | 13 +++++++------\n 1 file changed, 7 insertions(+), 6 deletions(-)\n\ndiff --git a/connected.c b/connected.c\nindex b90fd61790c..e4d404e10b2 100644\n--- a/connected.c\n+++ b/connected.c\n@@ -38,7 +38,7 @@ int check_connected(oid_iterate_fn fn, void *cb_data,\n \tif (!oid) {\n \t\tif (opt->err_fd)\n \t\t\tclose(opt->err_fd);\n-\t\treturn err;\n+\t\tgoto cleanup;\n \t}\n \n \tif (transport && transport->smart_options &&\n@@ -85,8 +85,7 @@ int check_connected(oid_iterate_fn fn, void *cb_data,\n promisor_pack_found:\n \t\t\t;\n \t\t} while ((oid = fn(cb_data)) != NULL);\n-\t\tfree(new_pack);\n-\t\treturn 0;\n+\t\tgoto cleanup;\n \t}\n \n no_promisor_pack_found:\n@@ -123,8 +122,8 @@ int check_connected(oid_iterate_fn fn, void *cb_data,\n \t\trev_list.no_stderr = opt->quiet;\n \n \tif (start_command(&rev_list)) {\n-\t\tfree(new_pack);\n-\t\treturn error(_(\"Could not run 'git rev-list'\"));\n+\t\terr = error(_(\"Could not run 'git rev-list'\"));\n+\t\tgoto cleanup;\n \t}\n \n \tsigchain_push(SIGPIPE, SIG_IGN);\n@@ -157,6 +156,8 @@ int check_connected(oid_iterate_fn fn, void *cb_data,\n \t\terr = error_errno(_(\"failed to close rev-list's stdin\"));\n \n \tsigchain_pop(SIGPIPE);\n+\terr = finish_command(&rev_list) || err;\n+cleanup:\n \tfree(new_pack);\n-\treturn finish_command(&rev_list) || err;\n+\treturn err;\n }\n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469602","messageId":"patch-18.20-aa4df0e1b5c-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 18/20] object-file.c: free the \"t.tag\" in check_tag()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:18Z","receivedAt":"2022-12-28T18:02:00Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us ever since c879daa2372 (Make\nhash-object more robust against malformed objects, 2011-02-05). With\n\"HASH_FORMAT_CHECK\" (used by \"hash-object\" and \"replace\") we'll parse\ntags into a throwaway variable on the stack, but weren't freeing the\n\"item->tag\" we might malloc() when doing so.\n\nMark the tests that now pass in their entirety as passing under\n\"SANITIZE=leak\", which means we'll test them as part of the\n\"linux-leaks\" CI job.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n object-file.c         | 1 +\n t/t3800-mktag.sh      | 1 +\n t/t5302-pack-index.sh | 2 ++\n 3 files changed, 4 insertions(+)\n\ndiff --git a/object-file.c b/object-file.c\nindex c1b71c28347..36ed6c3122c 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -2331,6 +2331,7 @@ static void check_tag(const void *buf, size_t size)\n \tmemset(&t, 0, sizeof(t));\n \tif (parse_tag_buffer(the_repository, &t, buf, size))\n \t\tdie(_(\"corrupt tag\"));\n+\tfree(t.tag);\n }\n \n static int index_mem(struct index_state *istate,\ndiff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh\nindex e3cf0ffbe59..d3e428ff46e 100755\n--- a/t/t3800-mktag.sh\n+++ b/t/t3800-mktag.sh\n@@ -4,6 +4,7 @@\n \n test_description='git mktag: tag object verify test'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n ###########################################################\ndiff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh\nindex b0095ab41d3..54b11f81c63 100755\n--- a/t/t5302-pack-index.sh\n+++ b/t/t5302-pack-index.sh\n@@ -4,6 +4,8 @@\n #\n \n test_description='pack index with 64-bit offsets and object CRC'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469603","messageId":"patch-15.20-8deeee4278d-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 15/20] builtin/merge.c: always free \"struct strbuf msg\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:15Z","receivedAt":"2022-12-28T18:02:00Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Follow-up 465028e0e25 (merge: add missing strbuf_release(),\n2021-10-07) and free \"&msg\" also when we'd \"goto done\" from the scope\nit's allocated in.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/merge.c | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 0f093f2a4f2..8f78f326dbe 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -1577,6 +1577,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\tcommit = remoteheads->item;\n \t\tif (!commit) {\n \t\t\tret = 1;\n+\t\t\tstrbuf_release(&msg);\n \t\t\tgoto done;\n \t\t}\n \n@@ -1589,6 +1590,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t\t\t  overwrite_ignore)) {\n \t\t\tapply_autostash(git_path_merge_autostash(the_repository));\n \t\t\tret = 1;\n+\t\t\tstrbuf_release(&msg);\n \t\t\tgoto done;\n \t\t}\n \n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469604","messageId":"patch-19.20-7928470addb-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 19/20] grep.c: make it easier to extend free_grep_patterns()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:19Z","receivedAt":"2022-12-28T18:02:00Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Before db84376f981 (grep.c: remove \"extended\" in favor of\n\"pattern_expression\", fix segfault, 2022-10-11) the pattern here was:\n\n\tif (!x)\n\t\treturn;\n\tfree(y);\n\nBut after the cleanup in db84376f981 (which was a narrow segfault fix,\nand thus avoided refactoring this) we ended up with:\n\n\tif (!x)\n\t\treturn;\n\tfree(x);\n\nLet's instead do:\n\n\tif (x)\n\t\tfree(x);\n\nThis doesn't matter for now, but makes the free_grep_patterns() easier\nto reason about, as we don't have to wonder why we're doing an early\n\"return\" if and when we add free()-ing of any members that come after\n\"pattern_expression\" in the \"struct grep_opt\".\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n grep.c | 5 ++---\n 1 file changed, 2 insertions(+), 3 deletions(-)\n\ndiff --git a/grep.c b/grep.c\nindex 06eed694936..ca75514f8f6 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -791,9 +791,8 @@ void free_grep_patterns(struct grep_opt *opt)\n \t\tfree(p);\n \t}\n \n-\tif (!opt->pattern_expression)\n-\t\treturn;\n-\tfree_pattern_expr(opt->pattern_expression);\n+\tif (opt->pattern_expression)\n+\t\tfree_pattern_expr(opt->pattern_expression);\n }\n \n static const char *end_of_line(const char *cp, unsigned long *left)\n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469605","messageId":"patch-20.20-8ecc68c3e93-20221228T175512Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH 20/20] grep API: plug memory leaks by freeing \"header_list\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-28T18:00:20Z","receivedAt":"2022-12-28T18:02:00Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the \"header_list\" struct member was added in [1] it wasn't made\nto free the list using loop added for the adjacent \"pattern_list\"\nmember, see [2] for when we started freeing it.\n\nLet's start doing o by splitting up the loop in free_grep_patterns()\ninto a utility function. This makes e.g. this command leak-free when\nrun on git.git:\n\n\t./git -P log -1 --color=always --author=A origin/master\n\n1. 80235ba79ef (\"log --author=me --grep=it\" should find intersection,\n   not union, 2010-01-17)\n2. b48fb5b6a95 (grep: free expressions and patterns when done.,\n   2006-09-27)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n grep.c | 10 ++++++++--\n 1 file changed, 8 insertions(+), 2 deletions(-)\n\ndiff --git a/grep.c b/grep.c\nindex ca75514f8f6..c908535e0d8 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -769,11 +769,11 @@ static void free_pattern_expr(struct grep_expr *x)\n \tfree(x);\n }\n \n-void free_grep_patterns(struct grep_opt *opt)\n+static void free_grep_pat(struct grep_pat *pattern)\n {\n \tstruct grep_pat *p, *n;\n \n-\tfor (p = opt->pattern_list; p; p = n) {\n+\tfor (p = pattern; p; p = n) {\n \t\tn = p->next;\n \t\tswitch (p->token) {\n \t\tcase GREP_PATTERN: /* atom */\n@@ -790,6 +790,12 @@ void free_grep_patterns(struct grep_opt *opt)\n \t\t}\n \t\tfree(p);\n \t}\n+}\n+\n+void free_grep_patterns(struct grep_opt *opt)\n+{\n+\tfree_grep_pat(opt->pattern_list);\n+\tfree_grep_pat(opt->header_list);\n \n \tif (opt->pattern_expression)\n \t\tfree_pattern_expr(opt->pattern_expression);\n-- \n2.39.0.1153.gb0033028ca9\n\n"},{"id":"469606","messageId":"c1d75914-9a73-b61e-c9a1-fe7c95129c9f@web.de","threadId":"59011","inReplyTo":"patch-04.20-5be87f9720c-20221228T175512Z-avarab@gmail.com","subject":"Re: [PATCH 04/20] commit-graph: use free() instead of UNLEAK()","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2022-12-28T18:10:26Z","receivedAt":"2022-12-28T18:10:39Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 28.12.22 um 19:00 schrieb Ævar Arnfjörð Bjarmason:\n> In 0bfb48e6723 (builtin/commit-graph.c: UNLEAK variables, 2018-10-03)\n> this was made to UNLEAK(), but we can just as easily free() the memory\n> instead.\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  builtin/commit-graph.c | 6 ++++--\n>  1 file changed, 4 insertions(+), 2 deletions(-)\n>\n> diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c\n> index e8f77f535f3..b6e5726b082 100644\n> --- a/builtin/commit-graph.c\n> +++ b/builtin/commit-graph.c\n> @@ -67,6 +67,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix)\n>  \tint fd;\n>  \tstruct stat st;\n>  \tint flags = 0;\n> +\tint ret;\n>\n>  \tstatic struct option builtin_commit_graph_verify_options[] = {\n>  \t\tOPT_BOOL(0, \"shallow\", &opts.shallow,\n> @@ -111,8 +112,9 @@ static int graph_verify(int argc, const char **argv, const char *prefix)\n>  \tif (!graph)\n>  \t\treturn !!open_ok;\n>\n> -\tUNLEAK(graph);\n> -\treturn verify_commit_graph(the_repository, graph, flags);\n> +\tret = verify_commit_graph(the_repository, graph, flags);\n> +\tfree(graph);\nShouldn't this be \"free_commit_graph(graph);\" instead?\n\n> +\treturn ret;\n>  }\n>\n>  extern int read_replace_refs;\n"},{"id":"469607","messageId":"ae6c99c1-3f6d-5fa9-3a43-ab10785e2ea9@web.de","threadId":"59011","inReplyTo":"patch-05.20-49e6714939d-20221228T175512Z-avarab@gmail.com","subject":"Re: [PATCH 05/20] clone: use free() instead of UNLEAK()","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2022-12-28T18:20:54Z","receivedAt":"2022-12-28T18:28:54Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 28.12.22 um 19:00 schrieb Ævar Arnfjörð Bjarmason:\n> Change an UNLEAK() added in 0c4542738e6 (clone: free or UNLEAK further\n> pointers when finished, 2021-03-14) to use a \"to_free\" pattern\n> instead. In this case the \"repo\" can be either this absolute_pathdup()\n> value, or in the \"else if\" branch seen in the context the the\n> \"argv[0]\" argument to \"main()\".\n>\n> We can only free() the value in the former case, hence the \"to_free\"\n> pattern.\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  builtin/clone.c | 5 +++--\n>  1 file changed, 3 insertions(+), 2 deletions(-)\n>\n> diff --git a/builtin/clone.c b/builtin/clone.c\n> index f518bb2dc1f..48156a4f2c2 100644\n> --- a/builtin/clone.c\n> +++ b/builtin/clone.c\n> @@ -892,6 +892,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n>  \tint is_bundle = 0, is_local;\n>  \tint reject_shallow = 0;\n>  \tconst char *repo_name, *repo, *work_tree, *git_dir;\n> +\tchar *repo_to_free = NULL;\n>  \tchar *path = NULL, *dir, *display_repo = NULL;\n>  \tint dest_exists, real_dest_exists = 0;\n>  \tconst struct ref *refs, *remote_head;\n> @@ -949,7 +950,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n>  \tpath = get_repo_path(repo_name, &is_bundle);\n>  \tif (path) {\n>  \t\tFREE_AND_NULL(path);\n> -\t\trepo = absolute_pathdup(repo_name);\n> +\t\trepo = repo_to_free = absolute_pathdup(repo_name);\n>  \t} else if (strchr(repo_name, ':')) {\n>  \t\trepo = repo_name;\n\nAlternatively you could do \"repo = xstrdup(repo_name);\" here to simplify\nmemory ownership of this string, at the cost of a small allocation.  But\nthe approach taken by this patch is fine as well.\n\n>  \t\tdisplay_repo = transport_anonymize_url(repo);\n> @@ -1392,7 +1393,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n>  \tfree(unborn_head);\n>  \tfree(dir);\n>  \tfree(path);\n> -\tUNLEAK(repo);\n> +\tfree(repo_to_free);\n>  \tjunk_mode = JUNK_LEAVE_ALL;\n>\n>  \ttransport_ls_refs_options_release(&transport_ls_refs_options);\n"},{"id":"469608","messageId":"CAPig+cS3-j9hHwuoP-vOsbwwTDWPm4RLxPKi0Tn_sWqbNm8KRg@mail.gmail.com","threadId":"59011","inReplyTo":"patch-20.20-8ecc68c3e93-20221228T175512Z-avarab@gmail.com","subject":"Re: [PATCH 20/20] grep API: plug memory leaks by freeing \"header_list\"","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2022-12-28T19:36:03Z","receivedAt":"2022-12-28T19:41:46Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Dec 28, 2022 at 1:03 PM Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n> When the \"header_list\" struct member was added in [1] it wasn't made\n> to free the list using loop added for the adjacent \"pattern_list\"\n> member, see [2] for when we started freeing it.\n>\n> Let's start doing o by splitting up the loop in free_grep_patterns()\n> into a utility function. This makes e.g. this command leak-free when\n> run on git.git:\n\ns/o by/so by/\n\n>         ./git -P log -1 --color=always --author=A origin/master\n>\n> 1. 80235ba79ef (\"log --author=me --grep=it\" should find intersection,\n>    not union, 2010-01-17)\n> 2. b48fb5b6a95 (grep: free expressions and patterns when done.,\n>    2006-09-27)\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n"},{"id":"469609","messageId":"ac9621a0-1046-30de-872f-0171412049bd@web.de","threadId":"59011","inReplyTo":"patch-07.20-e5a0134d1bb-20221228T175512Z-avarab@gmail.com","subject":"Re: [PATCH 07/20] stash: fix a \"struct pathspec\" leak","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2022-12-28T19:45:24Z","receivedAt":"2022-12-28T19:45:40Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 28.12.22 um 19:00 schrieb Ævar Arnfjörð Bjarmason:\n> Call clear_pathspec() on the pathspec initialized in\n> push_stash().\n\nThis puzzled me for a while.  This patch adds an {0} initializer to the\ndeclaration of the pathspec.  I assumed that this is necessary to avoid\ngiving clear_pathspec() an uninitialized struct.  It isn't, though,\nbecause the pathspec is handed to parse_pathspec() first, which\ninitializes it.  So you can safely drop the first hunk.\n\n> Initializing that structure in this way is already done\n> by a few other callers, and now we have:\n>\n> \t$ git grep -e 'struct pathspec.* = { 0 }' -e memset.pathspec\n> \tadd-interactive.c:              struct pathspec ps_selected = { 0 };\n> \tbuiltin/sparse-checkout.c:              struct pathspec p = { 0 };\n> \tbuiltin/stash.c:        struct pathspec ps = { 0 };\n> \tpathspec.c:     memset(pathspec, 0, sizeof(*pathspec));\n> \twt-status.c:                    struct pathspec ps = { 0 };\n\nNot sure if this part of the commit message is useful.  It seems to\nsuggest that the only place to initialize a pathspec with memset is\npathspec.c itself, but there are a few more.  Here's a really sloppy\nway to find (some of?) them:\n\n   $ git grep -e 'struct pathspec [^*]' -e memset --all-match -p -n | awk '\n      /struct pathspec [^*]/ {\n         decl=$0\n         declfunc=prevfunc\n         var=decl; sub(/^.* /, \"\", var); sub(/;/, \"\", var)\n         next\n      }\n      /memset/ && declfunc==prevfunc && match($0, var) {\n         print decl\n         print\n         next\n      }\n      {prevfunc=$0}'\n   builtin/log.c:726:\tstruct pathspec match_all;\n   builtin/log.c:737:\tmemset(&match_all, 0, sizeof(match_all));\n   builtin/ls-files.c:572:\tstruct pathspec pathspec;\n   builtin/ls-files.c:600:\t\tmemset(&pathspec, 0, sizeof(pathspec));\n   builtin/stash.c:1469:\tstruct pathspec ps;\n   builtin/stash.c:1474:\tmemset(&ps, 0, sizeof(ps));\n   builtin/stash.c:1787:\tstruct pathspec ps;\n   builtin/stash.c:1813:\tmemset(&ps, 0, sizeof(ps));\n   merge-recursive.c:479:\tstruct pathspec match_all;\n   merge-recursive.c:480:\tmemset(&match_all, 0, sizeof(match_all));\n   sparse-index.c:364:\t\tstruct pathspec ps;\n   sparse-index.c:388:\t\tmemset(&ps, 0, sizeof(ps));\n\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  builtin/stash.c | 9 ++++++---\n>  1 file changed, 6 insertions(+), 3 deletions(-)\n>\n> diff --git a/builtin/stash.c b/builtin/stash.c\n> index bb0fd861434..e82fb69c2b3 100644\n> --- a/builtin/stash.c\n> +++ b/builtin/stash.c\n> @@ -1708,7 +1708,7 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n>  \tint pathspec_file_nul = 0;\n>  \tconst char *stash_msg = NULL;\n>  \tconst char *pathspec_from_file = NULL;\n> -\tstruct pathspec ps;\n> +\tstruct pathspec ps = { 0 };\n>  \tstruct option options[] = {\n>  \t\tOPT_BOOL('k', \"keep-index\", &keep_index,\n>  \t\t\t N_(\"keep index\")),\n> @@ -1727,6 +1727,7 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n>  \t\tOPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),\n>  \t\tOPT_END()\n>  \t};\n> +\tint ret;\n>\n>  \tif (argc) {\n>  \t\tforce_assume = !strcmp(argv[0], \"-p\");\n> @@ -1766,8 +1767,10 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n>  \t\tdie(_(\"the option '%s' requires '%s'\"), \"--pathspec-file-nul\", \"--pathspec-from-file\");\n>  \t}\n>\n> -\treturn do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n> -\t\t\t     include_untracked, only_staged);\n> +\tret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n> +\t\t\t    include_untracked, only_staged);\n> +\tclear_pathspec(&ps);\n> +\treturn ret;\n>  }\n>\n>  static int push_stash_unassumed(int argc, const char **argv, const char *prefix)\n"},{"id":"469610","messageId":"dbc7c55d-d546-d004-ef44-62bd7349d5c9@web.de","threadId":"59011","inReplyTo":"patch-09.20-77fcdeb9284-20221228T175512Z-avarab@gmail.com","subject":"Re: [PATCH 09/20] name-rev: don't xstrdup() an already dup'd string","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2022-12-28T20:31:21Z","receivedAt":"2022-12-28T20:31:32Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 28.12.22 um 19:00 schrieb Ævar Arnfjörð Bjarmason:\n> When \"add_to_tip_table()\" is called with a non-zero\n> \"shorten_unambiguous\" we always return an xstrdup()'d string, which\n> we'd then xstrdup() again, leaking memory. See [1] and [2] for how\n> this leak came about.\n>\n> 1. 98c5c4ad015 (name-rev: allow to specify a subpath for --refs\n>    option, 2013-06-18)\n> 2. b23e0b9353e (name-rev: allow converting the exact object name at\n>    the tip of a ref, 2013-07-07)\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  builtin/name-rev.c | 3 ++-\n>  1 file changed, 2 insertions(+), 1 deletion(-)\n>\n> diff --git a/builtin/name-rev.c b/builtin/name-rev.c\n> index 15535e914a6..24f4438eb01 100644\n> --- a/builtin/name-rev.c\n> +++ b/builtin/name-rev.c\n> @@ -313,7 +313,8 @@ static void add_to_tip_table(const struct object_id *oid, const char *refname,\n>\n>  \tALLOC_GROW(tip_table.table, tip_table.nr + 1, tip_table.alloc);\n>  \toidcpy(&tip_table.table[tip_table.nr].oid, oid);\n> -\ttip_table.table[tip_table.nr].refname = xstrdup(refname);\n> +\ttip_table.table[tip_table.nr].refname = shorten_unambiguous ? refname :\n> +\t\txstrdup(refname);\n\nHmm, this works based on knowledge about the inner workings of\nname_ref_abbrev(), which provides the refname.  Could be cleaned up by\ninlining that short function, or by moving the xstrdup() call there.\n\n>  \ttip_table.table[tip_table.nr].commit = commit;\n>  \ttip_table.table[tip_table.nr].taggerdate = taggerdate;\n>  \ttip_table.table[tip_table.nr].from_tag = from_tag;\n"},{"id":"469611","messageId":"de30d137-5857-deb8-b497-56205a65b787@web.de","threadId":"59011","inReplyTo":"patch-11.20-ee05254eb6a-20221228T175512Z-avarab@gmail.com","subject":"Re: [PATCH 11/20] worktree: fix a trivial leak in prune_worktrees()","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2022-12-28T20:53:36Z","receivedAt":"2022-12-28T20:53:48Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 28.12.22 um 19:00 schrieb Ævar Arnfjörð Bjarmason:\n> We were leaking both the \"struct strbuf\" in prune_worktrees(), as well\n> as the \"path\" we got from should_prune_worktree(). Since these were\n> the only two uses of the \"struct string_list\" let's change it to a\n> \"DUP\" and push these to it with \"string_list_append_nodup()\".\n\nSeems odd at first to only use _nodup() on a _DUP list, but is valid.\n\n> For the string_list_append_nodup() we could also string_list_append()\n> the main_path.buf, and then strbuf_release(&main_path) right away. But\n> doing it this way avoids an allocation, as we already have the \"struct\n> strbuf\" prepared for appending to \"kept\".\n\nSimilarly we could release the path that should_prune_worktree() gives us\nafter adding it.\n\nThe patch looks good to me.\n\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  builtin/worktree.c         | 6 +++---\n>  t/t2401-worktree-prune.sh  | 1 +\n>  t/t2406-worktree-repair.sh | 1 +\n>  3 files changed, 5 insertions(+), 3 deletions(-)\n>\n> diff --git a/builtin/worktree.c b/builtin/worktree.c\n> index 591d659faea..865ce9be22b 100644\n> --- a/builtin/worktree.c\n> +++ b/builtin/worktree.c\n> @@ -173,7 +173,7 @@ static void prune_worktrees(void)\n>  {\n>  \tstruct strbuf reason = STRBUF_INIT;\n>  \tstruct strbuf main_path = STRBUF_INIT;\n> -\tstruct string_list kept = STRING_LIST_INIT_NODUP;\n> +\tstruct string_list kept = STRING_LIST_INIT_DUP;\n>  \tDIR *dir = opendir(git_path(\"worktrees\"));\n>  \tstruct dirent *d;\n>  \tif (!dir)\n> @@ -184,14 +184,14 @@ static void prune_worktrees(void)\n>  \t\tif (should_prune_worktree(d->d_name, &reason, &path, expire))\n>  \t\t\tprune_worktree(d->d_name, reason.buf);\n>  \t\telse if (path)\n> -\t\t\tstring_list_append(&kept, path)->util = xstrdup(d->d_name);\n> +\t\t\tstring_list_append_nodup(&kept, path)->util = xstrdup(d->d_name);\n>  \t}\n>  \tclosedir(dir);\n>\n>  \tstrbuf_add_absolute_path(&main_path, get_git_common_dir());\n>  \t/* massage main worktree absolute path to match 'gitdir' content */\n>  \tstrbuf_strip_suffix(&main_path, \"/.\");\n> -\tstring_list_append(&kept, strbuf_detach(&main_path, NULL));\n> +\tstring_list_append_nodup(&kept, strbuf_detach(&main_path, NULL));\n>  \tprune_dups(&kept);\n>  \tstring_list_clear(&kept, 1);\n>\n> diff --git a/t/t2401-worktree-prune.sh b/t/t2401-worktree-prune.sh\n> index 3d28c7f06b2..568a47ec426 100755\n> --- a/t/t2401-worktree-prune.sh\n> +++ b/t/t2401-worktree-prune.sh\n> @@ -5,6 +5,7 @@ test_description='prune $GIT_DIR/worktrees'\n>  GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n>  export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n>\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success initialize '\n> diff --git a/t/t2406-worktree-repair.sh b/t/t2406-worktree-repair.sh\n> index 5c44453e1c1..8970780efcc 100755\n> --- a/t/t2406-worktree-repair.sh\n> +++ b/t/t2406-worktree-repair.sh\n> @@ -2,6 +2,7 @@\n>\n>  test_description='test git worktree repair'\n>\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success setup '\n"},{"id":"469612","messageId":"5ca7b3ce-dda9-270a-6439-bd897cd5df28@web.de","threadId":"59011","inReplyTo":"patch-12.20-9be5b0c7836-20221228T175512Z-avarab@gmail.com","subject":"Re: [PATCH 12/20] http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2022-12-28T21:37:50Z","receivedAt":"2022-12-28T21:38:01Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 28.12.22 um 19:00 schrieb Ævar Arnfjörð Bjarmason:\n> Fix a memory leak that's been with us ever since\n> 2f4038ab337 (Git-aware CGI to provide dumb HTTP transport,\n> 2009-10-30). In this case we're not calling regerror() after a failed\n> regexec(), and don't otherwise use \"re\" afterwards.\n>\n> We can therefore simplify this code by calling regfree() right after\n> the regexec(). An alternative fix would be to add a regfree() to both\n> the \"return\" and \"break\" path in this for-loop.\n\nYes, or to add one regfree() call early in the conditional...\n\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  http-backend.c | 7 +++++--\n>  1 file changed, 5 insertions(+), 2 deletions(-)\n>\n> diff --git a/http-backend.c b/http-backend.c\n> index 6eb3b2fe51c..9bb63c458b1 100644\n> --- a/http-backend.c\n> +++ b/http-backend.c\n> @@ -759,10 +759,14 @@ int cmd_main(int argc, const char **argv)\n>  \t\tstruct service_cmd *c = &services[i];\n>  \t\tregex_t re;\n>  \t\tregmatch_t out[1];\n> +\t\tint ret;\n>\n>  \t\tif (regcomp(&re, c->pattern, REG_EXTENDED))\n>  \t\t\tdie(\"Bogus regex in service table: %s\", c->pattern);\n> -\t\tif (!regexec(&re, dir, 1, out, 0)) {\n> +\t\tret = regexec(&re, dir, 1, out, 0);\n> +\t\tregfree(&re);\n> +\n> +\t\tif (!ret) {\n>  \t\t\tsize_t n;\n>\n\n... i.e. right here.  But only after copying the offsets out of \"out\"!\n\nAnyway, the ret approach taken here is fine.\n\n\"dir\" is still leaking, by the way.  Probably worth a separate patch.\n\n>  \t\t\tif (strcmp(method, c->method))\n> @@ -774,7 +778,6 @@ int cmd_main(int argc, const char **argv)\n>  \t\t\tdir[out[0].rm_so] = 0;\n>  \t\t\tbreak;\n>  \t\t}\n> -\t\tregfree(&re);\n>  \t}\n>\n>  \tif (!cmd)\n"},{"id":"469613","messageId":"473c71c1-2456-fe03-a758-4952cb0835c5@web.de","threadId":"59011","inReplyTo":"patch-15.20-8deeee4278d-20221228T175512Z-avarab@gmail.com","subject":"Re: [PATCH 15/20] builtin/merge.c: always free \"struct strbuf msg\"","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2022-12-28T22:06:48Z","receivedAt":"2022-12-28T22:07:01Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 28.12.22 um 19:00 schrieb Ævar Arnfjörð Bjarmason:\n> Follow-up 465028e0e25 (merge: add missing strbuf_release(),\n> 2021-10-07) and free \"&msg\" also when we'd \"goto done\" from the scope\n> it's allocated in.\n\nOK, but quite some trouble to go through to get one of two static\nstrings out without leaking.\n\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  builtin/merge.c | 2 ++\n>  1 file changed, 2 insertions(+)\n>\n> diff --git a/builtin/merge.c b/builtin/merge.c\n> index 0f093f2a4f2..8f78f326dbe 100644\n> --- a/builtin/merge.c\n> +++ b/builtin/merge.c\n> @@ -1577,6 +1577,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n>  \t\tcommit = remoteheads->item;\n>  \t\tif (!commit) {\n>  \t\t\tret = 1;\n> +\t\t\tstrbuf_release(&msg);\n>  \t\t\tgoto done;\n>  \t\t}\n>\n> @@ -1589,6 +1590,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n>  \t\t\t\t\t  overwrite_ignore)) {\n>  \t\t\tapply_autostash(git_path_merge_autostash(the_repository));\n>  \t\t\tret = 1;\n> +\t\t\tstrbuf_release(&msg);\n>  \t\t\tgoto done;\n>  \t\t}\n>\n\nHow about not using strbuf instead?\n\n builtin/merge.c | 11 ++++-------\n 1 file changed, 4 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 0f093f2a4f..91dd5435c5 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -1560,7 +1560,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t!common->next &&\n \t\t\toideq(&common->item->object.oid, &head_commit->object.oid)) {\n \t\t/* Again the most common case of merging one remote. */\n-\t\tstruct strbuf msg = STRBUF_INIT;\n+\t\tconst char *msg = have_message ?\n+\t\t\t\"Fast-forward (no commit created; -m option ignored)\" :\n+\t\t\t\"Fast-forward\";\n \t\tstruct commit *commit;\n\n \t\tif (verbosity >= 0) {\n@@ -1570,10 +1572,6 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t       find_unique_abbrev(&remoteheads->item->object.oid,\n \t\t\t\t\t\t  DEFAULT_ABBREV));\n \t\t}\n-\t\tstrbuf_addstr(&msg, \"Fast-forward\");\n-\t\tif (have_message)\n-\t\t\tstrbuf_addstr(&msg,\n-\t\t\t\t\" (no commit created; -m option ignored)\");\n \t\tcommit = remoteheads->item;\n \t\tif (!commit) {\n \t\t\tret = 1;\n@@ -1592,9 +1590,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\tgoto done;\n \t\t}\n\n-\t\tfinish(head_commit, remoteheads, &commit->object.oid, msg.buf);\n+\t\tfinish(head_commit, remoteheads, &commit->object.oid, msg);\n \t\tremove_merge_branch_state(the_repository);\n-\t\tstrbuf_release(&msg);\n \t\tgoto done;\n \t} else if (!remoteheads->next && common->next)\n \t\t;\n"},{"id":"469615","messageId":"24cd9d7c-2eb5-e17b-3cd2-98a2c6bd1424@web.de","threadId":"59011","inReplyTo":"patch-16.20-95d59b914d0-20221228T175512Z-avarab@gmail.com","subject":"Re: [PATCH 16/20] builtin/merge.c: free \"&buf\" on \"Your local changes...\" error","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2022-12-28T22:13:41Z","receivedAt":"2022-12-28T22:13:59Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 28.12.22 um 19:00 schrieb Ævar Arnfjörð Bjarmason:\n> Plug a memory leak introduced in [1], since that change didn't follow\n> the \"goto done\" pattern introduced in [2] we'd leak the \"&buf\" memory.\n>\n> 1. e4cdfe84a0d (merge: abort if index does not match HEAD for trivial\n>    merges, 2022-07-23)\n> 2. d5a35c114ab (Copy resolve_ref() return value for longer use,\n>    2011-11-13)\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  builtin/merge.c                | 3 ++-\n>  t/t6439-merge-co-error-msgs.sh | 1 +\n>  2 files changed, 3 insertions(+), 1 deletion(-)\n>\n> diff --git a/builtin/merge.c b/builtin/merge.c\n> index 8f78f326dbe..e29b456f92c 100644\n> --- a/builtin/merge.c\n> +++ b/builtin/merge.c\n> @@ -1623,7 +1623,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n>  \t\t\t\terror(_(\"Your local changes to the following files would be overwritten by merge:\\n  %s\"),\n>  \t\t\t\t      sb.buf);\n>  \t\t\t\tstrbuf_release(&sb);\n> -\t\t\t\treturn 2;\n> +\t\t\t\tret = 2;\n> +\t\t\t\tgoto done;\n\nGood change -- only a single return remains, which is easier to handle.\n\nIf it was only about \"buf\" then moving its strbuf_release() call way up to\nfree it immediately after its last use would work as well.\n\n>  \t\t\t}\n>\n>  \t\t\t/* See if it is really trivial. */\n> diff --git a/t/t6439-merge-co-error-msgs.sh b/t/t6439-merge-co-error-msgs.sh\n> index 52cf0c87690..0cbec57cdab 100755\n> --- a/t/t6439-merge-co-error-msgs.sh\n> +++ b/t/t6439-merge-co-error-msgs.sh\n> @@ -5,6 +5,7 @@ test_description='unpack-trees error messages'\n>  GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n>  export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n>\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>\n"},{"id":"469617","messageId":"b6cd3023-2d9f-b1bd-d8e8-16dca4899cfb@web.de","threadId":"59011","inReplyTo":"patch-18.20-aa4df0e1b5c-20221228T175512Z-avarab@gmail.com","subject":"Re: [PATCH 18/20] object-file.c: free the \"t.tag\" in check_tag()","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2022-12-28T22:25:58Z","receivedAt":"2022-12-28T22:26:09Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 28.12.22 um 19:00 schrieb Ævar Arnfjörð Bjarmason:\n> Fix a memory leak that's been with us ever since c879daa2372 (Make\n> hash-object more robust against malformed objects, 2011-02-05). With\n> \"HASH_FORMAT_CHECK\" (used by \"hash-object\" and \"replace\") we'll parse\n> tags into a throwaway variable on the stack, but weren't freeing the\n> \"item->tag\" we might malloc() when doing so.\n>\n> Mark the tests that now pass in their entirety as passing under\n> \"SANITIZE=leak\", which means we'll test them as part of the\n> \"linux-leaks\" CI job.\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  object-file.c         | 1 +\n>  t/t3800-mktag.sh      | 1 +\n>  t/t5302-pack-index.sh | 2 ++\n>  3 files changed, 4 insertions(+)\n>\n> diff --git a/object-file.c b/object-file.c\n> index c1b71c28347..36ed6c3122c 100644\n> --- a/object-file.c\n> +++ b/object-file.c\n> @@ -2331,6 +2331,7 @@ static void check_tag(const void *buf, size_t size)\n>  \tmemset(&t, 0, sizeof(t));\n>  \tif (parse_tag_buffer(the_repository, &t, buf, size))\n>  \t\tdie(_(\"corrupt tag\"));\n> +\tfree(t.tag);\n\nBetter use release_tag_memory() instead to avoid leaking knowledge of tag\ninternals, no?\n\n>  }\n>\n>  static int index_mem(struct index_state *istate,\n> diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh\n> index e3cf0ffbe59..d3e428ff46e 100755\n> --- a/t/t3800-mktag.sh\n> +++ b/t/t3800-mktag.sh\n> @@ -4,6 +4,7 @@\n>\n>  test_description='git mktag: tag object verify test'\n>\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  ###########################################################\n> diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh\n> index b0095ab41d3..54b11f81c63 100755\n> --- a/t/t5302-pack-index.sh\n> +++ b/t/t5302-pack-index.sh\n> @@ -4,6 +4,8 @@\n>  #\n>\n>  test_description='pack index with 64-bit offsets and object CRC'\n> +\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success 'setup' '\n"},{"id":"469618","messageId":"aabc1976-63cf-4057-c5b4-8ab00a33b8c6@web.de","threadId":"59011","inReplyTo":"patch-20.20-8ecc68c3e93-20221228T175512Z-avarab@gmail.com","subject":"Re: [PATCH 20/20] grep API: plug memory leaks by freeing \"header_list\"","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2022-12-28T22:50:02Z","receivedAt":"2022-12-28T22:50:19Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 28.12.22 um 19:00 schrieb Ævar Arnfjörð Bjarmason:\n> When the \"header_list\" struct member was added in [1] it wasn't made\n> to free the list using loop added for the adjacent \"pattern_list\"\n> member, see [2] for when we started freeing it.\n>\n> Let's start doing o by splitting up the loop in free_grep_patterns()\n> into a utility function. This makes e.g. this command leak-free when\n> run on git.git:\n>\n> \t./git -P log -1 --color=always --author=A origin/master\n>\n> 1. 80235ba79ef (\"log --author=me --grep=it\" should find intersection,\n>    not union, 2010-01-17)\n> 2. b48fb5b6a95 (grep: free expressions and patterns when done.,\n>    2006-09-27)\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  grep.c | 10 ++++++++--\n>  1 file changed, 8 insertions(+), 2 deletions(-)\n>\n> diff --git a/grep.c b/grep.c\n> index ca75514f8f6..c908535e0d8 100644\n> --- a/grep.c\n> +++ b/grep.c\n> @@ -769,11 +769,11 @@ static void free_pattern_expr(struct grep_expr *x)\n>  \tfree(x);\n>  }\n>\n> -void free_grep_patterns(struct grep_opt *opt)\n> +static void free_grep_pat(struct grep_pat *pattern)\n>  {\n>  \tstruct grep_pat *p, *n;\n>\n> -\tfor (p = opt->pattern_list; p; p = n) {\n> +\tfor (p = pattern; p; p = n) {\n>  \t\tn = p->next;\n>  \t\tswitch (p->token) {\n>  \t\tcase GREP_PATTERN: /* atom */\n> @@ -790,6 +790,12 @@ void free_grep_patterns(struct grep_opt *opt)\n>  \t\t}\n>  \t\tfree(p);\n>  \t}\n> +}\n> +\n> +void free_grep_patterns(struct grep_opt *opt)\n> +{\n> +\tfree_grep_pat(opt->pattern_list);\n> +\tfree_grep_pat(opt->header_list);\n\nOK.  Patch 19 didn't help me understand this one, though, contrary to\nthe foreshadowing in its commit message.  It seems quite unrelated, in\nfact.  It's a stylistic improvement, to be sure, but I expected more\nstructural relevance.\n\nFactoring out free_grep_pat() first and then using it for header_list\nin a separate patch would have made a difference by making the actual\nleak fix being a one-liner.\n\nNot necessarily worth a re-roll, though -- the patch is understandable\nas-is, but it probably took me a moment longer with refactoring and\nfix blended together like this.\n\n>\n>  \tif (opt->pattern_expression)\n>  \t\tfree_pattern_expr(opt->pattern_expression);\n"},{"id":"469621","messageId":"xmqq1qoiofoc.fsf@gitster.g","threadId":"59011","inReplyTo":"ac9621a0-1046-30de-872f-0171412049bd@web.de","subject":"Re: [PATCH 07/20] stash: fix a \"struct pathspec\" leak","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-12-29T07:02:59Z","receivedAt":"2022-12-29T07:03:41Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"René Scharfe <l.s.r@web.de> writes:\n\n> Am 28.12.22 um 19:00 schrieb Ævar Arnfjörð Bjarmason:\n>> Call clear_pathspec() on the pathspec initialized in\n>> push_stash().\n>\n> This puzzled me for a while.  This patch adds an {0} initializer to the\n> declaration of the pathspec.  I assumed that this is necessary to avoid\n> giving clear_pathspec() an uninitialized struct.  It isn't, though,\n> because the pathspec is handed to parse_pathspec() first, which\n> initializes it.  So you can safely drop the first hunk.\n\nIt did mislead me too.  I expected that addition of \"= { 0 }\" was to\nremove memset('\\0') somewhere else, but that is not the case.\n"},{"id":"469622","messageId":"xmqqv8lun0n8.fsf@gitster.g","threadId":"59011","inReplyTo":"dbc7c55d-d546-d004-ef44-62bd7349d5c9@web.de","subject":"Re: [PATCH 09/20] name-rev: don't xstrdup() an already dup'd string","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-12-29T07:12:59Z","receivedAt":"2022-12-29T07:13:05Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"René Scharfe <l.s.r@web.de> writes:\n\n>> -\ttip_table.table[tip_table.nr].refname = xstrdup(refname);\n>> +\ttip_table.table[tip_table.nr].refname = shorten_unambiguous ? refname :\n>> +\t\txstrdup(refname);\n>\n> Hmm, this works based on knowledge about the inner workings of\n> name_ref_abbrev(), which provides the refname.  Could be cleaned up by\n> inlining that short function, or by moving the xstrdup() call there.\n\nYeah, name_ref_abbrev() returns sometimes an allocated and some\nother times a borrowed piece of memory, which is a poor design that\nignores memory ownership issues.  Luckily the function being touched\nis the sole caller of it, and I agree with you that inlining may give\nus a better fix.\n\n"},{"id":"469623","messageId":"xmqqpmc2mzpw.fsf@gitster.g","threadId":"59011","inReplyTo":"5ca7b3ce-dda9-270a-6439-bd897cd5df28@web.de","subject":"Re: [PATCH 12/20] http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-12-29T07:32:59Z","receivedAt":"2022-12-29T07:33:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"René Scharfe <l.s.r@web.de> writes:\n\n>> diff --git a/http-backend.c b/http-backend.c\n>> index 6eb3b2fe51c..9bb63c458b1 100644\n>> --- a/http-backend.c\n>> +++ b/http-backend.c\n>> @@ -759,10 +759,14 @@ int cmd_main(int argc, const char **argv)\n>>  \t\tstruct service_cmd *c = &services[i];\n>>  \t\tregex_t re;\n>>  \t\tregmatch_t out[1];\n>> +\t\tint ret;\n>>\n>>  \t\tif (regcomp(&re, c->pattern, REG_EXTENDED))\n>>  \t\t\tdie(\"Bogus regex in service table: %s\", c->pattern);\n>> -\t\tif (!regexec(&re, dir, 1, out, 0)) {\n>> +\t\tret = regexec(&re, dir, 1, out, 0);\n>> +\t\tregfree(&re);\n>> +\n>> +\t\tif (!ret) {\n>>  \t\t\tsize_t n;\n>>\n>\n> ... i.e. right here.  But only after copying the offsets out of \"out\"!\n\n\"only after...\"?  Do out[i].rm_eo and out[i].rm_so become invalid\nafter calling regfree() on the regex out[] was taken against?  I do\nnot think so, and am confused by the comment.  After all, if we can\nfree only after copying the offsets out of \"out\", the posted patch\nin question is already wrong ;-)\n\n> Anyway, the ret approach taken here is fine.\n\nYup.\n\n> \"dir\" is still leaking, by the way.  Probably worth a separate patch.\n\nGood eyes.  But I'd actually say UNLEAK() is fine for that one.\n\nThanks.\n\n"},{"id":"469625","messageId":"xmqqk02amvjw.fsf@gitster.g","threadId":"59011","inReplyTo":"patch-05.20-49e6714939d-20221228T175512Z-avarab@gmail.com","subject":"Re: [PATCH 05/20] clone: use free() instead of UNLEAK()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-12-29T09:02:59Z","receivedAt":"2022-12-29T09:03:03Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> Change an UNLEAK() added in 0c4542738e6 (clone: free or UNLEAK further\n> pointers when finished, 2021-03-14) to use a \"to_free\" pattern\n> instead. In this case the \"repo\" can be either this absolute_pathdup()\n> value, or in the \"else if\" branch seen in the context the the\n> \"argv[0]\" argument to \"main()\".\n>\n> We can only free() the value in the former case, hence the \"to_free\"\n> pattern.\n\nMany other patches in the series, especially the ones that touch the\nlibrary-ish parts that can be called unbounded number of times, do\nmake sense, but this patch helps nobody.  Not even the leak checker,\nwho should already be happy with the existing UNLEAK() marking.  The\nonly thing it does is to free() a piece of memory obtained from a\none-time allocation that will be discarded upon program exit anyway.\n\nIf this were a freestanding patch done outside any series, I would\nprobably have not bothered to queue it.  I'll be queuing as part of\nthe larger whole, but I am not all that impressed by this step and\nthe thinking that led to its inclusion in the series.\n\nThanks.\n\n\n\n\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  builtin/clone.c | 5 +++--\n>  1 file changed, 3 insertions(+), 2 deletions(-)\n>\n> diff --git a/builtin/clone.c b/builtin/clone.c\n> index f518bb2dc1f..48156a4f2c2 100644\n> --- a/builtin/clone.c\n> +++ b/builtin/clone.c\n> @@ -892,6 +892,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n>  \tint is_bundle = 0, is_local;\n>  \tint reject_shallow = 0;\n>  \tconst char *repo_name, *repo, *work_tree, *git_dir;\n> +\tchar *repo_to_free = NULL;\n>  \tchar *path = NULL, *dir, *display_repo = NULL;\n>  \tint dest_exists, real_dest_exists = 0;\n>  \tconst struct ref *refs, *remote_head;\n> @@ -949,7 +950,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n>  \tpath = get_repo_path(repo_name, &is_bundle);\n>  \tif (path) {\n>  \t\tFREE_AND_NULL(path);\n> -\t\trepo = absolute_pathdup(repo_name);\n> +\t\trepo = repo_to_free = absolute_pathdup(repo_name);\n>  \t} else if (strchr(repo_name, ':')) {\n>  \t\trepo = repo_name;\n>  \t\tdisplay_repo = transport_anonymize_url(repo);\n> @@ -1392,7 +1393,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n>  \tfree(unborn_head);\n>  \tfree(dir);\n>  \tfree(path);\n> -\tUNLEAK(repo);\n> +\tfree(repo_to_free);\n>  \tjunk_mode = JUNK_LEAVE_ALL;\n>  \n>  \ttransport_ls_refs_options_release(&transport_ls_refs_options);\n"},{"id":"469626","messageId":"xmqqedsimv38.fsf@gitster.g","threadId":"59011","inReplyTo":"patch-08.20-21670099c84-20221228T175512Z-avarab@gmail.com","subject":"Re: [PATCH 08/20] reset: fix cmd_reset() leaks with a clear_pathspec() call","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-12-29T09:12:59Z","receivedAt":"2022-12-29T09:13:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> Add clear_pathspec() calls to cmd_reset(), including to the codepaths\n> where we'd return early.\n\nUnlike the [05/20] step, this did not have UNLEAK(), so it is a true\nimprovement ;-)\n\n\n"},{"id":"469628","messageId":"221229.86zgb6tru1.gmgdl@evledraar.gmail.com","threadId":"59011","inReplyTo":"xmqqk02amvjw.fsf@gitster.g","subject":"Re: [PATCH 05/20] clone: use free() instead of UNLEAK()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-29T10:20:51Z","receivedAt":"2022-12-29T10:41:36Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Thu, Dec 29 2022, Junio C Hamano wrote:\n\n> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n>\n>> Change an UNLEAK() added in 0c4542738e6 (clone: free or UNLEAK further\n>> pointers when finished, 2021-03-14) to use a \"to_free\" pattern\n>> instead. In this case the \"repo\" can be either this absolute_pathdup()\n>> value, or in the \"else if\" branch seen in the context the the\n>> \"argv[0]\" argument to \"main()\".\n>>\n>> We can only free() the value in the former case, hence the \"to_free\"\n>> pattern.\n>\n> Many other patches in the series, especially the ones that touch the\n> library-ish parts that can be called unbounded number of times, do\n> make sense, but this patch helps nobody.  Not even the leak checker,\n> who should already be happy with the existing UNLEAK() marking.  The\n> only thing it does is to free() a piece of memory obtained from a\n> one-time allocation that will be discarded upon program exit anyway.\n\nThe changes in this series that deal with UNLEAK() take it as a given\nthat it's a good thing to replace these trivial cases with a free().\n\nBut the rationale is in ac95f5d36ad (built-ins: use free() not UNLEAK()\nif trivial, rm dead code, 2022-11-08) in the earlier topic, this is the\nfollow-up.\n\nWe only have 15 UNLEAK() invocations in-tree left, with this series\n(which made no special effort to get the rest, but just the remaining\nvery low hanging fruit) it's 13.\n\nIf our built-ins were using this pattern consistently I think it would\nbe worth keeping & using UNLEAK() like this, but they aren't.\n\nEven the \"display_repo\" variable seen in the context of this patch is\nfree()'d, see 46da295a770 (clone/fetch: anonymize URLs in the reflog,\n2020-06-04), along with the rest in this function and others (with the\nexception of the remaining UNLEAK(...)), e.g. \"remote_name\" etc.\n\nSo I think keeping it just makes the code more confusing, one wonders\nwhy this particular variable is being UNLEAK()'d, instead of just\nfree()'d like the rest.\n\nAs the comment on the SUPPRESS_ANNOTATED_LEAKS macro notes we only get\nthe benefit from it if you compile with SUPPRESS_ANNOTATED_LEAKS, so\ne.g. if you use SANITIZE=leak it'll kick in, but not on a normal build\nand e.g.:\n\n\tvalgrind --leak-check=full ./git commit-graph verify\n\nWhich will with UNLEAK() report the leak fixed in 04/20 here (I'm just\nusing it in this example since easier to reproduce), but with free() we\nwon't report it.\n\nI agree it has a marginal benefit, e.g. it won't contribute to the\nlinux-leaks job, as it uses SUPPRESS_ANNOTATED_LEAKS, but the above is\nwhy I think it's worth changing the remaining low-hanging UNLEAK() fruit\nto free().\n\nWe do have cases where it's much tricker to replace those UNLEAK() with\nfree(). I think it's much better if we narrow its use to those cases at\nthis point.\n"},{"id":"469632","messageId":"ca564bd3-cd45-aa4e-7c5a-8fe4e0cefbce@web.de","threadId":"59011","inReplyTo":"xmqqpmc2mzpw.fsf@gitster.g","subject":"Re: [PATCH 12/20] http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2022-12-29T15:49:44Z","receivedAt":"2022-12-29T15:49:59Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 29.12.22 um 08:32 schrieb Junio C Hamano:\n> René Scharfe <l.s.r@web.de> writes:\n>\n>>> diff --git a/http-backend.c b/http-backend.c\n>>> index 6eb3b2fe51c..9bb63c458b1 100644\n>>> --- a/http-backend.c\n>>> +++ b/http-backend.c\n>>> @@ -759,10 +759,14 @@ int cmd_main(int argc, const char **argv)\n>>>  \t\tstruct service_cmd *c = &services[i];\n>>>  \t\tregex_t re;\n>>>  \t\tregmatch_t out[1];\n>>> +\t\tint ret;\n>>>\n>>>  \t\tif (regcomp(&re, c->pattern, REG_EXTENDED))\n>>>  \t\t\tdie(\"Bogus regex in service table: %s\", c->pattern);\n>>> -\t\tif (!regexec(&re, dir, 1, out, 0)) {\n>>> +\t\tret = regexec(&re, dir, 1, out, 0);\n>>> +\t\tregfree(&re);\n>>> +\n>>> +\t\tif (!ret) {\n>>>  \t\t\tsize_t n;\n>>>\n>>\n>> ... i.e. right here.  But only after copying the offsets out of \"out\"!\n>\n> \"only after...\"?  Do out[i].rm_eo and out[i].rm_so become invalid\n> after calling regfree() on the regex out[] was taken against?  I do\n> not think so, and am confused by the comment.\nNah, sorry, I was confused. o_O  \"out\" is not affected by regfree(), of\ncourse; it's supplied by the regexec() caller -- cmd_main() owns it.\n\nRené\n"},{"id":"469644","messageId":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-00.20-00000000000-20221228T175512Z-avarab@gmail.com","subject":"[PATCH v2 00/20] leak fixes: various simple leak fixes","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:15Z","receivedAt":"2022-12-30T02:18:56Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"This is a follow-up to the ab/various-leak-fixes topic merged in\n9ea1378d046 (Merge branch 'ab/various-leak-fixes', 2022-12-14). Like\nthat topic this is mixed collection of various leak fixes, all of\nwhich should be simple to review & reason about.\n\nChanges since v1:\n\n * v1 added 32 more tests to the linux-leaks job, this adds 51. In the\n   v1 11 test files were made to pass by this series itself (the 1/20\n   adds already existing tests with TEST_PASSES_SANITIZE_LEAK=true),\n   we now have 30 newly passing tests.\n\n   This is because I added a couple of more leak fixes to this v2, see below.\n\n* Squash the previous [1-2]/20 into one.\n* Squash all of the \"pathspec\" leak fixes into one patch\n* Add a \"name-rev\" leak fix. Instad of UNLEAK() we can (mostly) skip\n  allocation altogether (just need a string_list container)\n* Fix the \"dir\" leak in http-backend.c as suggested, and also a\n  \"cmd_arg\" leak in the same function.\n* Rewrote the \"builtin/merge.c\" fix for \"msg\" as René suggested\n* Use release_tag_memory() in the check_tag() fix. I also missed that\n  I'd submitted that leak fix in another series. I re-rolled it\n  (https://lore.kernel.org/git/cover-v2-0.3-00000000000-20221230T011725Z-avarab@gmail.com/)\n  to avoid fixing the leak, and went for René's suggestion of using\n  release_tag_memory() in this v2.\n* Squashed/rewrote the grep.c refactoring & leak fix, hopfully this\n  state is easier to grok/follow.\n* Add two new leak fixes to the end of this series, each one is\n  trivial, but they make 6 and 12 new tests pass in their entirety.\n* Hopefully addressed all other comments, e.g. a typo fix, commit\n  message clarifications etc.\n\nBranch & CI for this at\nhttps://github.com/avar/git/tree/avar/leak-fixes-more-misc-trivial-2\n(the \"win build\" failure is unrelated, some generic CI issue that also\nhappens if I re-push Junio's \"master\").\n\nÆvar Arnfjörð Bjarmason (20):\n  tests: mark tests as passing with SANITIZE=leak\n  bundle.c: don't leak the \"args\" in the \"struct child_process\"\n  commit-graph: use free() instead of UNLEAK()\n  clone: use free() instead of UNLEAK()\n  various: add missing clear_pathspec(), fix leaks\n  name-rev: don't xstrdup() an already dup'd string\n  repack: fix leaks on error with \"goto cleanup\"\n  worktree: fix a trivial leak in prune_worktrees()\n  http-backend.c: fix \"dir\" and \"cmd_arg\" leaks in cmd_main()\n  http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()\n  commit-graph: fix a parse_options_concat() leak\n  show-branch: free() allocated \"head\" before return\n  builtin/merge.c: always free \"struct strbuf msg\"\n  builtin/merge.c: free \"&buf\" on \"Your local changes...\" error\n  connected.c: free(new_pack) in check_connected()\n  object-file.c: release the \"tag\" in check_tag()\n  grep.c: refactor free_grep_patterns()\n  grep API: plug memory leaks by freeing \"header_list\"\n  receive-pack: free() the \"ref_name\" in \"struct command\"\n  push: free_refs() the \"local_refs\" in set_refspecs()\n\n archive.c                                  |  1 +\n builtin/clean.c                            |  1 +\n builtin/clone.c                            |  5 +++--\n builtin/commit-graph.c                     | 10 ++++++----\n builtin/merge.c                            | 14 ++++++-------\n builtin/name-rev.c                         | 23 ++++++++++------------\n builtin/push.c                             |  1 +\n builtin/receive-pack.c                     | 10 ++++++++++\n builtin/repack.c                           | 13 ++++++------\n builtin/reset.c                            | 11 ++++++++---\n builtin/show-branch.c                      |  1 +\n builtin/stash.c                            |  7 +++++--\n builtin/worktree.c                         |  6 +++---\n bundle.c                                   |  6 ++++--\n connected.c                                | 13 ++++++------\n grep.c                                     | 15 +++++++++-----\n http-backend.c                             |  9 +++++++--\n object-file.c                              |  1 +\n t/t0023-crlf-am.sh                         |  1 +\n t/t1301-shared-repo.sh                     |  1 +\n t/t1302-repo-version.sh                    |  1 +\n t/t1304-default-acl.sh                     |  1 +\n t/t1408-packed-refs.sh                     |  1 +\n t/t1410-reflog.sh                          |  1 +\n t/t1416-ref-transaction-hooks.sh           |  1 +\n t/t2401-worktree-prune.sh                  |  1 +\n t/t2406-worktree-repair.sh                 |  1 +\n t/t3210-pack-refs.sh                       |  1 +\n t/t3800-mktag.sh                           |  1 +\n t/t4152-am-subjects.sh                     |  2 ++\n t/t4254-am-corrupt.sh                      |  2 ++\n t/t4256-am-format-flowed.sh                |  1 +\n t/t4257-am-interactive.sh                  |  2 ++\n t/t5001-archive-attr.sh                    |  1 +\n t/t5004-archive-corner-cases.sh            |  2 ++\n t/t5302-pack-index.sh                      |  2 ++\n t/t5317-pack-objects-filter-objects.sh     |  1 +\n t/t5330-no-lazy-fetch-with-commit-graph.sh |  1 +\n t/t5403-post-checkout-hook.sh              |  1 +\n t/t5405-send-pack-rewind.sh                |  1 +\n t/t5406-remote-rejects.sh                  |  1 +\n t/t5502-quickfetch.sh                      |  1 +\n t/t5504-fetch-receive-strict.sh            |  1 +\n t/t5507-remote-environment.sh              |  2 ++\n t/t5522-pull-symlink.sh                    |  1 +\n t/t5523-push-upstream.sh                   |  1 +\n t/t5527-fetch-odd-refs.sh                  |  1 +\n t/t5529-push-errors.sh                     |  2 ++\n t/t5546-receive-limits.sh                  |  2 ++\n t/t5547-push-quarantine.sh                 |  2 ++\n t/t5604-clone-reference.sh                 |  1 +\n t/t5606-clone-options.sh                   |  1 +\n t/t5613-info-alternate.sh                  |  2 ++\n t/t5705-session-id-in-capabilities.sh      |  1 +\n t/t5810-proto-disable-local.sh             |  2 ++\n t/t5813-proto-disable-ssh.sh               |  2 ++\n t/t6011-rev-list-with-bad-commit.sh        |  1 +\n t/t6014-rev-list-all.sh                    |  1 +\n t/t6021-rev-list-exclude-hidden.sh         |  1 +\n t/t6439-merge-co-error-msgs.sh             |  1 +\n t/t7105-reset-patch.sh                     |  2 ++\n t/t7106-reset-unborn-branch.sh             |  2 ++\n t/t7107-reset-pathspec-file.sh             |  1 +\n t/t7301-clean-interactive.sh               |  1 +\n t/t7403-submodule-sync.sh                  |  1 +\n t/t7409-submodule-detached-work-tree.sh    |  1 +\n t/t7416-submodule-dash-url.sh              |  2 ++\n t/t7450-bad-git-dotfiles.sh                |  2 ++\n t/t7701-repack-unpack-unreachable.sh       |  1 +\n 69 files changed, 158 insertions(+), 56 deletions(-)\n\nRange-diff against v1:\n 1:  84393ca3139 <  -:  ----------- t6021: mark as passing with SANITIZE=leak\n 2:  2ad81be0d7a !  1:  3de29c6d75f tests: mark tests as passing with SANITIZE=leak\n    @@ Metadata\n      ## Commit message ##\n         tests: mark tests as passing with SANITIZE=leak\n     \n    -    When the \"ab/various-leak-fixes\" topic was merged in [1] only\n    -    t6021 (which was fixed in the preceding commit) would fail if the\n    -    tests were run in the \"GIT_TEST_PASSING_SANITIZE_LEAK=check\" mode,\n    -    i.e. to check whether we marked all leak-free tests with\n    -    \"TEST_PASSES_SANITIZE_LEAK=true\".\n    +    When the \"ab/various-leak-fixes\" topic was merged in [1] only t6021\n    +    would fail if the tests were run in the\n    +    \"GIT_TEST_PASSING_SANITIZE_LEAK=check\" mode, i.e. to check whether we\n    +    marked all leak-free tests with \"TEST_PASSES_SANITIZE_LEAK=true\".\n     \n         Since then we've had various tests starting to pass under\n         SANITIZE=leak. Let's mark those as passing, this is when they started\n    @@ t/t6014-rev-list-all.sh\n      \n      \n     \n    + ## t/t6021-rev-list-exclude-hidden.sh ##\n    +@@\n    + \n    + test_description='git rev-list --exclude-hidden test'\n    + \n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + \n    + test_expect_success 'setup' '\n    +\n      ## t/t7403-submodule-sync.sh ##\n     @@ t/t7403-submodule-sync.sh: These tests exercise the \"git submodule sync\" subcommand.\n      GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n 3:  a8b373ddef9 =  2:  5036712391d bundle.c: don't leak the \"args\" in the \"struct child_process\"\n 4:  5be87f9720c !  3:  a840a1cb330 commit-graph: use free() instead of UNLEAK()\n    @@ Commit message\n         commit-graph: use free() instead of UNLEAK()\n     \n         In 0bfb48e6723 (builtin/commit-graph.c: UNLEAK variables, 2018-10-03)\n    -    this was made to UNLEAK(), but we can just as easily free() the memory\n    -    instead.\n    +    this was made to UNLEAK(), but we can just as easily invoke the\n    +    free_commit_graph() function added in c3756d5b7fc (commit-graph: add\n    +    free_commit_graph, 2018-07-11) instead.\n     \n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n    @@ builtin/commit-graph.c: static int graph_verify(int argc, const char **argv, con\n     -\tUNLEAK(graph);\n     -\treturn verify_commit_graph(the_repository, graph, flags);\n     +\tret = verify_commit_graph(the_repository, graph, flags);\n    -+\tfree(graph);\n    ++\tfree_commit_graph(graph);\n     +\treturn ret;\n      }\n      \n 5:  49e6714939d =  4:  c05620cef49 clone: use free() instead of UNLEAK()\n 8:  21670099c84 !  5:  62af6557760 reset: fix cmd_reset() leaks with a clear_pathspec() call\n    @@ Metadata\n     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## Commit message ##\n    -    reset: fix cmd_reset() leaks with a clear_pathspec() call\n    +    various: add missing clear_pathspec(), fix leaks\n     \n    -    Add clear_pathspec() calls to cmd_reset(), including to the codepaths\n    -    where we'd return early.\n    +    Fix memory leaks resulting from a missing clear_pathspec().\n    +\n    +    - archive.c: Plug a leak in the \"struct archiver_args\", and\n    +      clear_pathspec() the \"pathspec\" member that the \"parse_pathspec_arg()\"\n    +      call in this function populates.\n    +\n    +    - builtin/clean.c: Fix a memory leak that's been with us since\n    +      893d839970c (clean: convert to use parse_pathspec, 2013-07-14).\n    +\n    +    - builtin/reset.c: Add clear_pathspec() calls to cmd_reset(),\n    +      including to the codepaths where we'd return early.\n    +\n    +    - builtin/stash.c: Call clear_pathspec() on the pathspec initialized\n    +      in push_stash().\n     \n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n    + ## archive.c ##\n    +@@ archive.c: int write_archive(int argc, const char **argv, const char *prefix,\n    + \n    + \tstring_list_clear_func(&args.extra_files, extra_file_info_clear);\n    + \tfree(args.refname);\n    ++\tclear_pathspec(&args.pathspec);\n    + \n    + \treturn rc;\n    + }\n    +\n    + ## builtin/clean.c ##\n    +@@ builtin/clean.c: int cmd_clean(int argc, const char **argv, const char *prefix)\n    + \tstrbuf_release(&buf);\n    + \tstring_list_clear(&del_list, 0);\n    + \tstring_list_clear(&exclude_list, 0);\n    ++\tclear_pathspec(&pathspec);\n    + \treturn (errors != 0);\n    + }\n    +\n      ## builtin/reset.c ##\n     @@ builtin/reset.c: int cmd_reset(int argc, const char **argv, const char *prefix)\n      \t\tif (reset_type != NONE)\n    @@ builtin/reset.c: int cmd_reset(int argc, const char **argv, const char *prefix)\n      \treturn update_ref_status;\n      }\n     \n    + ## builtin/stash.c ##\n    +@@ builtin/stash.c: static int push_stash(int argc, const char **argv, const char *prefix,\n    + \t\tOPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),\n    + \t\tOPT_END()\n    + \t};\n    ++\tint ret;\n    + \n    + \tif (argc) {\n    + \t\tforce_assume = !strcmp(argv[0], \"-p\");\n    +@@ builtin/stash.c: static int push_stash(int argc, const char **argv, const char *prefix,\n    + \t\tdie(_(\"the option '%s' requires '%s'\"), \"--pathspec-file-nul\", \"--pathspec-from-file\");\n    + \t}\n    + \n    +-\treturn do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n    +-\t\t\t     include_untracked, only_staged);\n    ++\tret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n    ++\t\t\t    include_untracked, only_staged);\n    ++\tclear_pathspec(&ps);\n    ++\treturn ret;\n    + }\n    + \n    + static int push_stash_unassumed(int argc, const char **argv, const char *prefix)\n    +\n    + ## t/t5001-archive-attr.sh ##\n    +@@\n    + test_description='git archive attribute tests'\n    + \n    + TEST_CREATE_REPO_NO_TEMPLATE=1\n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + \n    + SUBSTFORMAT='%H (%h)%n'\n    +\n    + ## t/t5004-archive-corner-cases.sh ##\n    +@@\n    + #!/bin/sh\n    + \n    + test_description='test corner cases of git-archive'\n    ++\n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + \n    + # the 10knuls.tar file is used to test for an empty git generated tar\n    +\n      ## t/t7105-reset-patch.sh ##\n     @@\n      #!/bin/sh\n    @@ t/t7107-reset-pathspec-file.sh\n      . ./test-lib.sh\n      \n      test_tick\n    +\n    + ## t/t7301-clean-interactive.sh ##\n    +@@\n    + \n    + test_description='git clean -i basic tests'\n    + \n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + . \"$TEST_DIRECTORY\"/lib-terminal.sh\n    + \n 9:  77fcdeb9284 !  6:  7cea3da9fae name-rev: don't xstrdup() an already dup'd string\n    @@ Commit message\n         we'd then xstrdup() again, leaking memory. See [1] and [2] for how\n         this leak came about.\n     \n    +    We could xstrdup() only if \"shorten_unambiguous\" wasn't true, but\n    +    let's instead inline this code, so that information on whether we need\n    +    to xstrdup() is contained within add_to_tip_table().\n    +\n         1. 98c5c4ad015 (name-rev: allow to specify a subpath for --refs\n            option, 2013-06-18)\n         2. b23e0b9353e (name-rev: allow converting the exact object name at\n    @@ Commit message\n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## builtin/name-rev.c ##\n    +@@ builtin/name-rev.c: static int subpath_matches(const char *path, const char *filter)\n    + \treturn -1;\n    + }\n    + \n    +-static const char *name_ref_abbrev(const char *refname, int shorten_unambiguous)\n    +-{\n    +-\tif (shorten_unambiguous)\n    +-\t\trefname = shorten_unambiguous_ref(refname, 0);\n    +-\telse if (skip_prefix(refname, \"refs/heads/\", &refname))\n    +-\t\t; /* refname already advanced */\n    +-\telse\n    +-\t\tskip_prefix(refname, \"refs/\", &refname);\n    +-\treturn refname;\n    +-}\n    +-\n    + struct name_ref_data {\n    + \tint tags_only;\n    + \tint name_only;\n     @@ builtin/name-rev.c: static void add_to_tip_table(const struct object_id *oid, const char *refname,\n    + \t\t\t     int shorten_unambiguous, struct commit *commit,\n    + \t\t\t     timestamp_t taggerdate, int from_tag, int deref)\n    + {\n    +-\trefname = name_ref_abbrev(refname, shorten_unambiguous);\n    ++\tchar *short_refname = NULL;\n    ++\n    ++\tif (shorten_unambiguous)\n    ++\t\tshort_refname = shorten_unambiguous_ref(refname, 0);\n    ++\telse if (skip_prefix(refname, \"refs/heads/\", &refname))\n    ++\t\t; /* refname already advanced */\n    ++\telse\n    ++\t\tskip_prefix(refname, \"refs/\", &refname);\n      \n      \tALLOC_GROW(tip_table.table, tip_table.nr + 1, tip_table.alloc);\n      \toidcpy(&tip_table.table[tip_table.nr].oid, oid);\n     -\ttip_table.table[tip_table.nr].refname = xstrdup(refname);\n    -+\ttip_table.table[tip_table.nr].refname = shorten_unambiguous ? refname :\n    -+\t\txstrdup(refname);\n    ++\ttip_table.table[tip_table.nr].refname = short_refname ?\n    ++\t\tshort_refname : xstrdup(refname);\n      \ttip_table.table[tip_table.nr].commit = commit;\n      \ttip_table.table[tip_table.nr].taggerdate = taggerdate;\n      \ttip_table.table[tip_table.nr].from_tag = from_tag;\n10:  81555cce790 =  7:  b5978d75c6a repack: fix leaks on error with \"goto cleanup\"\n11:  ee05254eb6a =  8:  468615570f4 worktree: fix a trivial leak in prune_worktrees()\n 7:  e5a0134d1bb !  9:  8c5c964d872 stash: fix a \"struct pathspec\" leak\n    @@ Metadata\n     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## Commit message ##\n    -    stash: fix a \"struct pathspec\" leak\n    +    http-backend.c: fix \"dir\" and \"cmd_arg\" leaks in cmd_main()\n     \n    -    Call clear_pathspec() on the pathspec initialized in\n    -    push_stash(). Initializing that structure in this way is already done\n    -    by a few other callers, and now we have:\n    +    Free the \"dir\" variable after we're done with it. Before\n    +    917adc03608 (http-backend: add GIT_PROJECT_ROOT environment var,\n    +    2009-10-30) there was no leak here, as we'd get it via getenv(), but\n    +    since 917adc03608 we've xstrdup()'d it (or the equivalent), so we need\n    +    to free() it.\n     \n    -            $ git grep -e 'struct pathspec.* = { 0 }' -e memset.pathspec\n    -            add-interactive.c:              struct pathspec ps_selected = { 0 };\n    -            builtin/sparse-checkout.c:              struct pathspec p = { 0 };\n    -            builtin/stash.c:        struct pathspec ps = { 0 };\n    -            pathspec.c:     memset(pathspec, 0, sizeof(*pathspec));\n    -            wt-status.c:                    struct pathspec ps = { 0 };\n    +    We also need to free the \"cmd_arg\" variable, which has been leaked\n    +    ever since it was added in 2f4038ab337 (Git-aware CGI to provide dumb\n    +    HTTP transport, 2009-10-30).\n     \n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n    - ## builtin/stash.c ##\n    -@@ builtin/stash.c: static int push_stash(int argc, const char **argv, const char *prefix,\n    - \tint pathspec_file_nul = 0;\n    - \tconst char *stash_msg = NULL;\n    - \tconst char *pathspec_from_file = NULL;\n    --\tstruct pathspec ps;\n    -+\tstruct pathspec ps = { 0 };\n    - \tstruct option options[] = {\n    - \t\tOPT_BOOL('k', \"keep-index\", &keep_index,\n    - \t\t\t N_(\"keep index\")),\n    -@@ builtin/stash.c: static int push_stash(int argc, const char **argv, const char *prefix,\n    - \t\tOPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),\n    - \t\tOPT_END()\n    - \t};\n    -+\tint ret;\n    + ## http-backend.c ##\n    +@@ http-backend.c: int cmd_main(int argc, const char **argv)\n    + \tif (!getenv(\"GIT_HTTP_EXPORT_ALL\") &&\n    + \t    access(\"git-daemon-export-ok\", F_OK) )\n    + \t\tnot_found(&hdr, \"Repository not exported: '%s'\", dir);\n    ++\tfree(dir);\n      \n    - \tif (argc) {\n    - \t\tforce_assume = !strcmp(argv[0], \"-p\");\n    -@@ builtin/stash.c: static int push_stash(int argc, const char **argv, const char *prefix,\n    - \t\tdie(_(\"the option '%s' requires '%s'\"), \"--pathspec-file-nul\", \"--pathspec-from-file\");\n    - \t}\n    + \thttp_config();\n    + \tmax_request_buffer = git_env_ulong(\"GIT_HTTP_MAX_REQUEST_BUFFER\",\n    +@@ http-backend.c: int cmd_main(int argc, const char **argv)\n    + \t\tsetenv(GIT_PROTOCOL_ENVIRONMENT, proto_header, 0);\n      \n    --\treturn do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n    --\t\t\t     include_untracked, only_staged);\n    -+\tret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n    -+\t\t\t    include_untracked, only_staged);\n    -+\tclear_pathspec(&ps);\n    -+\treturn ret;\n    + \tcmd->imp(&hdr, cmd_arg);\n    ++\tfree(cmd_arg);\n    + \treturn 0;\n      }\n    - \n    - static int push_stash_unassumed(int argc, const char **argv, const char *prefix)\n12:  9be5b0c7836 = 10:  fd34c4817f4 http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()\n13:  78f12259ac5 = 11:  f7005f32cc0 commit-graph: fix a parse_options_concat() leak\n14:  9df41b090b4 = 12:  bf0e9bc5fa6 show-branch: free() allocated \"head\" before return\n15:  8deeee4278d ! 13:  b157092e8d0 builtin/merge.c: always free \"struct strbuf msg\"\n    @@ Commit message\n         builtin/merge.c: always free \"struct strbuf msg\"\n     \n         Follow-up 465028e0e25 (merge: add missing strbuf_release(),\n    -    2021-10-07) and free \"&msg\" also when we'd \"goto done\" from the scope\n    -    it's allocated in.\n    +    2021-10-07) and address the \"msg\" memory leak in this block. We could\n    +    free \"&msg\" before the \"goto done\" here, but even better is to avoid\n    +    allocating it in the first place.\n     \n    +    By repeating the \"Fast-forward\" string here we can avoid using a\n    +    \"struct strbuf\" altogether.\n    +\n    +    Suggested-by: René Scharfe <l.s.r@web.de>\n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## builtin/merge.c ##\n     @@ builtin/merge.c: int cmd_merge(int argc, const char **argv, const char *prefix)\n    + \t\t\t!common->next &&\n    + \t\t\toideq(&common->item->object.oid, &head_commit->object.oid)) {\n    + \t\t/* Again the most common case of merging one remote. */\n    +-\t\tstruct strbuf msg = STRBUF_INIT;\n    ++\t\tconst char *msg = have_message ?\n    ++\t\t\t\"Fast-forward (no commit created; -m option ignored)\" :\n    ++\t\t\t\"Fast-forward\";\n    + \t\tstruct commit *commit;\n    + \n    + \t\tif (verbosity >= 0) {\n    +@@ builtin/merge.c: int cmd_merge(int argc, const char **argv, const char *prefix)\n    + \t\t\t       find_unique_abbrev(&remoteheads->item->object.oid,\n    + \t\t\t\t\t\t  DEFAULT_ABBREV));\n    + \t\t}\n    +-\t\tstrbuf_addstr(&msg, \"Fast-forward\");\n    +-\t\tif (have_message)\n    +-\t\t\tstrbuf_addstr(&msg,\n    +-\t\t\t\t\" (no commit created; -m option ignored)\");\n      \t\tcommit = remoteheads->item;\n      \t\tif (!commit) {\n      \t\t\tret = 1;\n    -+\t\t\tstrbuf_release(&msg);\n    - \t\t\tgoto done;\n    - \t\t}\n    - \n     @@ builtin/merge.c: int cmd_merge(int argc, const char **argv, const char *prefix)\n    - \t\t\t\t\t  overwrite_ignore)) {\n    - \t\t\tapply_autostash(git_path_merge_autostash(the_repository));\n    - \t\t\tret = 1;\n    -+\t\t\tstrbuf_release(&msg);\n      \t\t\tgoto done;\n      \t\t}\n      \n    +-\t\tfinish(head_commit, remoteheads, &commit->object.oid, msg.buf);\n    ++\t\tfinish(head_commit, remoteheads, &commit->object.oid, msg);\n    + \t\tremove_merge_branch_state(the_repository);\n    +-\t\tstrbuf_release(&msg);\n    + \t\tgoto done;\n    + \t} else if (!remoteheads->next && common->next)\n    + \t\t;\n    +\n    + ## t/t6439-merge-co-error-msgs.sh ##\n    +@@ t/t6439-merge-co-error-msgs.sh: test_description='unpack-trees error messages'\n    + GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n    + export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n    + \n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + \n    + \n16:  95d59b914d0 ! 14:  bdd2bc9a956 builtin/merge.c: free \"&buf\" on \"Your local changes...\" error\n    @@ builtin/merge.c: int cmd_merge(int argc, const char **argv, const char *prefix)\n      \t\t\t}\n      \n      \t\t\t/* See if it is really trivial. */\n    -\n    - ## t/t6439-merge-co-error-msgs.sh ##\n    -@@ t/t6439-merge-co-error-msgs.sh: test_description='unpack-trees error messages'\n    - GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n    - export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n    - \n    -+TEST_PASSES_SANITIZE_LEAK=true\n    - . ./test-lib.sh\n    - \n    - \n17:  ae2f4931315 = 15:  d5210017cab connected.c: free(new_pack) in check_connected()\n18:  aa4df0e1b5c ! 16:  2016b4ddd0b object-file.c: free the \"t.tag\" in check_tag()\n    @@ Metadata\n     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## Commit message ##\n    -    object-file.c: free the \"t.tag\" in check_tag()\n    +    object-file.c: release the \"tag\" in check_tag()\n     \n         Fix a memory leak that's been with us ever since c879daa2372 (Make\n         hash-object more robust against malformed objects, 2011-02-05). With\n    @@ Commit message\n         tags into a throwaway variable on the stack, but weren't freeing the\n         \"item->tag\" we might malloc() when doing so.\n     \n    +    The clearing that release_tag_memory() does for us is redundant here,\n    +    but let's use it as-is anyway. It only has one other existing caller,\n    +    which does need the tag to be cleared.\n    +\n         Mark the tests that now pass in their entirety as passing under\n         \"SANITIZE=leak\", which means we'll test them as part of the\n         \"linux-leaks\" CI job.\n    @@ object-file.c: static void check_tag(const void *buf, size_t size)\n      \tmemset(&t, 0, sizeof(t));\n      \tif (parse_tag_buffer(the_repository, &t, buf, size))\n      \t\tdie(_(\"corrupt tag\"));\n    -+\tfree(t.tag);\n    ++\trelease_tag_memory(&t);\n      }\n      \n      static int index_mem(struct index_state *istate,\n20:  8ecc68c3e93 ! 17:  fa2e8a7d297 grep API: plug memory leaks by freeing \"header_list\"\n    @@ Metadata\n     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## Commit message ##\n    -    grep API: plug memory leaks by freeing \"header_list\"\n    +    grep.c: refactor free_grep_patterns()\n     \n    -    When the \"header_list\" struct member was added in [1] it wasn't made\n    -    to free the list using loop added for the adjacent \"pattern_list\"\n    -    member, see [2] for when we started freeing it.\n    +    Refactor the free_grep_patterns() function to split out the freeing of\n    +    the \"struct grep_pat\" it contains, right now we're only freeing the\n    +    \"pattern_list\", but we should be freeing another member of the same\n    +    type, which we'll do in the subsequent commit.\n     \n    -    Let's start doing o by splitting up the loop in free_grep_patterns()\n    -    into a utility function. This makes e.g. this command leak-free when\n    -    run on git.git:\n    +    Let's also replace the \"return\" if we don't have an\n    +    \"opt->pattern_expression\" with a conditional call of\n    +    free_pattern_expr().\n     \n    -            ./git -P log -1 --color=always --author=A origin/master\n    +    Before db84376f981 (grep.c: remove \"extended\" in favor of\n    +    \"pattern_expression\", fix segfault, 2022-10-11) the pattern here was:\n     \n    -    1. 80235ba79ef (\"log --author=me --grep=it\" should find intersection,\n    -       not union, 2010-01-17)\n    -    2. b48fb5b6a95 (grep: free expressions and patterns when done.,\n    -       2006-09-27)\n    +            if (!x)\n    +                    return;\n    +            free(y);\n    +\n    +    But after the cleanup in db84376f981 (which was a narrow segfault fix,\n    +    and thus avoided refactoring this) we ended up with:\n    +\n    +            if (!x)\n    +                    return;\n    +            free(x);\n    +\n    +    Let's instead do:\n    +\n    +            if (x)\n    +                    free(x);\n    +\n    +    This doesn't matter for the subsequent change, but as we're\n    +    refactoring this function let's make it easier to reason about, and to\n    +    extend in the future, i.e. if we start to free free() members that\n    +    come after \"pattern_expression\" in the \"struct grep_opt\".\n     \n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n    @@ grep.c: void free_grep_patterns(struct grep_opt *opt)\n      \t\tfree(p);\n      \t}\n     +}\n    -+\n    + \n    +-\tif (!opt->pattern_expression)\n    +-\t\treturn;\n    +-\tfree_pattern_expr(opt->pattern_expression);\n     +void free_grep_patterns(struct grep_opt *opt)\n     +{\n     +\tfree_grep_pat(opt->pattern_list);\n    -+\tfree_grep_pat(opt->header_list);\n    ++\n    ++\tif (opt->pattern_expression)\n    ++\t\tfree_pattern_expr(opt->pattern_expression);\n    + }\n      \n    - \tif (opt->pattern_expression)\n    - \t\tfree_pattern_expr(opt->pattern_expression);\n    + static const char *end_of_line(const char *cp, unsigned long *left)\n19:  7928470addb ! 18:  3fcf7054708 grep.c: make it easier to extend free_grep_patterns()\n    @@ Metadata\n     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## Commit message ##\n    -    grep.c: make it easier to extend free_grep_patterns()\n    +    grep API: plug memory leaks by freeing \"header_list\"\n     \n    -    Before db84376f981 (grep.c: remove \"extended\" in favor of\n    -    \"pattern_expression\", fix segfault, 2022-10-11) the pattern here was:\n    +    When the \"header_list\" struct member was added in [1] it wasn't made\n    +    to free the list using loop added for the adjacent \"pattern_list\"\n    +    member, see [2] for when we started freeing it.\n     \n    -            if (!x)\n    -                    return;\n    -            free(y);\n    +    This makes e.g. this command leak-free when run on git.git:\n     \n    -    But after the cleanup in db84376f981 (which was a narrow segfault fix,\n    -    and thus avoided refactoring this) we ended up with:\n    +            ./git -P log -1 --color=always --author=A origin/master\n     \n    -            if (!x)\n    -                    return;\n    -            free(x);\n    -\n    -    Let's instead do:\n    -\n    -            if (x)\n    -                    free(x);\n    -\n    -    This doesn't matter for now, but makes the free_grep_patterns() easier\n    -    to reason about, as we don't have to wonder why we're doing an early\n    -    \"return\" if and when we add free()-ing of any members that come after\n    -    \"pattern_expression\" in the \"struct grep_opt\".\n    +    1. 80235ba79ef (\"log --author=me --grep=it\" should find intersection,\n    +       not union, 2010-01-17)\n    +    2. b48fb5b6a95 (grep: free expressions and patterns when done.,\n    +       2006-09-27)\n     \n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## grep.c ##\n    -@@ grep.c: void free_grep_patterns(struct grep_opt *opt)\n    - \t\tfree(p);\n    - \t}\n    - \n    --\tif (!opt->pattern_expression)\n    --\t\treturn;\n    --\tfree_pattern_expr(opt->pattern_expression);\n    -+\tif (opt->pattern_expression)\n    -+\t\tfree_pattern_expr(opt->pattern_expression);\n    - }\n    +@@ grep.c: static void free_grep_pat(struct grep_pat *pattern)\n    + void free_grep_patterns(struct grep_opt *opt)\n    + {\n    + \tfree_grep_pat(opt->pattern_list);\n    ++\tfree_grep_pat(opt->header_list);\n      \n    - static const char *end_of_line(const char *cp, unsigned long *left)\n    + \tif (opt->pattern_expression)\n    + \t\tfree_pattern_expr(opt->pattern_expression);\n 6:  bc45aee530c ! 19:  fa5d657312f archive.c: call clear_pathspec() in write_archive()\n    @@ Metadata\n     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## Commit message ##\n    -    archive.c: call clear_pathspec() in write_archive()\n    +    receive-pack: free() the \"ref_name\" in \"struct command\"\n     \n    -    Plug a leak in the \"struct archiver_args\", and clear_pathspec() the\n    -    \"pathspec\" member that the \"parse_pathspec_arg()\" call in this\n    -    function populates.\n    +    Fix a memory leak that's been with us since this code was introduced\n    +    in 575f497456e (Add first cut at \"git-receive-pack\", 2005-06-29), see\n    +    eb1af2df0b1 (git-receive-pack: start parsing ref update commands,\n    +    2005-06-29) for the later change that refactored the code to add the\n    +    \"ref_name\" member.\n     \n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n    - ## archive.c ##\n    -@@ archive.c: int write_archive(int argc, const char **argv, const char *prefix,\n    + ## builtin/receive-pack.c ##\n    +@@ builtin/receive-pack.c: static struct command **queue_command(struct command **tail,\n    + \treturn &cmd->next;\n    + }\n      \n    - \tstring_list_clear_func(&args.extra_files, extra_file_info_clear);\n    - \tfree(args.refname);\n    -+\tclear_pathspec(&args.pathspec);\n    ++static void free_commands(struct command *commands)\n    ++{\n    ++\twhile (commands) {\n    ++\t\tstruct command *next = commands->next;\n    ++\t\tfree(commands);\n    ++\t\tcommands = next;\n    ++\t}\n    ++}\n    ++\n    + static void queue_commands_from_cert(struct command **tail,\n    + \t\t\t\t     struct strbuf *push_cert)\n    + {\n    +@@ builtin/receive-pack.c: int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n    + \t\trun_receive_hook(commands, \"post-receive\", 1,\n    + \t\t\t\t &push_options);\n    + \t\trun_update_post_hook(commands);\n    ++\t\tfree_commands(commands);\n    + \t\tstring_list_clear(&push_options, 0);\n    + \t\tif (auto_gc) {\n    + \t\t\tstruct child_process proc = CHILD_PROCESS_INIT;\n    +\n    + ## t/t5405-send-pack-rewind.sh ##\n    +@@ t/t5405-send-pack-rewind.sh: test_description='forced push to replace commit we do not have'\n    + GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n    + export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n      \n    - \treturn rc;\n    - }\n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + \n    + test_expect_success setup '\n     \n    - ## t/t5001-archive-attr.sh ##\n    + ## t/t5406-remote-rejects.sh ##\n     @@\n    - test_description='git archive attribute tests'\n      \n    - TEST_CREATE_REPO_NO_TEMPLATE=1\n    + test_description='remote push rejects are reported by client'\n    + \n     +TEST_PASSES_SANITIZE_LEAK=true\n      . ./test-lib.sh\n      \n    - SUBSTFORMAT='%H (%h)%n'\n    + test_expect_success 'setup' '\n     \n    - ## t/t5004-archive-corner-cases.sh ##\n    + ## t/t5507-remote-environment.sh ##\n     @@\n      #!/bin/sh\n      \n    - test_description='test corner cases of git-archive'\n    + test_description='check environment showed to remote side of transports'\n     +\n     +TEST_PASSES_SANITIZE_LEAK=true\n      . ./test-lib.sh\n      \n    - # the 10knuls.tar file is used to test for an empty git generated tar\n    + test_expect_success 'set up \"remote\" push situation' '\n    +\n    + ## t/t5522-pull-symlink.sh ##\n    +@@\n    + \n    + test_description='pulling from symlinked subdir'\n    + \n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + \n    + # The scenario we are building:\n    +\n    + ## t/t5527-fetch-odd-refs.sh ##\n    +@@ t/t5527-fetch-odd-refs.sh: test_description='test fetching of oddly-named refs'\n    + GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n    + export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n    + \n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + \n    + # afterwards we will have:\n    +\n    + ## t/t5705-session-id-in-capabilities.sh ##\n    +@@\n    + \n    + test_description='session ID in capabilities'\n    + \n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + \n    + REPO=\"$(pwd)/repo\"\n -:  ----------- > 20:  e5af27134df push: free_refs() the \"local_refs\" in set_refspecs()\n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469645","messageId":"patch-v2-01.20-3de29c6d75f-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 01/20] tests: mark tests as passing with SANITIZE=leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:16Z","receivedAt":"2022-12-30T02:19:04Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the \"ab/various-leak-fixes\" topic was merged in [1] only t6021\nwould fail if the tests were run in the\n\"GIT_TEST_PASSING_SANITIZE_LEAK=check\" mode, i.e. to check whether we\nmarked all leak-free tests with \"TEST_PASSES_SANITIZE_LEAK=true\".\n\nSince then we've had various tests starting to pass under\nSANITIZE=leak. Let's mark those as passing, this is when they started\nto pass, narrowed down with \"git bisect\":\n\n- t5317-pack-objects-filter-objects.sh: In\n  faebba436e6 (list-objects-filter: plug pattern_list leak, 2022-12-01).\n\n- t3210-pack-refs.sh, t5613-info-alternate.sh,\n  t7403-submodule-sync.sh: In 189e97bc4ba (diff: remove parseopts member\n  from struct diff_options, 2022-12-01).\n\n- t1408-packed-refs.sh: In ab91f6b7c42 (Merge branch\n  'rs/diff-parseopts', 2022-12-19).\n\n- t0023-crlf-am.sh, t4152-am-subjects.sh, t4254-am-corrupt.sh,\n  t4256-am-format-flowed.sh, t4257-am-interactive.sh,\n  t5403-post-checkout-hook.sh: In a658e881c13 (am: don't pass strvec to\n  apply_parse_options(), 2022-12-13)\n\n- t1301-shared-repo.sh, t1302-repo-version.sh: In b07a819c05f (reflog:\n  clear leftovers in reflog_expiry_cleanup(), 2022-12-13).\n\n- t1304-default-acl.sh, t1410-reflog.sh,\n  t5330-no-lazy-fetch-with-commit-graph.sh, t5502-quickfetch.sh,\n  t5604-clone-reference.sh, t6014-rev-list-all.sh,\n  t7701-repack-unpack-unreachable.sh: In b0c61be3209 (Merge branch\n  'rs/reflog-expiry-cleanup', 2022-12-26)\n\n1. 9ea1378d046 (Merge branch 'ab/various-leak-fixes', 2022-12-14)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n t/t0023-crlf-am.sh                         | 1 +\n t/t1301-shared-repo.sh                     | 1 +\n t/t1302-repo-version.sh                    | 1 +\n t/t1304-default-acl.sh                     | 1 +\n t/t1408-packed-refs.sh                     | 1 +\n t/t1410-reflog.sh                          | 1 +\n t/t3210-pack-refs.sh                       | 1 +\n t/t4152-am-subjects.sh                     | 2 ++\n t/t4254-am-corrupt.sh                      | 2 ++\n t/t4256-am-format-flowed.sh                | 1 +\n t/t4257-am-interactive.sh                  | 2 ++\n t/t5317-pack-objects-filter-objects.sh     | 1 +\n t/t5330-no-lazy-fetch-with-commit-graph.sh | 1 +\n t/t5403-post-checkout-hook.sh              | 1 +\n t/t5502-quickfetch.sh                      | 1 +\n t/t5604-clone-reference.sh                 | 1 +\n t/t5613-info-alternate.sh                  | 2 ++\n t/t6014-rev-list-all.sh                    | 1 +\n t/t6021-rev-list-exclude-hidden.sh         | 1 +\n t/t7403-submodule-sync.sh                  | 1 +\n t/t7701-repack-unpack-unreachable.sh       | 1 +\n 21 files changed, 25 insertions(+)\n\ndiff --git a/t/t0023-crlf-am.sh b/t/t0023-crlf-am.sh\nindex f9bbb91f64e..575805513a3 100755\n--- a/t/t0023-crlf-am.sh\n+++ b/t/t0023-crlf-am.sh\n@@ -2,6 +2,7 @@\n \n test_description='Test am with auto.crlf'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n cat >patchfile <<\\EOF\ndiff --git a/t/t1301-shared-repo.sh b/t/t1301-shared-repo.sh\nindex 93a2f91f8a5..a1251f65100 100755\n--- a/t/t1301-shared-repo.sh\n+++ b/t/t1301-shared-repo.sh\n@@ -8,6 +8,7 @@ test_description='Test shared repository initialization'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Remove a default ACL from the test dir if possible.\ndiff --git a/t/t1302-repo-version.sh b/t/t1302-repo-version.sh\nindex 0acabb6d11b..83c327ac2c8 100755\n--- a/t/t1302-repo-version.sh\n+++ b/t/t1302-repo-version.sh\n@@ -5,6 +5,7 @@\n \n test_description='Test repository version check'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh\nindex c69ae41306c..31b89dd9693 100755\n--- a/t/t1304-default-acl.sh\n+++ b/t/t1304-default-acl.sh\n@@ -9,6 +9,7 @@ test_description='Test repository with default ACL'\n # => this must come before . ./test-lib.sh\n umask 077\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # We need an arbitrary other user give permission to using ACLs. root\ndiff --git a/t/t1408-packed-refs.sh b/t/t1408-packed-refs.sh\nindex 41ba1f1d7fc..9469c79a585 100755\n--- a/t/t1408-packed-refs.sh\n+++ b/t/t1408-packed-refs.sh\n@@ -5,6 +5,7 @@ test_description='packed-refs entries are covered by loose refs'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh\nindex aa59954f6c5..6c45965b1e4 100755\n--- a/t/t1410-reflog.sh\n+++ b/t/t1410-reflog.sh\n@@ -7,6 +7,7 @@ test_description='Test prune and reflog expiration'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n check_have () {\ndiff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh\nindex 577f32dc71f..07a0ff93def 100755\n--- a/t/t3210-pack-refs.sh\n+++ b/t/t3210-pack-refs.sh\n@@ -12,6 +12,7 @@ semantic is still the same.\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'enable reflogs' '\ndiff --git a/t/t4152-am-subjects.sh b/t/t4152-am-subjects.sh\nindex 4c68245acad..9f2edba1f83 100755\n--- a/t/t4152-am-subjects.sh\n+++ b/t/t4152-am-subjects.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test subject preservation with format-patch | am'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n make_patches() {\ndiff --git a/t/t4254-am-corrupt.sh b/t/t4254-am-corrupt.sh\nindex 54be7da1611..45f1d4f95e5 100755\n--- a/t/t4254-am-corrupt.sh\n+++ b/t/t4254-am-corrupt.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git am with corrupt input'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n make_mbox_with_nul () {\ndiff --git a/t/t4256-am-format-flowed.sh b/t/t4256-am-format-flowed.sh\nindex 2369c4e17ad..1015273bc82 100755\n--- a/t/t4256-am-format-flowed.sh\n+++ b/t/t4256-am-format-flowed.sh\n@@ -2,6 +2,7 @@\n \n test_description='test format=flowed support of git am'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t4257-am-interactive.sh b/t/t4257-am-interactive.sh\nindex aed8f4de3d6..f26d7fd2dbd 100755\n--- a/t/t4257-am-interactive.sh\n+++ b/t/t4257-am-interactive.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='am --interactive tests'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'set up patches to apply' '\ndiff --git a/t/t5317-pack-objects-filter-objects.sh b/t/t5317-pack-objects-filter-objects.sh\nindex 5b707d911b5..b26d476c646 100755\n--- a/t/t5317-pack-objects-filter-objects.sh\n+++ b/t/t5317-pack-objects-filter-objects.sh\n@@ -5,6 +5,7 @@ test_description='git pack-objects using object filtering'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Test blob:none filter.\ndiff --git a/t/t5330-no-lazy-fetch-with-commit-graph.sh b/t/t5330-no-lazy-fetch-with-commit-graph.sh\nindex 2cc7fd7a476..5eb28f0512d 100755\n--- a/t/t5330-no-lazy-fetch-with-commit-graph.sh\n+++ b/t/t5330-no-lazy-fetch-with-commit-graph.sh\n@@ -2,6 +2,7 @@\n \n test_description='test for no lazy fetch with the commit-graph'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup: prepare a repository with a commit' '\ndiff --git a/t/t5403-post-checkout-hook.sh b/t/t5403-post-checkout-hook.sh\nindex 978f240cdac..cfaae547398 100755\n--- a/t/t5403-post-checkout-hook.sh\n+++ b/t/t5403-post-checkout-hook.sh\n@@ -7,6 +7,7 @@ test_description='Test the post-checkout hook.'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5502-quickfetch.sh b/t/t5502-quickfetch.sh\nindex b160f8b7fb7..7b3ff21b984 100755\n--- a/t/t5502-quickfetch.sh\n+++ b/t/t5502-quickfetch.sh\n@@ -5,6 +5,7 @@ test_description='test quickfetch from local'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh\nindex 2734e37e880..dc86dea1333 100755\n--- a/t/t5604-clone-reference.sh\n+++ b/t/t5604-clone-reference.sh\n@@ -7,6 +7,7 @@ test_description='test clone --reference'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n base_dir=$(pwd)\ndiff --git a/t/t5613-info-alternate.sh b/t/t5613-info-alternate.sh\nindex 895f46bb911..7708cbafa98 100755\n--- a/t/t5613-info-alternate.sh\n+++ b/t/t5613-info-alternate.sh\n@@ -4,6 +4,8 @@\n #\n \n test_description='test transitive info/alternate entries'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'preparing first repository' '\ndiff --git a/t/t6014-rev-list-all.sh b/t/t6014-rev-list-all.sh\nindex c9bedd29cba..16b8bd1d090 100755\n--- a/t/t6014-rev-list-all.sh\n+++ b/t/t6014-rev-list-all.sh\n@@ -2,6 +2,7 @@\n \n test_description='--all includes detached HEADs'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n \ndiff --git a/t/t6021-rev-list-exclude-hidden.sh b/t/t6021-rev-list-exclude-hidden.sh\nindex 32b2b094138..11c50b7c0dd 100755\n--- a/t/t6021-rev-list-exclude-hidden.sh\n+++ b/t/t6021-rev-list-exclude-hidden.sh\n@@ -2,6 +2,7 @@\n \n test_description='git rev-list --exclude-hidden test'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh\nindex ea92ef52a5e..ff09443a0a4 100755\n--- a/t/t7403-submodule-sync.sh\n+++ b/t/t7403-submodule-sync.sh\n@@ -11,6 +11,7 @@ These tests exercise the \"git submodule sync\" subcommand.\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t7701-repack-unpack-unreachable.sh b/t/t7701-repack-unpack-unreachable.sh\nindex b7ac4f598a8..ebb267855fe 100755\n--- a/t/t7701-repack-unpack-unreachable.sh\n+++ b/t/t7701-repack-unpack-unreachable.sh\n@@ -5,6 +5,7 @@ test_description='git repack works correctly'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n fsha1=\n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469646","messageId":"patch-v2-03.20-a840a1cb330-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 03/20] commit-graph: use free() instead of UNLEAK()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:18Z","receivedAt":"2022-12-30T02:19:05Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"In 0bfb48e6723 (builtin/commit-graph.c: UNLEAK variables, 2018-10-03)\nthis was made to UNLEAK(), but we can just as easily invoke the\nfree_commit_graph() function added in c3756d5b7fc (commit-graph: add\nfree_commit_graph, 2018-07-11) instead.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/commit-graph.c | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/commit-graph.c b/builtin/commit-graph.c\nindex e8f77f535f3..0102ac8540e 100644\n--- a/builtin/commit-graph.c\n+++ b/builtin/commit-graph.c\n@@ -67,6 +67,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix)\n \tint fd;\n \tstruct stat st;\n \tint flags = 0;\n+\tint ret;\n \n \tstatic struct option builtin_commit_graph_verify_options[] = {\n \t\tOPT_BOOL(0, \"shallow\", &opts.shallow,\n@@ -111,8 +112,9 @@ static int graph_verify(int argc, const char **argv, const char *prefix)\n \tif (!graph)\n \t\treturn !!open_ok;\n \n-\tUNLEAK(graph);\n-\treturn verify_commit_graph(the_repository, graph, flags);\n+\tret = verify_commit_graph(the_repository, graph, flags);\n+\tfree_commit_graph(graph);\n+\treturn ret;\n }\n \n extern int read_replace_refs;\n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469647","messageId":"patch-v2-02.20-5036712391d-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 02/20] bundle.c: don't leak the \"args\" in the \"struct child_process\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:17Z","receivedAt":"2022-12-30T02:19:06Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a leak that's been here since 7366096de9d (bundle API: change\n\"flags\" to be \"extra_index_pack_args\", 2021-09-05), if can't verify\nthe bundle we didn't call child_process_clear() to clear the \"args\".\n\nBut rather than doing that let's verify the bundle before we start\npreparing the process we're going to spawn, if we get an error we\ndon't need to push anything to the \"args\".\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n bundle.c | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/bundle.c b/bundle.c\nindex 4ef7256aa11..9ebb10a8f72 100644\n--- a/bundle.c\n+++ b/bundle.c\n@@ -627,6 +627,10 @@ int unbundle(struct repository *r, struct bundle_header *header,\n \t     enum verify_bundle_flags flags)\n {\n \tstruct child_process ip = CHILD_PROCESS_INIT;\n+\n+\tif (verify_bundle(r, header, flags))\n+\t\treturn -1;\n+\n \tstrvec_pushl(&ip.args, \"index-pack\", \"--fix-thin\", \"--stdin\", NULL);\n \n \t/* If there is a filter, then we need to create the promisor pack. */\n@@ -638,8 +642,6 @@ int unbundle(struct repository *r, struct bundle_header *header,\n \t\tstrvec_clear(extra_index_pack_args);\n \t}\n \n-\tif (verify_bundle(r, header, flags))\n-\t\treturn -1;\n \tip.in = bundle_fd;\n \tip.no_stdout = 1;\n \tip.git_cmd = 1;\n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469648","messageId":"patch-v2-06.20-7cea3da9fae-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 06/20] name-rev: don't xstrdup() an already dup'd string","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:21Z","receivedAt":"2022-12-30T02:19:09Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When \"add_to_tip_table()\" is called with a non-zero\n\"shorten_unambiguous\" we always return an xstrdup()'d string, which\nwe'd then xstrdup() again, leaking memory. See [1] and [2] for how\nthis leak came about.\n\nWe could xstrdup() only if \"shorten_unambiguous\" wasn't true, but\nlet's instead inline this code, so that information on whether we need\nto xstrdup() is contained within add_to_tip_table().\n\n1. 98c5c4ad015 (name-rev: allow to specify a subpath for --refs\n   option, 2013-06-18)\n2. b23e0b9353e (name-rev: allow converting the exact object name at\n   the tip of a ref, 2013-07-07)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/name-rev.c | 23 ++++++++++-------------\n 1 file changed, 10 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin/name-rev.c b/builtin/name-rev.c\nindex 15535e914a6..49fae523694 100644\n--- a/builtin/name-rev.c\n+++ b/builtin/name-rev.c\n@@ -273,17 +273,6 @@ static int subpath_matches(const char *path, const char *filter)\n \treturn -1;\n }\n \n-static const char *name_ref_abbrev(const char *refname, int shorten_unambiguous)\n-{\n-\tif (shorten_unambiguous)\n-\t\trefname = shorten_unambiguous_ref(refname, 0);\n-\telse if (skip_prefix(refname, \"refs/heads/\", &refname))\n-\t\t; /* refname already advanced */\n-\telse\n-\t\tskip_prefix(refname, \"refs/\", &refname);\n-\treturn refname;\n-}\n-\n struct name_ref_data {\n \tint tags_only;\n \tint name_only;\n@@ -309,11 +298,19 @@ static void add_to_tip_table(const struct object_id *oid, const char *refname,\n \t\t\t     int shorten_unambiguous, struct commit *commit,\n \t\t\t     timestamp_t taggerdate, int from_tag, int deref)\n {\n-\trefname = name_ref_abbrev(refname, shorten_unambiguous);\n+\tchar *short_refname = NULL;\n+\n+\tif (shorten_unambiguous)\n+\t\tshort_refname = shorten_unambiguous_ref(refname, 0);\n+\telse if (skip_prefix(refname, \"refs/heads/\", &refname))\n+\t\t; /* refname already advanced */\n+\telse\n+\t\tskip_prefix(refname, \"refs/\", &refname);\n \n \tALLOC_GROW(tip_table.table, tip_table.nr + 1, tip_table.alloc);\n \toidcpy(&tip_table.table[tip_table.nr].oid, oid);\n-\ttip_table.table[tip_table.nr].refname = xstrdup(refname);\n+\ttip_table.table[tip_table.nr].refname = short_refname ?\n+\t\tshort_refname : xstrdup(refname);\n \ttip_table.table[tip_table.nr].commit = commit;\n \ttip_table.table[tip_table.nr].taggerdate = taggerdate;\n \ttip_table.table[tip_table.nr].from_tag = from_tag;\n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469649","messageId":"patch-v2-05.20-62af6557760-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 05/20] various: add missing clear_pathspec(), fix leaks","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:20Z","receivedAt":"2022-12-30T02:19:12Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix memory leaks resulting from a missing clear_pathspec().\n\n- archive.c: Plug a leak in the \"struct archiver_args\", and\n  clear_pathspec() the \"pathspec\" member that the \"parse_pathspec_arg()\"\n  call in this function populates.\n\n- builtin/clean.c: Fix a memory leak that's been with us since\n  893d839970c (clean: convert to use parse_pathspec, 2013-07-14).\n\n- builtin/reset.c: Add clear_pathspec() calls to cmd_reset(),\n  including to the codepaths where we'd return early.\n\n- builtin/stash.c: Call clear_pathspec() on the pathspec initialized\n  in push_stash().\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n archive.c                       |  1 +\n builtin/clean.c                 |  1 +\n builtin/reset.c                 | 11 ++++++++---\n builtin/stash.c                 |  7 +++++--\n t/t5001-archive-attr.sh         |  1 +\n t/t5004-archive-corner-cases.sh |  2 ++\n t/t7105-reset-patch.sh          |  2 ++\n t/t7106-reset-unborn-branch.sh  |  2 ++\n t/t7107-reset-pathspec-file.sh  |  1 +\n t/t7301-clean-interactive.sh    |  1 +\n 10 files changed, 24 insertions(+), 5 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex 941495f5d78..a2d813e50db 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -710,6 +710,7 @@ int write_archive(int argc, const char **argv, const char *prefix,\n \n \tstring_list_clear_func(&args.extra_files, extra_file_info_clear);\n \tfree(args.refname);\n+\tclear_pathspec(&args.pathspec);\n \n \treturn rc;\n }\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex b2701a28158..b15eab328b7 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -1092,5 +1092,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tstrbuf_release(&buf);\n \tstring_list_clear(&del_list, 0);\n \tstring_list_clear(&exclude_list, 0);\n+\tclear_pathspec(&pathspec);\n \treturn (errors != 0);\n }\ndiff --git a/builtin/reset.c b/builtin/reset.c\nindex fea20a9ba0b..e9c10618cd3 100644\n--- a/builtin/reset.c\n+++ b/builtin/reset.c\n@@ -390,7 +390,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \t\tif (reset_type != NONE)\n \t\t\tdie(_(\"options '%s' and '%s' cannot be used together\"), \"--patch\", \"--{hard,mixed,soft}\");\n \t\ttrace2_cmd_mode(\"patch-interactive\");\n-\t\treturn run_add_interactive(rev, \"--patch=reset\", &pathspec);\n+\t\tupdate_ref_status = run_add_interactive(rev, \"--patch=reset\", &pathspec);\n+\t\tgoto cleanup;\n \t}\n \n \t/* git reset tree [--] paths... can be used to\n@@ -439,8 +440,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \t\t\t\t       LOCK_DIE_ON_ERROR);\n \t\tif (reset_type == MIXED) {\n \t\t\tint flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;\n-\t\t\tif (read_from_tree(&pathspec, &oid, intent_to_add))\n-\t\t\t\treturn 1;\n+\t\t\tif (read_from_tree(&pathspec, &oid, intent_to_add)) {\n+\t\t\t\tupdate_ref_status = 1;\n+\t\t\t\tgoto cleanup;\n+\t\t\t}\n \t\t\tthe_index.updated_skipworktree = 1;\n \t\t\tif (!no_refresh && get_git_work_tree()) {\n \t\t\t\tuint64_t t_begin, t_delta_in_ms;\n@@ -488,5 +491,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \n \tdiscard_index(&the_index);\n \n+cleanup:\n+\tclear_pathspec(&pathspec);\n \treturn update_ref_status;\n }\ndiff --git a/builtin/stash.c b/builtin/stash.c\nindex bb0fd861434..45bffdf54bb 100644\n--- a/builtin/stash.c\n+++ b/builtin/stash.c\n@@ -1727,6 +1727,7 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n \t\tOPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),\n \t\tOPT_END()\n \t};\n+\tint ret;\n \n \tif (argc) {\n \t\tforce_assume = !strcmp(argv[0], \"-p\");\n@@ -1766,8 +1767,10 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n \t\tdie(_(\"the option '%s' requires '%s'\"), \"--pathspec-file-nul\", \"--pathspec-from-file\");\n \t}\n \n-\treturn do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n-\t\t\t     include_untracked, only_staged);\n+\tret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n+\t\t\t    include_untracked, only_staged);\n+\tclear_pathspec(&ps);\n+\treturn ret;\n }\n \n static int push_stash_unassumed(int argc, const char **argv, const char *prefix)\ndiff --git a/t/t5001-archive-attr.sh b/t/t5001-archive-attr.sh\nindex 2f6eef5e372..04d300eeda7 100755\n--- a/t/t5001-archive-attr.sh\n+++ b/t/t5001-archive-attr.sh\n@@ -3,6 +3,7 @@\n test_description='git archive attribute tests'\n \n TEST_CREATE_REPO_NO_TEMPLATE=1\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n SUBSTFORMAT='%H (%h)%n'\ndiff --git a/t/t5004-archive-corner-cases.sh b/t/t5004-archive-corner-cases.sh\nindex ae508e21623..9f2c6da80e8 100755\n--- a/t/t5004-archive-corner-cases.sh\n+++ b/t/t5004-archive-corner-cases.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test corner cases of git-archive'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # the 10knuls.tar file is used to test for an empty git generated tar\ndiff --git a/t/t7105-reset-patch.sh b/t/t7105-reset-patch.sh\nindex fc2a6cf5c7a..9b46da7aaa7 100755\n--- a/t/t7105-reset-patch.sh\n+++ b/t/t7105-reset-patch.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git reset --patch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./lib-patch-mode.sh\n \n test_expect_success PERL 'setup' '\ndiff --git a/t/t7106-reset-unborn-branch.sh b/t/t7106-reset-unborn-branch.sh\nindex ecb85c3b823..a0b67a0b843 100755\n--- a/t/t7106-reset-unborn-branch.sh\n+++ b/t/t7106-reset-unborn-branch.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git reset should work on unborn branch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7107-reset-pathspec-file.sh b/t/t7107-reset-pathspec-file.sh\nindex 523efbecde1..af5ea406db3 100755\n--- a/t/t7107-reset-pathspec-file.sh\n+++ b/t/t7107-reset-pathspec-file.sh\n@@ -2,6 +2,7 @@\n \n test_description='reset --pathspec-from-file'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_tick\ndiff --git a/t/t7301-clean-interactive.sh b/t/t7301-clean-interactive.sh\nindex a07e8b86de2..d82a3210a1d 100755\n--- a/t/t7301-clean-interactive.sh\n+++ b/t/t7301-clean-interactive.sh\n@@ -2,6 +2,7 @@\n \n test_description='git clean -i basic tests'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-terminal.sh\n \n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469650","messageId":"patch-v2-04.20-c05620cef49-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 04/20] clone: use free() instead of UNLEAK()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:19Z","receivedAt":"2022-12-30T02:19:14Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change an UNLEAK() added in 0c4542738e6 (clone: free or UNLEAK further\npointers when finished, 2021-03-14) to use a \"to_free\" pattern\ninstead. In this case the \"repo\" can be either this absolute_pathdup()\nvalue, or in the \"else if\" branch seen in the context the the\n\"argv[0]\" argument to \"main()\".\n\nWe can only free() the value in the former case, hence the \"to_free\"\npattern.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/clone.c | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex f518bb2dc1f..48156a4f2c2 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -892,6 +892,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tint is_bundle = 0, is_local;\n \tint reject_shallow = 0;\n \tconst char *repo_name, *repo, *work_tree, *git_dir;\n+\tchar *repo_to_free = NULL;\n \tchar *path = NULL, *dir, *display_repo = NULL;\n \tint dest_exists, real_dest_exists = 0;\n \tconst struct ref *refs, *remote_head;\n@@ -949,7 +950,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tpath = get_repo_path(repo_name, &is_bundle);\n \tif (path) {\n \t\tFREE_AND_NULL(path);\n-\t\trepo = absolute_pathdup(repo_name);\n+\t\trepo = repo_to_free = absolute_pathdup(repo_name);\n \t} else if (strchr(repo_name, ':')) {\n \t\trepo = repo_name;\n \t\tdisplay_repo = transport_anonymize_url(repo);\n@@ -1392,7 +1393,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tfree(unborn_head);\n \tfree(dir);\n \tfree(path);\n-\tUNLEAK(repo);\n+\tfree(repo_to_free);\n \tjunk_mode = JUNK_LEAVE_ALL;\n \n \ttransport_ls_refs_options_release(&transport_ls_refs_options);\n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469651","messageId":"patch-v2-09.20-8c5c964d872-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 09/20] http-backend.c: fix \"dir\" and \"cmd_arg\" leaks in cmd_main()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:24Z","receivedAt":"2022-12-30T02:19:16Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Free the \"dir\" variable after we're done with it. Before\n917adc03608 (http-backend: add GIT_PROJECT_ROOT environment var,\n2009-10-30) there was no leak here, as we'd get it via getenv(), but\nsince 917adc03608 we've xstrdup()'d it (or the equivalent), so we need\nto free() it.\n\nWe also need to free the \"cmd_arg\" variable, which has been leaked\never since it was added in 2f4038ab337 (Git-aware CGI to provide dumb\nHTTP transport, 2009-10-30).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n http-backend.c | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git a/http-backend.c b/http-backend.c\nindex 6eb3b2fe51c..67819d931ce 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -786,6 +786,7 @@ int cmd_main(int argc, const char **argv)\n \tif (!getenv(\"GIT_HTTP_EXPORT_ALL\") &&\n \t    access(\"git-daemon-export-ok\", F_OK) )\n \t\tnot_found(&hdr, \"Repository not exported: '%s'\", dir);\n+\tfree(dir);\n \n \thttp_config();\n \tmax_request_buffer = git_env_ulong(\"GIT_HTTP_MAX_REQUEST_BUFFER\",\n@@ -795,5 +796,6 @@ int cmd_main(int argc, const char **argv)\n \t\tsetenv(GIT_PROTOCOL_ENVIRONMENT, proto_header, 0);\n \n \tcmd->imp(&hdr, cmd_arg);\n+\tfree(cmd_arg);\n \treturn 0;\n }\n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469652","messageId":"patch-v2-08.20-468615570f4-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 08/20] worktree: fix a trivial leak in prune_worktrees()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:23Z","receivedAt":"2022-12-30T02:19:18Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"We were leaking both the \"struct strbuf\" in prune_worktrees(), as well\nas the \"path\" we got from should_prune_worktree(). Since these were\nthe only two uses of the \"struct string_list\" let's change it to a\n\"DUP\" and push these to it with \"string_list_append_nodup()\".\n\nFor the string_list_append_nodup() we could also string_list_append()\nthe main_path.buf, and then strbuf_release(&main_path) right away. But\ndoing it this way avoids an allocation, as we already have the \"struct\nstrbuf\" prepared for appending to \"kept\".\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/worktree.c         | 6 +++---\n t/t2401-worktree-prune.sh  | 1 +\n t/t2406-worktree-repair.sh | 1 +\n 3 files changed, 5 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex 591d659faea..865ce9be22b 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -173,7 +173,7 @@ static void prune_worktrees(void)\n {\n \tstruct strbuf reason = STRBUF_INIT;\n \tstruct strbuf main_path = STRBUF_INIT;\n-\tstruct string_list kept = STRING_LIST_INIT_NODUP;\n+\tstruct string_list kept = STRING_LIST_INIT_DUP;\n \tDIR *dir = opendir(git_path(\"worktrees\"));\n \tstruct dirent *d;\n \tif (!dir)\n@@ -184,14 +184,14 @@ static void prune_worktrees(void)\n \t\tif (should_prune_worktree(d->d_name, &reason, &path, expire))\n \t\t\tprune_worktree(d->d_name, reason.buf);\n \t\telse if (path)\n-\t\t\tstring_list_append(&kept, path)->util = xstrdup(d->d_name);\n+\t\t\tstring_list_append_nodup(&kept, path)->util = xstrdup(d->d_name);\n \t}\n \tclosedir(dir);\n \n \tstrbuf_add_absolute_path(&main_path, get_git_common_dir());\n \t/* massage main worktree absolute path to match 'gitdir' content */\n \tstrbuf_strip_suffix(&main_path, \"/.\");\n-\tstring_list_append(&kept, strbuf_detach(&main_path, NULL));\n+\tstring_list_append_nodup(&kept, strbuf_detach(&main_path, NULL));\n \tprune_dups(&kept);\n \tstring_list_clear(&kept, 1);\n \ndiff --git a/t/t2401-worktree-prune.sh b/t/t2401-worktree-prune.sh\nindex 3d28c7f06b2..568a47ec426 100755\n--- a/t/t2401-worktree-prune.sh\n+++ b/t/t2401-worktree-prune.sh\n@@ -5,6 +5,7 @@ test_description='prune $GIT_DIR/worktrees'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success initialize '\ndiff --git a/t/t2406-worktree-repair.sh b/t/t2406-worktree-repair.sh\nindex 5c44453e1c1..8970780efcc 100755\n--- a/t/t2406-worktree-repair.sh\n+++ b/t/t2406-worktree-repair.sh\n@@ -2,6 +2,7 @@\n \n test_description='test git worktree repair'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469653","messageId":"patch-v2-07.20-b5978d75c6a-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 07/20] repack: fix leaks on error with \"goto cleanup\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:22Z","receivedAt":"2022-12-30T02:19:20Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change cmd_repack() to \"goto cleanup\" rather than \"return ret\" on\nerror, when we returned we'd potentially skip cleaning up the\nstring_lists and other data we'd allocated in this function.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/repack.c                    | 13 +++++++------\n t/t6011-rev-list-with-bad-commit.sh |  1 +\n 2 files changed, 8 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/repack.c b/builtin/repack.c\nindex c1402ad038f..f6493795318 100644\n--- a/builtin/repack.c\n+++ b/builtin/repack.c\n@@ -948,7 +948,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \n \tret = start_command(&cmd);\n \tif (ret)\n-\t\treturn ret;\n+\t\tgoto cleanup;\n \n \tif (geometry) {\n \t\tFILE *in = xfdopen(cmd.in, \"w\");\n@@ -977,7 +977,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \tfclose(out);\n \tret = finish_command(&cmd);\n \tif (ret)\n-\t\treturn ret;\n+\t\tgoto cleanup;\n \n \tif (!names.nr && !po_args.quiet)\n \t\tprintf_ln(_(\"Nothing new to pack.\"));\n@@ -1007,7 +1007,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\t\t\t       &existing_nonkept_packs,\n \t\t\t\t       &existing_kept_packs);\n \t\tif (ret)\n-\t\t\treturn ret;\n+\t\t\tgoto cleanup;\n \n \t\tif (delete_redundant && expire_to) {\n \t\t\t/*\n@@ -1039,7 +1039,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\t\t\t\t       &existing_nonkept_packs,\n \t\t\t\t\t       &existing_kept_packs);\n \t\t\tif (ret)\n-\t\t\t\treturn ret;\n+\t\t\t\tgoto cleanup;\n \t\t}\n \t}\n \n@@ -1115,7 +1115,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\tstring_list_clear(&include, 0);\n \n \t\tif (ret)\n-\t\t\treturn ret;\n+\t\t\tgoto cleanup;\n \t}\n \n \treprepare_packed_git(the_repository);\n@@ -1172,10 +1172,11 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\twrite_midx_file(get_object_directory(), NULL, NULL, flags);\n \t}\n \n+cleanup:\n \tstring_list_clear(&names, 1);\n \tstring_list_clear(&existing_nonkept_packs, 0);\n \tstring_list_clear(&existing_kept_packs, 0);\n \tclear_pack_geometry(geometry);\n \n-\treturn 0;\n+\treturn ret;\n }\ndiff --git a/t/t6011-rev-list-with-bad-commit.sh b/t/t6011-rev-list-with-bad-commit.sh\nindex bad02cf5b83..b2e422cf0f7 100755\n--- a/t/t6011-rev-list-with-bad-commit.sh\n+++ b/t/t6011-rev-list-with-bad-commit.sh\n@@ -2,6 +2,7 @@\n \n test_description='git rev-list should notice bad commits'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Note:\n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469654","messageId":"patch-v2-10.20-fd34c4817f4-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 10/20] http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:25Z","receivedAt":"2022-12-30T02:19:22Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us ever since\n2f4038ab337 (Git-aware CGI to provide dumb HTTP transport,\n2009-10-30). In this case we're not calling regerror() after a failed\nregexec(), and don't otherwise use \"re\" afterwards.\n\nWe can therefore simplify this code by calling regfree() right after\nthe regexec(). An alternative fix would be to add a regfree() to both\nthe \"return\" and \"break\" path in this for-loop.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n http-backend.c | 7 +++++--\n 1 file changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/http-backend.c b/http-backend.c\nindex 67819d931ce..8ab58e55f85 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -759,10 +759,14 @@ int cmd_main(int argc, const char **argv)\n \t\tstruct service_cmd *c = &services[i];\n \t\tregex_t re;\n \t\tregmatch_t out[1];\n+\t\tint ret;\n \n \t\tif (regcomp(&re, c->pattern, REG_EXTENDED))\n \t\t\tdie(\"Bogus regex in service table: %s\", c->pattern);\n-\t\tif (!regexec(&re, dir, 1, out, 0)) {\n+\t\tret = regexec(&re, dir, 1, out, 0);\n+\t\tregfree(&re);\n+\n+\t\tif (!ret) {\n \t\t\tsize_t n;\n \n \t\t\tif (strcmp(method, c->method))\n@@ -774,7 +778,6 @@ int cmd_main(int argc, const char **argv)\n \t\t\tdir[out[0].rm_so] = 0;\n \t\t\tbreak;\n \t\t}\n-\t\tregfree(&re);\n \t}\n \n \tif (!cmd)\n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469655","messageId":"patch-v2-12.20-bf0e9bc5fa6-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 12/20] show-branch: free() allocated \"head\" before return","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:27Z","receivedAt":"2022-12-30T02:19:26Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Stop leaking the \"head\" variable, which we've been leaking since it\nwas originally added in [1], and in its current form since [2]\n\n1. ed378ec7e85 (Make ref resolution saner, 2006-09-11)\n2. d9e557a320b (show-branch: store resolved head in heap buffer,\n   2017-02-14).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/show-branch.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/show-branch.c b/builtin/show-branch.c\nindex c013abaf942..358ac3e519a 100644\n--- a/builtin/show-branch.c\n+++ b/builtin/show-branch.c\n@@ -956,5 +956,6 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)\n \t\tif (shown_merge_point && --extra < 0)\n \t\t\tbreak;\n \t}\n+\tfree(head);\n \treturn 0;\n }\n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469656","messageId":"patch-v2-13.20-b157092e8d0-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 13/20] builtin/merge.c: always free \"struct strbuf msg\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:28Z","receivedAt":"2022-12-30T02:19:28Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Follow-up 465028e0e25 (merge: add missing strbuf_release(),\n2021-10-07) and address the \"msg\" memory leak in this block. We could\nfree \"&msg\" before the \"goto done\" here, but even better is to avoid\nallocating it in the first place.\n\nBy repeating the \"Fast-forward\" string here we can avoid using a\n\"struct strbuf\" altogether.\n\nSuggested-by: René Scharfe <l.s.r@web.de>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/merge.c                | 11 ++++-------\n t/t6439-merge-co-error-msgs.sh |  1 +\n 2 files changed, 5 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 0f093f2a4f2..91dd5435c59 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -1560,7 +1560,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t!common->next &&\n \t\t\toideq(&common->item->object.oid, &head_commit->object.oid)) {\n \t\t/* Again the most common case of merging one remote. */\n-\t\tstruct strbuf msg = STRBUF_INIT;\n+\t\tconst char *msg = have_message ?\n+\t\t\t\"Fast-forward (no commit created; -m option ignored)\" :\n+\t\t\t\"Fast-forward\";\n \t\tstruct commit *commit;\n \n \t\tif (verbosity >= 0) {\n@@ -1570,10 +1572,6 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t       find_unique_abbrev(&remoteheads->item->object.oid,\n \t\t\t\t\t\t  DEFAULT_ABBREV));\n \t\t}\n-\t\tstrbuf_addstr(&msg, \"Fast-forward\");\n-\t\tif (have_message)\n-\t\t\tstrbuf_addstr(&msg,\n-\t\t\t\t\" (no commit created; -m option ignored)\");\n \t\tcommit = remoteheads->item;\n \t\tif (!commit) {\n \t\t\tret = 1;\n@@ -1592,9 +1590,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\tgoto done;\n \t\t}\n \n-\t\tfinish(head_commit, remoteheads, &commit->object.oid, msg.buf);\n+\t\tfinish(head_commit, remoteheads, &commit->object.oid, msg);\n \t\tremove_merge_branch_state(the_repository);\n-\t\tstrbuf_release(&msg);\n \t\tgoto done;\n \t} else if (!remoteheads->next && common->next)\n \t\t;\ndiff --git a/t/t6439-merge-co-error-msgs.sh b/t/t6439-merge-co-error-msgs.sh\nindex 52cf0c87690..0cbec57cdab 100755\n--- a/t/t6439-merge-co-error-msgs.sh\n+++ b/t/t6439-merge-co-error-msgs.sh\n@@ -5,6 +5,7 @@ test_description='unpack-trees error messages'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n \n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469657","messageId":"patch-v2-15.20-d5210017cab-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 15/20] connected.c: free(new_pack) in check_connected()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:30Z","receivedAt":"2022-12-30T02:19:31Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us since this code was introduced\nin c6807a40dcd (clone: open a shortcut for connectivity check,\n2013-05-26). We'd never free() the \"new_pack\" that we'd potentially\nallocate. Since it's initialized to \"NULL\" it's safe to call free()\nhere unconditionally.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n connected.c | 13 +++++++------\n 1 file changed, 7 insertions(+), 6 deletions(-)\n\ndiff --git a/connected.c b/connected.c\nindex b90fd61790c..e4d404e10b2 100644\n--- a/connected.c\n+++ b/connected.c\n@@ -38,7 +38,7 @@ int check_connected(oid_iterate_fn fn, void *cb_data,\n \tif (!oid) {\n \t\tif (opt->err_fd)\n \t\t\tclose(opt->err_fd);\n-\t\treturn err;\n+\t\tgoto cleanup;\n \t}\n \n \tif (transport && transport->smart_options &&\n@@ -85,8 +85,7 @@ int check_connected(oid_iterate_fn fn, void *cb_data,\n promisor_pack_found:\n \t\t\t;\n \t\t} while ((oid = fn(cb_data)) != NULL);\n-\t\tfree(new_pack);\n-\t\treturn 0;\n+\t\tgoto cleanup;\n \t}\n \n no_promisor_pack_found:\n@@ -123,8 +122,8 @@ int check_connected(oid_iterate_fn fn, void *cb_data,\n \t\trev_list.no_stderr = opt->quiet;\n \n \tif (start_command(&rev_list)) {\n-\t\tfree(new_pack);\n-\t\treturn error(_(\"Could not run 'git rev-list'\"));\n+\t\terr = error(_(\"Could not run 'git rev-list'\"));\n+\t\tgoto cleanup;\n \t}\n \n \tsigchain_push(SIGPIPE, SIG_IGN);\n@@ -157,6 +156,8 @@ int check_connected(oid_iterate_fn fn, void *cb_data,\n \t\terr = error_errno(_(\"failed to close rev-list's stdin\"));\n \n \tsigchain_pop(SIGPIPE);\n+\terr = finish_command(&rev_list) || err;\n+cleanup:\n \tfree(new_pack);\n-\treturn finish_command(&rev_list) || err;\n+\treturn err;\n }\n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469658","messageId":"patch-v2-11.20-f7005f32cc0-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 11/20] commit-graph: fix a parse_options_concat() leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:26Z","receivedAt":"2022-12-30T02:19:33Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the parse_options_concat() was added to this file in\n84e4484f128 (commit-graph: use parse_options_concat(), 2021-08-23) we\nwouldn't free() it if we returned early in these cases.\n\nSince \"result\" is 0 by default we can \"goto cleanup\" in both cases,\nand only need to set \"result\" if write_commit_graph_reachable() fails.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/commit-graph.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/commit-graph.c b/builtin/commit-graph.c\nindex 0102ac8540e..93704f95a9d 100644\n--- a/builtin/commit-graph.c\n+++ b/builtin/commit-graph.c\n@@ -269,8 +269,8 @@ static int graph_write(int argc, const char **argv, const char *prefix)\n \n \tif (opts.reachable) {\n \t\tif (write_commit_graph_reachable(odb, flags, &write_opts))\n-\t\t\treturn 1;\n-\t\treturn 0;\n+\t\t\tresult = 1;\n+\t\tgoto cleanup;\n \t}\n \n \tif (opts.stdin_packs) {\n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469659","messageId":"patch-v2-14.20-bdd2bc9a956-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 14/20] builtin/merge.c: free \"&buf\" on \"Your local changes...\" error","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:29Z","receivedAt":"2022-12-30T02:19:37Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Plug a memory leak introduced in [1], since that change didn't follow\nthe \"goto done\" pattern introduced in [2] we'd leak the \"&buf\" memory.\n\n1. e4cdfe84a0d (merge: abort if index does not match HEAD for trivial\n   merges, 2022-07-23)\n2. d5a35c114ab (Copy resolve_ref() return value for longer use,\n   2011-11-13)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/merge.c | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 91dd5435c59..2b13124c497 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -1618,7 +1618,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t\terror(_(\"Your local changes to the following files would be overwritten by merge:\\n  %s\"),\n \t\t\t\t      sb.buf);\n \t\t\t\tstrbuf_release(&sb);\n-\t\t\t\treturn 2;\n+\t\t\t\tret = 2;\n+\t\t\t\tgoto done;\n \t\t\t}\n \n \t\t\t/* See if it is really trivial. */\n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469660","messageId":"patch-v2-16.20-2016b4ddd0b-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 16/20] object-file.c: release the \"tag\" in check_tag()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:31Z","receivedAt":"2022-12-30T02:19:41Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us ever since c879daa2372 (Make\nhash-object more robust against malformed objects, 2011-02-05). With\n\"HASH_FORMAT_CHECK\" (used by \"hash-object\" and \"replace\") we'll parse\ntags into a throwaway variable on the stack, but weren't freeing the\n\"item->tag\" we might malloc() when doing so.\n\nThe clearing that release_tag_memory() does for us is redundant here,\nbut let's use it as-is anyway. It only has one other existing caller,\nwhich does need the tag to be cleared.\n\nMark the tests that now pass in their entirety as passing under\n\"SANITIZE=leak\", which means we'll test them as part of the\n\"linux-leaks\" CI job.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n object-file.c         | 1 +\n t/t3800-mktag.sh      | 1 +\n t/t5302-pack-index.sh | 2 ++\n 3 files changed, 4 insertions(+)\n\ndiff --git a/object-file.c b/object-file.c\nindex c1b71c28347..53477a07469 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -2331,6 +2331,7 @@ static void check_tag(const void *buf, size_t size)\n \tmemset(&t, 0, sizeof(t));\n \tif (parse_tag_buffer(the_repository, &t, buf, size))\n \t\tdie(_(\"corrupt tag\"));\n+\trelease_tag_memory(&t);\n }\n \n static int index_mem(struct index_state *istate,\ndiff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh\nindex e3cf0ffbe59..d3e428ff46e 100755\n--- a/t/t3800-mktag.sh\n+++ b/t/t3800-mktag.sh\n@@ -4,6 +4,7 @@\n \n test_description='git mktag: tag object verify test'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n ###########################################################\ndiff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh\nindex b0095ab41d3..54b11f81c63 100755\n--- a/t/t5302-pack-index.sh\n+++ b/t/t5302-pack-index.sh\n@@ -4,6 +4,8 @@\n #\n \n test_description='pack index with 64-bit offsets and object CRC'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469661","messageId":"patch-v2-19.20-fa5d657312f-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 19/20] receive-pack: free() the \"ref_name\" in \"struct command\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:34Z","receivedAt":"2022-12-30T02:19:42Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us since this code was introduced\nin 575f497456e (Add first cut at \"git-receive-pack\", 2005-06-29), see\neb1af2df0b1 (git-receive-pack: start parsing ref update commands,\n2005-06-29) for the later change that refactored the code to add the\n\"ref_name\" member.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/receive-pack.c                | 10 ++++++++++\n t/t5405-send-pack-rewind.sh           |  1 +\n t/t5406-remote-rejects.sh             |  1 +\n t/t5507-remote-environment.sh         |  2 ++\n t/t5522-pull-symlink.sh               |  1 +\n t/t5527-fetch-odd-refs.sh             |  1 +\n t/t5705-session-id-in-capabilities.sh |  1 +\n 7 files changed, 17 insertions(+)\n\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex a90af303630..451bad776c6 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -2032,6 +2032,15 @@ static struct command **queue_command(struct command **tail,\n \treturn &cmd->next;\n }\n \n+static void free_commands(struct command *commands)\n+{\n+\twhile (commands) {\n+\t\tstruct command *next = commands->next;\n+\t\tfree(commands);\n+\t\tcommands = next;\n+\t}\n+}\n+\n static void queue_commands_from_cert(struct command **tail,\n \t\t\t\t     struct strbuf *push_cert)\n {\n@@ -2569,6 +2578,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n \t\trun_receive_hook(commands, \"post-receive\", 1,\n \t\t\t\t &push_options);\n \t\trun_update_post_hook(commands);\n+\t\tfree_commands(commands);\n \t\tstring_list_clear(&push_options, 0);\n \t\tif (auto_gc) {\n \t\t\tstruct child_process proc = CHILD_PROCESS_INIT;\ndiff --git a/t/t5405-send-pack-rewind.sh b/t/t5405-send-pack-rewind.sh\nindex 11f03239a06..1686ac13aa6 100755\n--- a/t/t5405-send-pack-rewind.sh\n+++ b/t/t5405-send-pack-rewind.sh\n@@ -5,6 +5,7 @@ test_description='forced push to replace commit we do not have'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5406-remote-rejects.sh b/t/t5406-remote-rejects.sh\nindex dcbeb420827..d6a99466338 100755\n--- a/t/t5406-remote-rejects.sh\n+++ b/t/t5406-remote-rejects.sh\n@@ -2,6 +2,7 @@\n \n test_description='remote push rejects are reported by client'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t5507-remote-environment.sh b/t/t5507-remote-environment.sh\nindex e6149295b18..c6a6957c500 100755\n--- a/t/t5507-remote-environment.sh\n+++ b/t/t5507-remote-environment.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check environment showed to remote side of transports'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'set up \"remote\" push situation' '\ndiff --git a/t/t5522-pull-symlink.sh b/t/t5522-pull-symlink.sh\nindex bcff460d0a2..394bc60cb8e 100755\n--- a/t/t5522-pull-symlink.sh\n+++ b/t/t5522-pull-symlink.sh\n@@ -2,6 +2,7 @@\n \n test_description='pulling from symlinked subdir'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # The scenario we are building:\ndiff --git a/t/t5527-fetch-odd-refs.sh b/t/t5527-fetch-odd-refs.sh\nindex e2770e4541f..98ece27c6a0 100755\n--- a/t/t5527-fetch-odd-refs.sh\n+++ b/t/t5527-fetch-odd-refs.sh\n@@ -4,6 +4,7 @@ test_description='test fetching of oddly-named refs'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # afterwards we will have:\ndiff --git a/t/t5705-session-id-in-capabilities.sh b/t/t5705-session-id-in-capabilities.sh\nindex ed38c76c290..b8a722ec27e 100755\n--- a/t/t5705-session-id-in-capabilities.sh\n+++ b/t/t5705-session-id-in-capabilities.sh\n@@ -2,6 +2,7 @@\n \n test_description='session ID in capabilities'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n REPO=\"$(pwd)/repo\"\n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469662","messageId":"patch-v2-17.20-fa2e8a7d297-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 17/20] grep.c: refactor free_grep_patterns()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:32Z","receivedAt":"2022-12-30T02:19:45Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Refactor the free_grep_patterns() function to split out the freeing of\nthe \"struct grep_pat\" it contains, right now we're only freeing the\n\"pattern_list\", but we should be freeing another member of the same\ntype, which we'll do in the subsequent commit.\n\nLet's also replace the \"return\" if we don't have an\n\"opt->pattern_expression\" with a conditional call of\nfree_pattern_expr().\n\nBefore db84376f981 (grep.c: remove \"extended\" in favor of\n\"pattern_expression\", fix segfault, 2022-10-11) the pattern here was:\n\n\tif (!x)\n\t\treturn;\n\tfree(y);\n\nBut after the cleanup in db84376f981 (which was a narrow segfault fix,\nand thus avoided refactoring this) we ended up with:\n\n\tif (!x)\n\t\treturn;\n\tfree(x);\n\nLet's instead do:\n\n\tif (x)\n\t\tfree(x);\n\nThis doesn't matter for the subsequent change, but as we're\nrefactoring this function let's make it easier to reason about, and to\nextend in the future, i.e. if we start to free free() members that\ncome after \"pattern_expression\" in the \"struct grep_opt\".\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n grep.c | 14 +++++++++-----\n 1 file changed, 9 insertions(+), 5 deletions(-)\n\ndiff --git a/grep.c b/grep.c\nindex 06eed694936..a4450df4559 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -769,11 +769,11 @@ static void free_pattern_expr(struct grep_expr *x)\n \tfree(x);\n }\n \n-void free_grep_patterns(struct grep_opt *opt)\n+static void free_grep_pat(struct grep_pat *pattern)\n {\n \tstruct grep_pat *p, *n;\n \n-\tfor (p = opt->pattern_list; p; p = n) {\n+\tfor (p = pattern; p; p = n) {\n \t\tn = p->next;\n \t\tswitch (p->token) {\n \t\tcase GREP_PATTERN: /* atom */\n@@ -790,10 +790,14 @@ void free_grep_patterns(struct grep_opt *opt)\n \t\t}\n \t\tfree(p);\n \t}\n+}\n \n-\tif (!opt->pattern_expression)\n-\t\treturn;\n-\tfree_pattern_expr(opt->pattern_expression);\n+void free_grep_patterns(struct grep_opt *opt)\n+{\n+\tfree_grep_pat(opt->pattern_list);\n+\n+\tif (opt->pattern_expression)\n+\t\tfree_pattern_expr(opt->pattern_expression);\n }\n \n static const char *end_of_line(const char *cp, unsigned long *left)\n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469663","messageId":"patch-v2-18.20-3fcf7054708-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 18/20] grep API: plug memory leaks by freeing \"header_list\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:33Z","receivedAt":"2022-12-30T02:19:50Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the \"header_list\" struct member was added in [1] it wasn't made\nto free the list using loop added for the adjacent \"pattern_list\"\nmember, see [2] for when we started freeing it.\n\nThis makes e.g. this command leak-free when run on git.git:\n\n\t./git -P log -1 --color=always --author=A origin/master\n\n1. 80235ba79ef (\"log --author=me --grep=it\" should find intersection,\n   not union, 2010-01-17)\n2. b48fb5b6a95 (grep: free expressions and patterns when done.,\n   2006-09-27)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n grep.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/grep.c b/grep.c\nindex a4450df4559..c908535e0d8 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -795,6 +795,7 @@ static void free_grep_pat(struct grep_pat *pattern)\n void free_grep_patterns(struct grep_opt *opt)\n {\n \tfree_grep_pat(opt->pattern_list);\n+\tfree_grep_pat(opt->header_list);\n \n \tif (opt->pattern_expression)\n \t\tfree_pattern_expr(opt->pattern_expression);\n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469664","messageId":"patch-v2-20.20-e5af27134df-20221230T020341Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v2 20/20] push: free_refs() the \"local_refs\" in set_refspecs()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-12-30T02:18:35Z","receivedAt":"2022-12-30T02:19:53Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us since this code was added in\nca02465b413 (push: use remote.$name.push as a refmap, 2013-12-03).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/push.c                          | 1 +\n t/t1416-ref-transaction-hooks.sh        | 1 +\n t/t5504-fetch-receive-strict.sh         | 1 +\n t/t5523-push-upstream.sh                | 1 +\n t/t5529-push-errors.sh                  | 2 ++\n t/t5546-receive-limits.sh               | 2 ++\n t/t5547-push-quarantine.sh              | 2 ++\n t/t5606-clone-options.sh                | 1 +\n t/t5810-proto-disable-local.sh          | 2 ++\n t/t5813-proto-disable-ssh.sh            | 2 ++\n t/t7409-submodule-detached-work-tree.sh | 1 +\n t/t7416-submodule-dash-url.sh           | 2 ++\n t/t7450-bad-git-dotfiles.sh             | 2 ++\n 13 files changed, 20 insertions(+)\n\ndiff --git a/builtin/push.c b/builtin/push.c\nindex 60ac8017e52..f48e4c6a856 100644\n--- a/builtin/push.c\n+++ b/builtin/push.c\n@@ -129,6 +129,7 @@ static void set_refspecs(const char **refs, int nr, const char *repo)\n \t\t} else\n \t\t\trefspec_append(&rs, ref);\n \t}\n+\tfree_refs(local_refs);\n }\n \n static int push_url_of_remote(struct remote *remote, const char ***url_p)\ndiff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh\nindex 27731722a5b..b32ca798f9f 100755\n--- a/t/t1416-ref-transaction-hooks.sh\n+++ b/t/t1416-ref-transaction-hooks.sh\n@@ -5,6 +5,7 @@ test_description='reference transaction hooks'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh\nindex ac4099ca893..14e8af1f3b7 100755\n--- a/t/t5504-fetch-receive-strict.sh\n+++ b/t/t5504-fetch-receive-strict.sh\n@@ -4,6 +4,7 @@ test_description='fetch/receive strict mode'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup and inject \"corrupt or missing\" object' '\ndiff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh\nindex fdb42920564..c9acc076353 100755\n--- a/t/t5523-push-upstream.sh\n+++ b/t/t5523-push-upstream.sh\n@@ -4,6 +4,7 @@ test_description='push with --set-upstream'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-terminal.sh\n \ndiff --git a/t/t5529-push-errors.sh b/t/t5529-push-errors.sh\nindex ce85fd30ad1..0247137cb36 100755\n--- a/t/t5529-push-errors.sh\n+++ b/t/t5529-push-errors.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='detect some push errors early (before contacting remote)'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup commits' '\ndiff --git a/t/t5546-receive-limits.sh b/t/t5546-receive-limits.sh\nindex 0b0e987fdb7..eed3c9d81ab 100755\n--- a/t/t5546-receive-limits.sh\n+++ b/t/t5546-receive-limits.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check receive input limits'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Let's run tests with different unpack limits: 1 and 10000\ndiff --git a/t/t5547-push-quarantine.sh b/t/t5547-push-quarantine.sh\nindex 1876fb34e51..9f899b8c7d7 100755\n--- a/t/t5547-push-quarantine.sh\n+++ b/t/t5547-push-quarantine.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check quarantine of objects during push'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'create picky dest repo' '\ndiff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh\nindex cf221e92c4d..27f9f776389 100755\n--- a/t/t5606-clone-options.sh\n+++ b/t/t5606-clone-options.sh\n@@ -4,6 +4,7 @@ test_description='basic clone options'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t5810-proto-disable-local.sh b/t/t5810-proto-disable-local.sh\nindex c1ef99b85c2..862610256fb 100755\n--- a/t/t5810-proto-disable-local.sh\n+++ b/t/t5810-proto-disable-local.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test disabling of local paths in clone/fetch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY/lib-proto-disable.sh\"\n \ndiff --git a/t/t5813-proto-disable-ssh.sh b/t/t5813-proto-disable-ssh.sh\nindex 3f084ee3065..2e975dc70ec 100755\n--- a/t/t5813-proto-disable-ssh.sh\n+++ b/t/t5813-proto-disable-ssh.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test disabling of git-over-ssh in clone/fetch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY/lib-proto-disable.sh\"\n \ndiff --git a/t/t7409-submodule-detached-work-tree.sh b/t/t7409-submodule-detached-work-tree.sh\nindex 374ed481e9c..574a6fc526e 100755\n--- a/t/t7409-submodule-detached-work-tree.sh\n+++ b/t/t7409-submodule-detached-work-tree.sh\n@@ -13,6 +13,7 @@ TEST_NO_CREATE_REPO=1\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7416-submodule-dash-url.sh b/t/t7416-submodule-dash-url.sh\nindex 3ebd9859814..7cf72b9a076 100755\n--- a/t/t7416-submodule-dash-url.sh\n+++ b/t/t7416-submodule-dash-url.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check handling of disallowed .gitmodule urls'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7450-bad-git-dotfiles.sh b/t/t7450-bad-git-dotfiles.sh\nindex ba1f569bcbb..0d0c3f2c683 100755\n--- a/t/t7450-bad-git-dotfiles.sh\n+++ b/t/t7450-bad-git-dotfiles.sh\n@@ -12,6 +12,8 @@ Such as:\n \n   - symlinked .gitmodules, etc\n '\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-pack.sh\n \n-- \n2.39.0.1153.g589e4efe9dc\n\n"},{"id":"469680","messageId":"755d84d5-62f1-4f4e-ff31-4604c0dca0a9@web.de","threadId":"59011","inReplyTo":"patch-v2-15.20-d5210017cab-20221230T020341Z-avarab@gmail.com","subject":"Re: [PATCH v2 15/20] connected.c: free(new_pack) in check_connected()","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2022-12-30T16:17:02Z","receivedAt":"2022-12-30T16:17:15Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 30.12.22 um 03:18 schrieb Ævar Arnfjörð Bjarmason:\n> Fix a memory leak that's been with us since this code was introduced\n> in c6807a40dcd (clone: open a shortcut for connectivity check,\n> 2013-05-26). We'd never free() the \"new_pack\" that we'd potentially\n> allocate.\n\nThat's obviously not true because the patch removes free() calls for\nit, so at least some execution paths were already cleaning it up.\n\nTaking a closer look, though: Is there a leaking execution path\nwithout this patch at all?\n\n   $ git grep -n return connected.c\n   connected.c:41:\t\treturn err;\n   connected.c:89:\t\treturn 0;\n   connected.c:127:\t\treturn error(_(\"Could not run 'git rev-list'\"));\n   connected.c:161:\treturn finish_command(&rev_list) || err;\n\nSo there are four returns before.\n\n> Since it's initialized to \"NULL\" it's safe to call free()\n> here unconditionally.\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  connected.c | 13 +++++++------\n>  1 file changed, 7 insertions(+), 6 deletions(-)\n>\n> diff --git a/connected.c b/connected.c\n> index b90fd61790c..e4d404e10b2 100644\n> --- a/connected.c\n> +++ b/connected.c\n> @@ -38,7 +38,7 @@ int check_connected(oid_iterate_fn fn, void *cb_data,\n>  \tif (!oid) {\n>  \t\tif (opt->err_fd)\n>  \t\t\tclose(opt->err_fd);\n> -\t\treturn err;\n> +\t\tgoto cleanup;\n\nWhere are we?\n\n   $ git grep -n new_pack.= connected.c\n   connected.c:29:\tstruct packed_git *new_pack = NULL;\n   connected.c:53:\t\tnew_pack = add_packed_git(idx_file.buf, idx_file.len, 1);\n\nAfter new_pack is initialized to NULL, but before it is set to\npoint to some actual pack object.  So no free() is needed here.\n\n>  \t}\n>\n>  \tif (transport && transport->smart_options &&\n> @@ -85,8 +85,7 @@ int check_connected(oid_iterate_fn fn, void *cb_data,\n>  promisor_pack_found:\n>  \t\t\t;\n>  \t\t} while ((oid = fn(cb_data)) != NULL);\n> -\t\tfree(new_pack);\n> -\t\treturn 0;\n> +\t\tgoto cleanup;\n\nfree() removed, no leak before.\n\n>  \t}\n>\n>  no_promisor_pack_found:\n> @@ -123,8 +122,8 @@ int check_connected(oid_iterate_fn fn, void *cb_data,\n>  \t\trev_list.no_stderr = opt->quiet;\n>\n>  \tif (start_command(&rev_list)) {\n> -\t\tfree(new_pack);\n> -\t\treturn error(_(\"Could not run 'git rev-list'\"));\n> +\t\terr = error(_(\"Could not run 'git rev-list'\"));\n> +\t\tgoto cleanup;\n\nSame here.\n\n>  \t}\n>\n>  \tsigchain_push(SIGPIPE, SIG_IGN);\n> @@ -157,6 +156,8 @@ int check_connected(oid_iterate_fn fn, void *cb_data,\n>  \t\terr = error_errno(_(\"failed to close rev-list's stdin\"));\n>\n>  \tsigchain_pop(SIGPIPE);\n> +\terr = finish_command(&rev_list) || err;\n> +cleanup:\n>  \tfree(new_pack);\n> -\treturn finish_command(&rev_list) || err;\n> +\treturn err;\n\nfree() kept, no leak before.\n\nAnd that's all four returns.\n\nSo there is no leak to begin with here, or am I missing something?\n\n>  }\n"},{"id":"469681","messageId":"64923db2-fa0c-5ca3-6a43-ba215b85509e@web.de","threadId":"59011","inReplyTo":"patch-v2-03.20-a840a1cb330-20221230T020341Z-avarab@gmail.com","subject":"Re: [PATCH v2 03/20] commit-graph: use free() instead of UNLEAK()","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2022-12-30T16:26:52Z","receivedAt":"2022-12-30T16:27:06Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 30.12.22 um 03:18 schrieb Ævar Arnfjörð Bjarmason:\n> In 0bfb48e6723 (builtin/commit-graph.c: UNLEAK variables, 2018-10-03)\n> this was made to UNLEAK(), but we can just as easily invoke the\n> free_commit_graph() function added in c3756d5b7fc (commit-graph: add\n> free_commit_graph, 2018-07-11) instead.\n\nPatch and commit message are about free_commit_graph(), but the subject\nstill mentions free().\n\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  builtin/commit-graph.c | 6 ++++--\n>  1 file changed, 4 insertions(+), 2 deletions(-)\n>\n> diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c\n> index e8f77f535f3..0102ac8540e 100644\n> --- a/builtin/commit-graph.c\n> +++ b/builtin/commit-graph.c\n> @@ -67,6 +67,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix)\n>  \tint fd;\n>  \tstruct stat st;\n>  \tint flags = 0;\n> +\tint ret;\n>\n>  \tstatic struct option builtin_commit_graph_verify_options[] = {\n>  \t\tOPT_BOOL(0, \"shallow\", &opts.shallow,\n> @@ -111,8 +112,9 @@ static int graph_verify(int argc, const char **argv, const char *prefix)\n>  \tif (!graph)\n>  \t\treturn !!open_ok;\n>\n> -\tUNLEAK(graph);\n> -\treturn verify_commit_graph(the_repository, graph, flags);\n> +\tret = verify_commit_graph(the_repository, graph, flags);\n> +\tfree_commit_graph(graph);\n> +\treturn ret;\n>  }\n>\n>  extern int read_replace_refs;\n"},{"id":"470021","messageId":"230110.86wn5vymk7.gmgdl@evledraar.gmail.com","threadId":"59011","inReplyTo":"755d84d5-62f1-4f4e-ff31-4604c0dca0a9@web.de","subject":"Re: [PATCH v2 15/20] connected.c: free(new_pack) in check_connected()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:39:38Z","receivedAt":"2023-01-10T05:40:34Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Fri, Dec 30 2022, René Scharfe wrote:\n\n> Am 30.12.22 um 03:18 schrieb Ævar Arnfjörð Bjarmason:\n>> Fix a memory leak that's been with us since this code was introduced\n>> in c6807a40dcd (clone: open a shortcut for connectivity check,\n>> 2013-05-26). We'd never free() the \"new_pack\" that we'd potentially\n>> allocate.\n>\n> That's obviously not true because the patch removes free() calls for\n> it, so at least some execution paths were already cleaning it up.\n>\n> Taking a closer look, though: Is there a leaking execution path\n> without this patch at all?\n>\n>    $ git grep -n return connected.c\n>    connected.c:41:\t\treturn err;\n>    connected.c:89:\t\treturn 0;\n>    connected.c:127:\t\treturn error(_(\"Could not run 'git rev-list'\"));\n>    connected.c:161:\treturn finish_command(&rev_list) || err;\n>\n> So there are four returns before.\n>\n>> Since it's initialized to \"NULL\" it's safe to call free()\n>> here unconditionally.\n>>\n>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n>> ---\n>>  connected.c | 13 +++++++------\n>>  1 file changed, 7 insertions(+), 6 deletions(-)\n>>\n>> diff --git a/connected.c b/connected.c\n>> index b90fd61790c..e4d404e10b2 100644\n>> --- a/connected.c\n>> +++ b/connected.c\n>> @@ -38,7 +38,7 @@ int check_connected(oid_iterate_fn fn, void *cb_data,\n>>  \tif (!oid) {\n>>  \t\tif (opt->err_fd)\n>>  \t\t\tclose(opt->err_fd);\n>> -\t\treturn err;\n>> +\t\tgoto cleanup;\n>\n> Where are we?\n>\n>    $ git grep -n new_pack.= connected.c\n>    connected.c:29:\tstruct packed_git *new_pack = NULL;\n>    connected.c:53:\t\tnew_pack = add_packed_git(idx_file.buf, idx_file.len, 1);\n>\n> After new_pack is initialized to NULL, but before it is set to\n> point to some actual pack object.  So no free() is needed here.\n>\n>>  \t}\n>>\n>>  \tif (transport && transport->smart_options &&\n>> @@ -85,8 +85,7 @@ int check_connected(oid_iterate_fn fn, void *cb_data,\n>>  promisor_pack_found:\n>>  \t\t\t;\n>>  \t\t} while ((oid = fn(cb_data)) != NULL);\n>> -\t\tfree(new_pack);\n>> -\t\treturn 0;\n>> +\t\tgoto cleanup;\n>\n> free() removed, no leak before.\n>\n>>  \t}\n>>\n>>  no_promisor_pack_found:\n>> @@ -123,8 +122,8 @@ int check_connected(oid_iterate_fn fn, void *cb_data,\n>>  \t\trev_list.no_stderr = opt->quiet;\n>>\n>>  \tif (start_command(&rev_list)) {\n>> -\t\tfree(new_pack);\n>> -\t\treturn error(_(\"Could not run 'git rev-list'\"));\n>> +\t\terr = error(_(\"Could not run 'git rev-list'\"));\n>> +\t\tgoto cleanup;\n>\n> Same here.\n>\n>>  \t}\n>>\n>>  \tsigchain_push(SIGPIPE, SIG_IGN);\n>> @@ -157,6 +156,8 @@ int check_connected(oid_iterate_fn fn, void *cb_data,\n>>  \t\terr = error_errno(_(\"failed to close rev-list's stdin\"));\n>>\n>>  \tsigchain_pop(SIGPIPE);\n>> +\terr = finish_command(&rev_list) || err;\n>> +cleanup:\n>>  \tfree(new_pack);\n>> -\treturn finish_command(&rev_list) || err;\n>> +\treturn err;\n>\n> free() kept, no leak before.\n>\n> And that's all four returns.\n>\n> So there is no leak to begin with here, or am I missing something?\n\nThe commit message was just out of date, this was just the\npost-refactoring for the already landed dd4143e7bf4 (connected.c: free\nthe \"struct packed_git\", 2022-11-08), but I forgot to update it.\n\nI'll just drop this patch, as this series is meant to be leak fixes, not\nsuch post-refactorings, sorry.\n"},{"id":"470022","messageId":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com","subject":"[PATCH v3 00/19] leak fixes: various simple leak fixes","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:20Z","receivedAt":"2023-01-10T05:44:04Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"A hopefully final version of this collection of simple leak fixes. See\nhttps://lore.kernel.org/git/cover-v2-00.20-00000000000-20221230T020341Z-avarab@gmail.com/\nfor v2.\n\nChanges since v2:\n\n * Updated reference to function name in a commit subject, spotted by\n   René.\n\n * Dropped a patch that didn't fix a leak, but just did a post-cleanup\n   of an already fixed leak.\n\nÆvar Arnfjörð Bjarmason (19):\n  tests: mark tests as passing with SANITIZE=leak\n  bundle.c: don't leak the \"args\" in the \"struct child_process\"\n  commit-graph: use free_commit_graph() instead of UNLEAK()\n  clone: use free() instead of UNLEAK()\n  various: add missing clear_pathspec(), fix leaks\n  name-rev: don't xstrdup() an already dup'd string\n  repack: fix leaks on error with \"goto cleanup\"\n  worktree: fix a trivial leak in prune_worktrees()\n  http-backend.c: fix \"dir\" and \"cmd_arg\" leaks in cmd_main()\n  http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()\n  commit-graph: fix a parse_options_concat() leak\n  show-branch: free() allocated \"head\" before return\n  builtin/merge.c: always free \"struct strbuf msg\"\n  builtin/merge.c: free \"&buf\" on \"Your local changes...\" error\n  object-file.c: release the \"tag\" in check_tag()\n  grep.c: refactor free_grep_patterns()\n  grep API: plug memory leaks by freeing \"header_list\"\n  receive-pack: free() the \"ref_name\" in \"struct command\"\n  push: free_refs() the \"local_refs\" in set_refspecs()\n\n archive.c                                  |  1 +\n builtin/clean.c                            |  1 +\n builtin/clone.c                            |  5 +++--\n builtin/commit-graph.c                     | 10 ++++++----\n builtin/merge.c                            | 14 ++++++-------\n builtin/name-rev.c                         | 23 ++++++++++------------\n builtin/push.c                             |  1 +\n builtin/receive-pack.c                     | 10 ++++++++++\n builtin/repack.c                           | 13 ++++++------\n builtin/reset.c                            | 11 ++++++++---\n builtin/show-branch.c                      |  1 +\n builtin/stash.c                            |  7 +++++--\n builtin/worktree.c                         |  6 +++---\n bundle.c                                   |  6 ++++--\n grep.c                                     | 15 +++++++++-----\n http-backend.c                             |  9 +++++++--\n object-file.c                              |  1 +\n t/t0023-crlf-am.sh                         |  1 +\n t/t1301-shared-repo.sh                     |  1 +\n t/t1302-repo-version.sh                    |  1 +\n t/t1304-default-acl.sh                     |  1 +\n t/t1408-packed-refs.sh                     |  1 +\n t/t1410-reflog.sh                          |  1 +\n t/t1416-ref-transaction-hooks.sh           |  1 +\n t/t2401-worktree-prune.sh                  |  1 +\n t/t2406-worktree-repair.sh                 |  1 +\n t/t3210-pack-refs.sh                       |  1 +\n t/t3800-mktag.sh                           |  1 +\n t/t4152-am-subjects.sh                     |  2 ++\n t/t4254-am-corrupt.sh                      |  2 ++\n t/t4256-am-format-flowed.sh                |  1 +\n t/t4257-am-interactive.sh                  |  2 ++\n t/t5001-archive-attr.sh                    |  1 +\n t/t5004-archive-corner-cases.sh            |  2 ++\n t/t5302-pack-index.sh                      |  2 ++\n t/t5317-pack-objects-filter-objects.sh     |  1 +\n t/t5330-no-lazy-fetch-with-commit-graph.sh |  1 +\n t/t5403-post-checkout-hook.sh              |  1 +\n t/t5405-send-pack-rewind.sh                |  1 +\n t/t5406-remote-rejects.sh                  |  1 +\n t/t5502-quickfetch.sh                      |  1 +\n t/t5504-fetch-receive-strict.sh            |  1 +\n t/t5507-remote-environment.sh              |  2 ++\n t/t5522-pull-symlink.sh                    |  1 +\n t/t5523-push-upstream.sh                   |  1 +\n t/t5527-fetch-odd-refs.sh                  |  1 +\n t/t5529-push-errors.sh                     |  2 ++\n t/t5546-receive-limits.sh                  |  2 ++\n t/t5547-push-quarantine.sh                 |  2 ++\n t/t5604-clone-reference.sh                 |  1 +\n t/t5606-clone-options.sh                   |  1 +\n t/t5613-info-alternate.sh                  |  2 ++\n t/t5705-session-id-in-capabilities.sh      |  1 +\n t/t5810-proto-disable-local.sh             |  2 ++\n t/t5813-proto-disable-ssh.sh               |  2 ++\n t/t6011-rev-list-with-bad-commit.sh        |  1 +\n t/t6014-rev-list-all.sh                    |  1 +\n t/t6021-rev-list-exclude-hidden.sh         |  1 +\n t/t6439-merge-co-error-msgs.sh             |  1 +\n t/t7105-reset-patch.sh                     |  2 ++\n t/t7106-reset-unborn-branch.sh             |  2 ++\n t/t7107-reset-pathspec-file.sh             |  1 +\n t/t7301-clean-interactive.sh               |  1 +\n t/t7403-submodule-sync.sh                  |  1 +\n t/t7409-submodule-detached-work-tree.sh    |  1 +\n t/t7416-submodule-dash-url.sh              |  2 ++\n t/t7450-bad-git-dotfiles.sh                |  2 ++\n t/t7701-repack-unpack-unreachable.sh       |  1 +\n 68 files changed, 151 insertions(+), 50 deletions(-)\n\nRange-diff against v2:\n 1:  3de29c6d75f =  1:  f5b67f44e2d tests: mark tests as passing with SANITIZE=leak\n 2:  5036712391d =  2:  88c6b66be3c bundle.c: don't leak the \"args\" in the \"struct child_process\"\n 3:  a840a1cb330 !  3:  8cc8060cd92 commit-graph: use free() instead of UNLEAK()\n    @@ Metadata\n     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## Commit message ##\n    -    commit-graph: use free() instead of UNLEAK()\n    +    commit-graph: use free_commit_graph() instead of UNLEAK()\n     \n         In 0bfb48e6723 (builtin/commit-graph.c: UNLEAK variables, 2018-10-03)\n         this was made to UNLEAK(), but we can just as easily invoke the\n 4:  c05620cef49 =  4:  765d5cbcf81 clone: use free() instead of UNLEAK()\n 5:  62af6557760 =  5:  5087fb73286 various: add missing clear_pathspec(), fix leaks\n 6:  7cea3da9fae =  6:  39cb8aefb58 name-rev: don't xstrdup() an already dup'd string\n 7:  b5978d75c6a =  7:  a3f1e800127 repack: fix leaks on error with \"goto cleanup\"\n 8:  468615570f4 =  8:  f918a6f2adc worktree: fix a trivial leak in prune_worktrees()\n 9:  8c5c964d872 =  9:  56204806dfd http-backend.c: fix \"dir\" and \"cmd_arg\" leaks in cmd_main()\n10:  fd34c4817f4 = 10:  5355e0fc60b http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()\n11:  f7005f32cc0 = 11:  dfb52dbd1c4 commit-graph: fix a parse_options_concat() leak\n12:  bf0e9bc5fa6 = 12:  e44e74dcc58 show-branch: free() allocated \"head\" before return\n13:  b157092e8d0 = 13:  6d99fdcc44e builtin/merge.c: always free \"struct strbuf msg\"\n14:  bdd2bc9a956 = 14:  a3bf3045597 builtin/merge.c: free \"&buf\" on \"Your local changes...\" error\n15:  d5210017cab <  -:  ----------- connected.c: free(new_pack) in check_connected()\n16:  2016b4ddd0b = 15:  7c70bbdebc8 object-file.c: release the \"tag\" in check_tag()\n17:  fa2e8a7d297 = 16:  17537e1393e grep.c: refactor free_grep_patterns()\n18:  3fcf7054708 = 17:  e4bd46a343e grep API: plug memory leaks by freeing \"header_list\"\n19:  fa5d657312f = 18:  3e4b12cb623 receive-pack: free() the \"ref_name\" in \"struct command\"\n20:  e5af27134df = 19:  d51ed239a8a push: free_refs() the \"local_refs\" in set_refspecs()\n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470023","messageId":"patch-v3-01.19-f5b67f44e2d-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v3 01/19] tests: mark tests as passing with SANITIZE=leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:21Z","receivedAt":"2023-01-10T05:44:05Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the \"ab/various-leak-fixes\" topic was merged in [1] only t6021\nwould fail if the tests were run in the\n\"GIT_TEST_PASSING_SANITIZE_LEAK=check\" mode, i.e. to check whether we\nmarked all leak-free tests with \"TEST_PASSES_SANITIZE_LEAK=true\".\n\nSince then we've had various tests starting to pass under\nSANITIZE=leak. Let's mark those as passing, this is when they started\nto pass, narrowed down with \"git bisect\":\n\n- t5317-pack-objects-filter-objects.sh: In\n  faebba436e6 (list-objects-filter: plug pattern_list leak, 2022-12-01).\n\n- t3210-pack-refs.sh, t5613-info-alternate.sh,\n  t7403-submodule-sync.sh: In 189e97bc4ba (diff: remove parseopts member\n  from struct diff_options, 2022-12-01).\n\n- t1408-packed-refs.sh: In ab91f6b7c42 (Merge branch\n  'rs/diff-parseopts', 2022-12-19).\n\n- t0023-crlf-am.sh, t4152-am-subjects.sh, t4254-am-corrupt.sh,\n  t4256-am-format-flowed.sh, t4257-am-interactive.sh,\n  t5403-post-checkout-hook.sh: In a658e881c13 (am: don't pass strvec to\n  apply_parse_options(), 2022-12-13)\n\n- t1301-shared-repo.sh, t1302-repo-version.sh: In b07a819c05f (reflog:\n  clear leftovers in reflog_expiry_cleanup(), 2022-12-13).\n\n- t1304-default-acl.sh, t1410-reflog.sh,\n  t5330-no-lazy-fetch-with-commit-graph.sh, t5502-quickfetch.sh,\n  t5604-clone-reference.sh, t6014-rev-list-all.sh,\n  t7701-repack-unpack-unreachable.sh: In b0c61be3209 (Merge branch\n  'rs/reflog-expiry-cleanup', 2022-12-26)\n\n1. 9ea1378d046 (Merge branch 'ab/various-leak-fixes', 2022-12-14)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n t/t0023-crlf-am.sh                         | 1 +\n t/t1301-shared-repo.sh                     | 1 +\n t/t1302-repo-version.sh                    | 1 +\n t/t1304-default-acl.sh                     | 1 +\n t/t1408-packed-refs.sh                     | 1 +\n t/t1410-reflog.sh                          | 1 +\n t/t3210-pack-refs.sh                       | 1 +\n t/t4152-am-subjects.sh                     | 2 ++\n t/t4254-am-corrupt.sh                      | 2 ++\n t/t4256-am-format-flowed.sh                | 1 +\n t/t4257-am-interactive.sh                  | 2 ++\n t/t5317-pack-objects-filter-objects.sh     | 1 +\n t/t5330-no-lazy-fetch-with-commit-graph.sh | 1 +\n t/t5403-post-checkout-hook.sh              | 1 +\n t/t5502-quickfetch.sh                      | 1 +\n t/t5604-clone-reference.sh                 | 1 +\n t/t5613-info-alternate.sh                  | 2 ++\n t/t6014-rev-list-all.sh                    | 1 +\n t/t6021-rev-list-exclude-hidden.sh         | 1 +\n t/t7403-submodule-sync.sh                  | 1 +\n t/t7701-repack-unpack-unreachable.sh       | 1 +\n 21 files changed, 25 insertions(+)\n\ndiff --git a/t/t0023-crlf-am.sh b/t/t0023-crlf-am.sh\nindex f9bbb91f64e..575805513a3 100755\n--- a/t/t0023-crlf-am.sh\n+++ b/t/t0023-crlf-am.sh\n@@ -2,6 +2,7 @@\n \n test_description='Test am with auto.crlf'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n cat >patchfile <<\\EOF\ndiff --git a/t/t1301-shared-repo.sh b/t/t1301-shared-repo.sh\nindex 93a2f91f8a5..a1251f65100 100755\n--- a/t/t1301-shared-repo.sh\n+++ b/t/t1301-shared-repo.sh\n@@ -8,6 +8,7 @@ test_description='Test shared repository initialization'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Remove a default ACL from the test dir if possible.\ndiff --git a/t/t1302-repo-version.sh b/t/t1302-repo-version.sh\nindex 7cf80bf66a6..70389fa2ebb 100755\n--- a/t/t1302-repo-version.sh\n+++ b/t/t1302-repo-version.sh\n@@ -5,6 +5,7 @@\n \n test_description='Test repository version check'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh\nindex c69ae41306c..31b89dd9693 100755\n--- a/t/t1304-default-acl.sh\n+++ b/t/t1304-default-acl.sh\n@@ -9,6 +9,7 @@ test_description='Test repository with default ACL'\n # => this must come before . ./test-lib.sh\n umask 077\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # We need an arbitrary other user give permission to using ACLs. root\ndiff --git a/t/t1408-packed-refs.sh b/t/t1408-packed-refs.sh\nindex 41ba1f1d7fc..9469c79a585 100755\n--- a/t/t1408-packed-refs.sh\n+++ b/t/t1408-packed-refs.sh\n@@ -5,6 +5,7 @@ test_description='packed-refs entries are covered by loose refs'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh\nindex aa59954f6c5..6c45965b1e4 100755\n--- a/t/t1410-reflog.sh\n+++ b/t/t1410-reflog.sh\n@@ -7,6 +7,7 @@ test_description='Test prune and reflog expiration'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n check_have () {\ndiff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh\nindex 577f32dc71f..07a0ff93def 100755\n--- a/t/t3210-pack-refs.sh\n+++ b/t/t3210-pack-refs.sh\n@@ -12,6 +12,7 @@ semantic is still the same.\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'enable reflogs' '\ndiff --git a/t/t4152-am-subjects.sh b/t/t4152-am-subjects.sh\nindex 4c68245acad..9f2edba1f83 100755\n--- a/t/t4152-am-subjects.sh\n+++ b/t/t4152-am-subjects.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test subject preservation with format-patch | am'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n make_patches() {\ndiff --git a/t/t4254-am-corrupt.sh b/t/t4254-am-corrupt.sh\nindex 54be7da1611..45f1d4f95e5 100755\n--- a/t/t4254-am-corrupt.sh\n+++ b/t/t4254-am-corrupt.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git am with corrupt input'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n make_mbox_with_nul () {\ndiff --git a/t/t4256-am-format-flowed.sh b/t/t4256-am-format-flowed.sh\nindex 2369c4e17ad..1015273bc82 100755\n--- a/t/t4256-am-format-flowed.sh\n+++ b/t/t4256-am-format-flowed.sh\n@@ -2,6 +2,7 @@\n \n test_description='test format=flowed support of git am'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t4257-am-interactive.sh b/t/t4257-am-interactive.sh\nindex aed8f4de3d6..f26d7fd2dbd 100755\n--- a/t/t4257-am-interactive.sh\n+++ b/t/t4257-am-interactive.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='am --interactive tests'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'set up patches to apply' '\ndiff --git a/t/t5317-pack-objects-filter-objects.sh b/t/t5317-pack-objects-filter-objects.sh\nindex 5b707d911b5..b26d476c646 100755\n--- a/t/t5317-pack-objects-filter-objects.sh\n+++ b/t/t5317-pack-objects-filter-objects.sh\n@@ -5,6 +5,7 @@ test_description='git pack-objects using object filtering'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Test blob:none filter.\ndiff --git a/t/t5330-no-lazy-fetch-with-commit-graph.sh b/t/t5330-no-lazy-fetch-with-commit-graph.sh\nindex 2cc7fd7a476..5eb28f0512d 100755\n--- a/t/t5330-no-lazy-fetch-with-commit-graph.sh\n+++ b/t/t5330-no-lazy-fetch-with-commit-graph.sh\n@@ -2,6 +2,7 @@\n \n test_description='test for no lazy fetch with the commit-graph'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup: prepare a repository with a commit' '\ndiff --git a/t/t5403-post-checkout-hook.sh b/t/t5403-post-checkout-hook.sh\nindex 978f240cdac..cfaae547398 100755\n--- a/t/t5403-post-checkout-hook.sh\n+++ b/t/t5403-post-checkout-hook.sh\n@@ -7,6 +7,7 @@ test_description='Test the post-checkout hook.'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5502-quickfetch.sh b/t/t5502-quickfetch.sh\nindex b160f8b7fb7..7b3ff21b984 100755\n--- a/t/t5502-quickfetch.sh\n+++ b/t/t5502-quickfetch.sh\n@@ -5,6 +5,7 @@ test_description='test quickfetch from local'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh\nindex 2734e37e880..dc86dea1333 100755\n--- a/t/t5604-clone-reference.sh\n+++ b/t/t5604-clone-reference.sh\n@@ -7,6 +7,7 @@ test_description='test clone --reference'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n base_dir=$(pwd)\ndiff --git a/t/t5613-info-alternate.sh b/t/t5613-info-alternate.sh\nindex 895f46bb911..7708cbafa98 100755\n--- a/t/t5613-info-alternate.sh\n+++ b/t/t5613-info-alternate.sh\n@@ -4,6 +4,8 @@\n #\n \n test_description='test transitive info/alternate entries'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'preparing first repository' '\ndiff --git a/t/t6014-rev-list-all.sh b/t/t6014-rev-list-all.sh\nindex c9bedd29cba..16b8bd1d090 100755\n--- a/t/t6014-rev-list-all.sh\n+++ b/t/t6014-rev-list-all.sh\n@@ -2,6 +2,7 @@\n \n test_description='--all includes detached HEADs'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n \ndiff --git a/t/t6021-rev-list-exclude-hidden.sh b/t/t6021-rev-list-exclude-hidden.sh\nindex 32b2b094138..11c50b7c0dd 100755\n--- a/t/t6021-rev-list-exclude-hidden.sh\n+++ b/t/t6021-rev-list-exclude-hidden.sh\n@@ -2,6 +2,7 @@\n \n test_description='git rev-list --exclude-hidden test'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh\nindex ea92ef52a5e..ff09443a0a4 100755\n--- a/t/t7403-submodule-sync.sh\n+++ b/t/t7403-submodule-sync.sh\n@@ -11,6 +11,7 @@ These tests exercise the \"git submodule sync\" subcommand.\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t7701-repack-unpack-unreachable.sh b/t/t7701-repack-unpack-unreachable.sh\nindex b7ac4f598a8..ebb267855fe 100755\n--- a/t/t7701-repack-unpack-unreachable.sh\n+++ b/t/t7701-repack-unpack-unreachable.sh\n@@ -5,6 +5,7 @@ test_description='git repack works correctly'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n fsha1=\n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470024","messageId":"patch-v3-02.19-88c6b66be3c-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v3 02/19] bundle.c: don't leak the \"args\" in the \"struct child_process\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:22Z","receivedAt":"2023-01-10T05:44:10Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a leak that's been here since 7366096de9d (bundle API: change\n\"flags\" to be \"extra_index_pack_args\", 2021-09-05), if can't verify\nthe bundle we didn't call child_process_clear() to clear the \"args\".\n\nBut rather than doing that let's verify the bundle before we start\npreparing the process we're going to spawn, if we get an error we\ndon't need to push anything to the \"args\".\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n bundle.c | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/bundle.c b/bundle.c\nindex 4ef7256aa11..9ebb10a8f72 100644\n--- a/bundle.c\n+++ b/bundle.c\n@@ -627,6 +627,10 @@ int unbundle(struct repository *r, struct bundle_header *header,\n \t     enum verify_bundle_flags flags)\n {\n \tstruct child_process ip = CHILD_PROCESS_INIT;\n+\n+\tif (verify_bundle(r, header, flags))\n+\t\treturn -1;\n+\n \tstrvec_pushl(&ip.args, \"index-pack\", \"--fix-thin\", \"--stdin\", NULL);\n \n \t/* If there is a filter, then we need to create the promisor pack. */\n@@ -638,8 +642,6 @@ int unbundle(struct repository *r, struct bundle_header *header,\n \t\tstrvec_clear(extra_index_pack_args);\n \t}\n \n-\tif (verify_bundle(r, header, flags))\n-\t\treturn -1;\n \tip.in = bundle_fd;\n \tip.no_stdout = 1;\n \tip.git_cmd = 1;\n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470025","messageId":"patch-v3-03.19-8cc8060cd92-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v3 03/19] commit-graph: use free_commit_graph() instead of UNLEAK()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:23Z","receivedAt":"2023-01-10T05:44:19Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"In 0bfb48e6723 (builtin/commit-graph.c: UNLEAK variables, 2018-10-03)\nthis was made to UNLEAK(), but we can just as easily invoke the\nfree_commit_graph() function added in c3756d5b7fc (commit-graph: add\nfree_commit_graph, 2018-07-11) instead.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/commit-graph.c | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/commit-graph.c b/builtin/commit-graph.c\nindex e8f77f535f3..0102ac8540e 100644\n--- a/builtin/commit-graph.c\n+++ b/builtin/commit-graph.c\n@@ -67,6 +67,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix)\n \tint fd;\n \tstruct stat st;\n \tint flags = 0;\n+\tint ret;\n \n \tstatic struct option builtin_commit_graph_verify_options[] = {\n \t\tOPT_BOOL(0, \"shallow\", &opts.shallow,\n@@ -111,8 +112,9 @@ static int graph_verify(int argc, const char **argv, const char *prefix)\n \tif (!graph)\n \t\treturn !!open_ok;\n \n-\tUNLEAK(graph);\n-\treturn verify_commit_graph(the_repository, graph, flags);\n+\tret = verify_commit_graph(the_repository, graph, flags);\n+\tfree_commit_graph(graph);\n+\treturn ret;\n }\n \n extern int read_replace_refs;\n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470026","messageId":"patch-v3-04.19-765d5cbcf81-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v3 04/19] clone: use free() instead of UNLEAK()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:24Z","receivedAt":"2023-01-10T05:44:36Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change an UNLEAK() added in 0c4542738e6 (clone: free or UNLEAK further\npointers when finished, 2021-03-14) to use a \"to_free\" pattern\ninstead. In this case the \"repo\" can be either this absolute_pathdup()\nvalue, or in the \"else if\" branch seen in the context the the\n\"argv[0]\" argument to \"main()\".\n\nWe can only free() the value in the former case, hence the \"to_free\"\npattern.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/clone.c | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 5453ba5277f..ba82f5e4108 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -892,6 +892,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tint is_bundle = 0, is_local;\n \tint reject_shallow = 0;\n \tconst char *repo_name, *repo, *work_tree, *git_dir;\n+\tchar *repo_to_free = NULL;\n \tchar *path = NULL, *dir, *display_repo = NULL;\n \tint dest_exists, real_dest_exists = 0;\n \tconst struct ref *refs, *remote_head;\n@@ -949,7 +950,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tpath = get_repo_path(repo_name, &is_bundle);\n \tif (path) {\n \t\tFREE_AND_NULL(path);\n-\t\trepo = absolute_pathdup(repo_name);\n+\t\trepo = repo_to_free = absolute_pathdup(repo_name);\n \t} else if (strchr(repo_name, ':')) {\n \t\trepo = repo_name;\n \t\tdisplay_repo = transport_anonymize_url(repo);\n@@ -1413,7 +1414,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tfree(unborn_head);\n \tfree(dir);\n \tfree(path);\n-\tUNLEAK(repo);\n+\tfree(repo_to_free);\n \tjunk_mode = JUNK_LEAVE_ALL;\n \n \ttransport_ls_refs_options_release(&transport_ls_refs_options);\n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470027","messageId":"patch-v3-06.19-39cb8aefb58-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v3 06/19] name-rev: don't xstrdup() an already dup'd string","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:26Z","receivedAt":"2023-01-10T05:44:40Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When \"add_to_tip_table()\" is called with a non-zero\n\"shorten_unambiguous\" we always return an xstrdup()'d string, which\nwe'd then xstrdup() again, leaking memory. See [1] and [2] for how\nthis leak came about.\n\nWe could xstrdup() only if \"shorten_unambiguous\" wasn't true, but\nlet's instead inline this code, so that information on whether we need\nto xstrdup() is contained within add_to_tip_table().\n\n1. 98c5c4ad015 (name-rev: allow to specify a subpath for --refs\n   option, 2013-06-18)\n2. b23e0b9353e (name-rev: allow converting the exact object name at\n   the tip of a ref, 2013-07-07)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/name-rev.c | 23 ++++++++++-------------\n 1 file changed, 10 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin/name-rev.c b/builtin/name-rev.c\nindex 15535e914a6..49fae523694 100644\n--- a/builtin/name-rev.c\n+++ b/builtin/name-rev.c\n@@ -273,17 +273,6 @@ static int subpath_matches(const char *path, const char *filter)\n \treturn -1;\n }\n \n-static const char *name_ref_abbrev(const char *refname, int shorten_unambiguous)\n-{\n-\tif (shorten_unambiguous)\n-\t\trefname = shorten_unambiguous_ref(refname, 0);\n-\telse if (skip_prefix(refname, \"refs/heads/\", &refname))\n-\t\t; /* refname already advanced */\n-\telse\n-\t\tskip_prefix(refname, \"refs/\", &refname);\n-\treturn refname;\n-}\n-\n struct name_ref_data {\n \tint tags_only;\n \tint name_only;\n@@ -309,11 +298,19 @@ static void add_to_tip_table(const struct object_id *oid, const char *refname,\n \t\t\t     int shorten_unambiguous, struct commit *commit,\n \t\t\t     timestamp_t taggerdate, int from_tag, int deref)\n {\n-\trefname = name_ref_abbrev(refname, shorten_unambiguous);\n+\tchar *short_refname = NULL;\n+\n+\tif (shorten_unambiguous)\n+\t\tshort_refname = shorten_unambiguous_ref(refname, 0);\n+\telse if (skip_prefix(refname, \"refs/heads/\", &refname))\n+\t\t; /* refname already advanced */\n+\telse\n+\t\tskip_prefix(refname, \"refs/\", &refname);\n \n \tALLOC_GROW(tip_table.table, tip_table.nr + 1, tip_table.alloc);\n \toidcpy(&tip_table.table[tip_table.nr].oid, oid);\n-\ttip_table.table[tip_table.nr].refname = xstrdup(refname);\n+\ttip_table.table[tip_table.nr].refname = short_refname ?\n+\t\tshort_refname : xstrdup(refname);\n \ttip_table.table[tip_table.nr].commit = commit;\n \ttip_table.table[tip_table.nr].taggerdate = taggerdate;\n \ttip_table.table[tip_table.nr].from_tag = from_tag;\n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470028","messageId":"patch-v3-05.19-5087fb73286-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v3 05/19] various: add missing clear_pathspec(), fix leaks","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:25Z","receivedAt":"2023-01-10T05:44:43Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix memory leaks resulting from a missing clear_pathspec().\n\n- archive.c: Plug a leak in the \"struct archiver_args\", and\n  clear_pathspec() the \"pathspec\" member that the \"parse_pathspec_arg()\"\n  call in this function populates.\n\n- builtin/clean.c: Fix a memory leak that's been with us since\n  893d839970c (clean: convert to use parse_pathspec, 2013-07-14).\n\n- builtin/reset.c: Add clear_pathspec() calls to cmd_reset(),\n  including to the codepaths where we'd return early.\n\n- builtin/stash.c: Call clear_pathspec() on the pathspec initialized\n  in push_stash().\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n archive.c                       |  1 +\n builtin/clean.c                 |  1 +\n builtin/reset.c                 | 11 ++++++++---\n builtin/stash.c                 |  7 +++++--\n t/t5001-archive-attr.sh         |  1 +\n t/t5004-archive-corner-cases.sh |  2 ++\n t/t7105-reset-patch.sh          |  2 ++\n t/t7106-reset-unborn-branch.sh  |  2 ++\n t/t7107-reset-pathspec-file.sh  |  1 +\n t/t7301-clean-interactive.sh    |  1 +\n 10 files changed, 24 insertions(+), 5 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex 941495f5d78..a2d813e50db 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -710,6 +710,7 @@ int write_archive(int argc, const char **argv, const char *prefix,\n \n \tstring_list_clear_func(&args.extra_files, extra_file_info_clear);\n \tfree(args.refname);\n+\tclear_pathspec(&args.pathspec);\n \n \treturn rc;\n }\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex b2701a28158..b15eab328b7 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -1092,5 +1092,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tstrbuf_release(&buf);\n \tstring_list_clear(&del_list, 0);\n \tstring_list_clear(&exclude_list, 0);\n+\tclear_pathspec(&pathspec);\n \treturn (errors != 0);\n }\ndiff --git a/builtin/reset.c b/builtin/reset.c\nindex fea20a9ba0b..e9c10618cd3 100644\n--- a/builtin/reset.c\n+++ b/builtin/reset.c\n@@ -390,7 +390,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \t\tif (reset_type != NONE)\n \t\t\tdie(_(\"options '%s' and '%s' cannot be used together\"), \"--patch\", \"--{hard,mixed,soft}\");\n \t\ttrace2_cmd_mode(\"patch-interactive\");\n-\t\treturn run_add_interactive(rev, \"--patch=reset\", &pathspec);\n+\t\tupdate_ref_status = run_add_interactive(rev, \"--patch=reset\", &pathspec);\n+\t\tgoto cleanup;\n \t}\n \n \t/* git reset tree [--] paths... can be used to\n@@ -439,8 +440,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \t\t\t\t       LOCK_DIE_ON_ERROR);\n \t\tif (reset_type == MIXED) {\n \t\t\tint flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;\n-\t\t\tif (read_from_tree(&pathspec, &oid, intent_to_add))\n-\t\t\t\treturn 1;\n+\t\t\tif (read_from_tree(&pathspec, &oid, intent_to_add)) {\n+\t\t\t\tupdate_ref_status = 1;\n+\t\t\t\tgoto cleanup;\n+\t\t\t}\n \t\t\tthe_index.updated_skipworktree = 1;\n \t\t\tif (!no_refresh && get_git_work_tree()) {\n \t\t\t\tuint64_t t_begin, t_delta_in_ms;\n@@ -488,5 +491,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \n \tdiscard_index(&the_index);\n \n+cleanup:\n+\tclear_pathspec(&pathspec);\n \treturn update_ref_status;\n }\ndiff --git a/builtin/stash.c b/builtin/stash.c\nindex bb0fd861434..45bffdf54bb 100644\n--- a/builtin/stash.c\n+++ b/builtin/stash.c\n@@ -1727,6 +1727,7 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n \t\tOPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),\n \t\tOPT_END()\n \t};\n+\tint ret;\n \n \tif (argc) {\n \t\tforce_assume = !strcmp(argv[0], \"-p\");\n@@ -1766,8 +1767,10 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n \t\tdie(_(\"the option '%s' requires '%s'\"), \"--pathspec-file-nul\", \"--pathspec-from-file\");\n \t}\n \n-\treturn do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n-\t\t\t     include_untracked, only_staged);\n+\tret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n+\t\t\t    include_untracked, only_staged);\n+\tclear_pathspec(&ps);\n+\treturn ret;\n }\n \n static int push_stash_unassumed(int argc, const char **argv, const char *prefix)\ndiff --git a/t/t5001-archive-attr.sh b/t/t5001-archive-attr.sh\nindex 2f6eef5e372..04d300eeda7 100755\n--- a/t/t5001-archive-attr.sh\n+++ b/t/t5001-archive-attr.sh\n@@ -3,6 +3,7 @@\n test_description='git archive attribute tests'\n \n TEST_CREATE_REPO_NO_TEMPLATE=1\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n SUBSTFORMAT='%H (%h)%n'\ndiff --git a/t/t5004-archive-corner-cases.sh b/t/t5004-archive-corner-cases.sh\nindex ae508e21623..9f2c6da80e8 100755\n--- a/t/t5004-archive-corner-cases.sh\n+++ b/t/t5004-archive-corner-cases.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test corner cases of git-archive'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # the 10knuls.tar file is used to test for an empty git generated tar\ndiff --git a/t/t7105-reset-patch.sh b/t/t7105-reset-patch.sh\nindex fc2a6cf5c7a..9b46da7aaa7 100755\n--- a/t/t7105-reset-patch.sh\n+++ b/t/t7105-reset-patch.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git reset --patch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./lib-patch-mode.sh\n \n test_expect_success PERL 'setup' '\ndiff --git a/t/t7106-reset-unborn-branch.sh b/t/t7106-reset-unborn-branch.sh\nindex ecb85c3b823..a0b67a0b843 100755\n--- a/t/t7106-reset-unborn-branch.sh\n+++ b/t/t7106-reset-unborn-branch.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git reset should work on unborn branch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7107-reset-pathspec-file.sh b/t/t7107-reset-pathspec-file.sh\nindex 523efbecde1..af5ea406db3 100755\n--- a/t/t7107-reset-pathspec-file.sh\n+++ b/t/t7107-reset-pathspec-file.sh\n@@ -2,6 +2,7 @@\n \n test_description='reset --pathspec-from-file'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_tick\ndiff --git a/t/t7301-clean-interactive.sh b/t/t7301-clean-interactive.sh\nindex a07e8b86de2..d82a3210a1d 100755\n--- a/t/t7301-clean-interactive.sh\n+++ b/t/t7301-clean-interactive.sh\n@@ -2,6 +2,7 @@\n \n test_description='git clean -i basic tests'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-terminal.sh\n \n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470029","messageId":"patch-v3-08.19-f918a6f2adc-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v3 08/19] worktree: fix a trivial leak in prune_worktrees()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:28Z","receivedAt":"2023-01-10T05:44:46Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"We were leaking both the \"struct strbuf\" in prune_worktrees(), as well\nas the \"path\" we got from should_prune_worktree(). Since these were\nthe only two uses of the \"struct string_list\" let's change it to a\n\"DUP\" and push these to it with \"string_list_append_nodup()\".\n\nFor the string_list_append_nodup() we could also string_list_append()\nthe main_path.buf, and then strbuf_release(&main_path) right away. But\ndoing it this way avoids an allocation, as we already have the \"struct\nstrbuf\" prepared for appending to \"kept\".\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/worktree.c         | 6 +++---\n t/t2401-worktree-prune.sh  | 1 +\n t/t2406-worktree-repair.sh | 1 +\n 3 files changed, 5 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex 591d659faea..865ce9be22b 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -173,7 +173,7 @@ static void prune_worktrees(void)\n {\n \tstruct strbuf reason = STRBUF_INIT;\n \tstruct strbuf main_path = STRBUF_INIT;\n-\tstruct string_list kept = STRING_LIST_INIT_NODUP;\n+\tstruct string_list kept = STRING_LIST_INIT_DUP;\n \tDIR *dir = opendir(git_path(\"worktrees\"));\n \tstruct dirent *d;\n \tif (!dir)\n@@ -184,14 +184,14 @@ static void prune_worktrees(void)\n \t\tif (should_prune_worktree(d->d_name, &reason, &path, expire))\n \t\t\tprune_worktree(d->d_name, reason.buf);\n \t\telse if (path)\n-\t\t\tstring_list_append(&kept, path)->util = xstrdup(d->d_name);\n+\t\t\tstring_list_append_nodup(&kept, path)->util = xstrdup(d->d_name);\n \t}\n \tclosedir(dir);\n \n \tstrbuf_add_absolute_path(&main_path, get_git_common_dir());\n \t/* massage main worktree absolute path to match 'gitdir' content */\n \tstrbuf_strip_suffix(&main_path, \"/.\");\n-\tstring_list_append(&kept, strbuf_detach(&main_path, NULL));\n+\tstring_list_append_nodup(&kept, strbuf_detach(&main_path, NULL));\n \tprune_dups(&kept);\n \tstring_list_clear(&kept, 1);\n \ndiff --git a/t/t2401-worktree-prune.sh b/t/t2401-worktree-prune.sh\nindex 3d28c7f06b2..568a47ec426 100755\n--- a/t/t2401-worktree-prune.sh\n+++ b/t/t2401-worktree-prune.sh\n@@ -5,6 +5,7 @@ test_description='prune $GIT_DIR/worktrees'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success initialize '\ndiff --git a/t/t2406-worktree-repair.sh b/t/t2406-worktree-repair.sh\nindex 5c44453e1c1..8970780efcc 100755\n--- a/t/t2406-worktree-repair.sh\n+++ b/t/t2406-worktree-repair.sh\n@@ -2,6 +2,7 @@\n \n test_description='test git worktree repair'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470030","messageId":"patch-v3-09.19-56204806dfd-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v3 09/19] http-backend.c: fix \"dir\" and \"cmd_arg\" leaks in cmd_main()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:29Z","receivedAt":"2023-01-10T05:44:49Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Free the \"dir\" variable after we're done with it. Before\n917adc03608 (http-backend: add GIT_PROJECT_ROOT environment var,\n2009-10-30) there was no leak here, as we'd get it via getenv(), but\nsince 917adc03608 we've xstrdup()'d it (or the equivalent), so we need\nto free() it.\n\nWe also need to free the \"cmd_arg\" variable, which has been leaked\never since it was added in 2f4038ab337 (Git-aware CGI to provide dumb\nHTTP transport, 2009-10-30).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n http-backend.c | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git a/http-backend.c b/http-backend.c\nindex 6eb3b2fe51c..67819d931ce 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -786,6 +786,7 @@ int cmd_main(int argc, const char **argv)\n \tif (!getenv(\"GIT_HTTP_EXPORT_ALL\") &&\n \t    access(\"git-daemon-export-ok\", F_OK) )\n \t\tnot_found(&hdr, \"Repository not exported: '%s'\", dir);\n+\tfree(dir);\n \n \thttp_config();\n \tmax_request_buffer = git_env_ulong(\"GIT_HTTP_MAX_REQUEST_BUFFER\",\n@@ -795,5 +796,6 @@ int cmd_main(int argc, const char **argv)\n \t\tsetenv(GIT_PROTOCOL_ENVIRONMENT, proto_header, 0);\n \n \tcmd->imp(&hdr, cmd_arg);\n+\tfree(cmd_arg);\n \treturn 0;\n }\n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470031","messageId":"patch-v3-07.19-a3f1e800127-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v3 07/19] repack: fix leaks on error with \"goto cleanup\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:27Z","receivedAt":"2023-01-10T05:44:54Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change cmd_repack() to \"goto cleanup\" rather than \"return ret\" on\nerror, when we returned we'd potentially skip cleaning up the\nstring_lists and other data we'd allocated in this function.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/repack.c                    | 13 +++++++------\n t/t6011-rev-list-with-bad-commit.sh |  1 +\n 2 files changed, 8 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/repack.c b/builtin/repack.c\nindex c1402ad038f..f6493795318 100644\n--- a/builtin/repack.c\n+++ b/builtin/repack.c\n@@ -948,7 +948,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \n \tret = start_command(&cmd);\n \tif (ret)\n-\t\treturn ret;\n+\t\tgoto cleanup;\n \n \tif (geometry) {\n \t\tFILE *in = xfdopen(cmd.in, \"w\");\n@@ -977,7 +977,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \tfclose(out);\n \tret = finish_command(&cmd);\n \tif (ret)\n-\t\treturn ret;\n+\t\tgoto cleanup;\n \n \tif (!names.nr && !po_args.quiet)\n \t\tprintf_ln(_(\"Nothing new to pack.\"));\n@@ -1007,7 +1007,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\t\t\t       &existing_nonkept_packs,\n \t\t\t\t       &existing_kept_packs);\n \t\tif (ret)\n-\t\t\treturn ret;\n+\t\t\tgoto cleanup;\n \n \t\tif (delete_redundant && expire_to) {\n \t\t\t/*\n@@ -1039,7 +1039,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\t\t\t\t       &existing_nonkept_packs,\n \t\t\t\t\t       &existing_kept_packs);\n \t\t\tif (ret)\n-\t\t\t\treturn ret;\n+\t\t\t\tgoto cleanup;\n \t\t}\n \t}\n \n@@ -1115,7 +1115,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\tstring_list_clear(&include, 0);\n \n \t\tif (ret)\n-\t\t\treturn ret;\n+\t\t\tgoto cleanup;\n \t}\n \n \treprepare_packed_git(the_repository);\n@@ -1172,10 +1172,11 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\twrite_midx_file(get_object_directory(), NULL, NULL, flags);\n \t}\n \n+cleanup:\n \tstring_list_clear(&names, 1);\n \tstring_list_clear(&existing_nonkept_packs, 0);\n \tstring_list_clear(&existing_kept_packs, 0);\n \tclear_pack_geometry(geometry);\n \n-\treturn 0;\n+\treturn ret;\n }\ndiff --git a/t/t6011-rev-list-with-bad-commit.sh b/t/t6011-rev-list-with-bad-commit.sh\nindex bad02cf5b83..b2e422cf0f7 100755\n--- a/t/t6011-rev-list-with-bad-commit.sh\n+++ b/t/t6011-rev-list-with-bad-commit.sh\n@@ -2,6 +2,7 @@\n \n test_description='git rev-list should notice bad commits'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Note:\n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470032","messageId":"patch-v3-12.19-e44e74dcc58-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v3 12/19] show-branch: free() allocated \"head\" before return","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:32Z","receivedAt":"2023-01-10T05:44:59Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Stop leaking the \"head\" variable, which we've been leaking since it\nwas originally added in [1], and in its current form since [2]\n\n1. ed378ec7e85 (Make ref resolution saner, 2006-09-11)\n2. d9e557a320b (show-branch: store resolved head in heap buffer,\n   2017-02-14).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/show-branch.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/show-branch.c b/builtin/show-branch.c\nindex c013abaf942..358ac3e519a 100644\n--- a/builtin/show-branch.c\n+++ b/builtin/show-branch.c\n@@ -956,5 +956,6 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)\n \t\tif (shown_merge_point && --extra < 0)\n \t\t\tbreak;\n \t}\n+\tfree(head);\n \treturn 0;\n }\n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470033","messageId":"patch-v3-10.19-5355e0fc60b-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v3 10/19] http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:30Z","receivedAt":"2023-01-10T05:45:01Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us ever since\n2f4038ab337 (Git-aware CGI to provide dumb HTTP transport,\n2009-10-30). In this case we're not calling regerror() after a failed\nregexec(), and don't otherwise use \"re\" afterwards.\n\nWe can therefore simplify this code by calling regfree() right after\nthe regexec(). An alternative fix would be to add a regfree() to both\nthe \"return\" and \"break\" path in this for-loop.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n http-backend.c | 7 +++++--\n 1 file changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/http-backend.c b/http-backend.c\nindex 67819d931ce..8ab58e55f85 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -759,10 +759,14 @@ int cmd_main(int argc, const char **argv)\n \t\tstruct service_cmd *c = &services[i];\n \t\tregex_t re;\n \t\tregmatch_t out[1];\n+\t\tint ret;\n \n \t\tif (regcomp(&re, c->pattern, REG_EXTENDED))\n \t\t\tdie(\"Bogus regex in service table: %s\", c->pattern);\n-\t\tif (!regexec(&re, dir, 1, out, 0)) {\n+\t\tret = regexec(&re, dir, 1, out, 0);\n+\t\tregfree(&re);\n+\n+\t\tif (!ret) {\n \t\t\tsize_t n;\n \n \t\t\tif (strcmp(method, c->method))\n@@ -774,7 +778,6 @@ int cmd_main(int argc, const char **argv)\n \t\t\tdir[out[0].rm_so] = 0;\n \t\t\tbreak;\n \t\t}\n-\t\tregfree(&re);\n \t}\n \n \tif (!cmd)\n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470034","messageId":"patch-v3-11.19-dfb52dbd1c4-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v3 11/19] commit-graph: fix a parse_options_concat() leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:31Z","receivedAt":"2023-01-10T05:45:04Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the parse_options_concat() was added to this file in\n84e4484f128 (commit-graph: use parse_options_concat(), 2021-08-23) we\nwouldn't free() it if we returned early in these cases.\n\nSince \"result\" is 0 by default we can \"goto cleanup\" in both cases,\nand only need to set \"result\" if write_commit_graph_reachable() fails.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/commit-graph.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/commit-graph.c b/builtin/commit-graph.c\nindex 0102ac8540e..93704f95a9d 100644\n--- a/builtin/commit-graph.c\n+++ b/builtin/commit-graph.c\n@@ -269,8 +269,8 @@ static int graph_write(int argc, const char **argv, const char *prefix)\n \n \tif (opts.reachable) {\n \t\tif (write_commit_graph_reachable(odb, flags, &write_opts))\n-\t\t\treturn 1;\n-\t\treturn 0;\n+\t\t\tresult = 1;\n+\t\tgoto cleanup;\n \t}\n \n \tif (opts.stdin_packs) {\n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470035","messageId":"patch-v3-13.19-6d99fdcc44e-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v3 13/19] builtin/merge.c: always free \"struct strbuf msg\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:33Z","receivedAt":"2023-01-10T05:45:06Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Follow-up 465028e0e25 (merge: add missing strbuf_release(),\n2021-10-07) and address the \"msg\" memory leak in this block. We could\nfree \"&msg\" before the \"goto done\" here, but even better is to avoid\nallocating it in the first place.\n\nBy repeating the \"Fast-forward\" string here we can avoid using a\n\"struct strbuf\" altogether.\n\nSuggested-by: René Scharfe <l.s.r@web.de>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/merge.c                | 11 ++++-------\n t/t6439-merge-co-error-msgs.sh |  1 +\n 2 files changed, 5 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 0f093f2a4f2..91dd5435c59 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -1560,7 +1560,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t!common->next &&\n \t\t\toideq(&common->item->object.oid, &head_commit->object.oid)) {\n \t\t/* Again the most common case of merging one remote. */\n-\t\tstruct strbuf msg = STRBUF_INIT;\n+\t\tconst char *msg = have_message ?\n+\t\t\t\"Fast-forward (no commit created; -m option ignored)\" :\n+\t\t\t\"Fast-forward\";\n \t\tstruct commit *commit;\n \n \t\tif (verbosity >= 0) {\n@@ -1570,10 +1572,6 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t       find_unique_abbrev(&remoteheads->item->object.oid,\n \t\t\t\t\t\t  DEFAULT_ABBREV));\n \t\t}\n-\t\tstrbuf_addstr(&msg, \"Fast-forward\");\n-\t\tif (have_message)\n-\t\t\tstrbuf_addstr(&msg,\n-\t\t\t\t\" (no commit created; -m option ignored)\");\n \t\tcommit = remoteheads->item;\n \t\tif (!commit) {\n \t\t\tret = 1;\n@@ -1592,9 +1590,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\tgoto done;\n \t\t}\n \n-\t\tfinish(head_commit, remoteheads, &commit->object.oid, msg.buf);\n+\t\tfinish(head_commit, remoteheads, &commit->object.oid, msg);\n \t\tremove_merge_branch_state(the_repository);\n-\t\tstrbuf_release(&msg);\n \t\tgoto done;\n \t} else if (!remoteheads->next && common->next)\n \t\t;\ndiff --git a/t/t6439-merge-co-error-msgs.sh b/t/t6439-merge-co-error-msgs.sh\nindex 52cf0c87690..0cbec57cdab 100755\n--- a/t/t6439-merge-co-error-msgs.sh\n+++ b/t/t6439-merge-co-error-msgs.sh\n@@ -5,6 +5,7 @@ test_description='unpack-trees error messages'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n \n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470036","messageId":"patch-v3-14.19-a3bf3045597-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v3 14/19] builtin/merge.c: free \"&buf\" on \"Your local changes...\" error","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:34Z","receivedAt":"2023-01-10T05:45:11Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Plug a memory leak introduced in [1], since that change didn't follow\nthe \"goto done\" pattern introduced in [2] we'd leak the \"&buf\" memory.\n\n1. e4cdfe84a0d (merge: abort if index does not match HEAD for trivial\n   merges, 2022-07-23)\n2. d5a35c114ab (Copy resolve_ref() return value for longer use,\n   2011-11-13)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/merge.c | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 91dd5435c59..2b13124c497 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -1618,7 +1618,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t\terror(_(\"Your local changes to the following files would be overwritten by merge:\\n  %s\"),\n \t\t\t\t      sb.buf);\n \t\t\t\tstrbuf_release(&sb);\n-\t\t\t\treturn 2;\n+\t\t\t\tret = 2;\n+\t\t\t\tgoto done;\n \t\t\t}\n \n \t\t\t/* See if it is really trivial. */\n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470037","messageId":"patch-v3-15.19-7c70bbdebc8-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v3 15/19] object-file.c: release the \"tag\" in check_tag()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:35Z","receivedAt":"2023-01-10T05:45:18Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us ever since c879daa2372 (Make\nhash-object more robust against malformed objects, 2011-02-05). With\n\"HASH_FORMAT_CHECK\" (used by \"hash-object\" and \"replace\") we'll parse\ntags into a throwaway variable on the stack, but weren't freeing the\n\"item->tag\" we might malloc() when doing so.\n\nThe clearing that release_tag_memory() does for us is redundant here,\nbut let's use it as-is anyway. It only has one other existing caller,\nwhich does need the tag to be cleared.\n\nMark the tests that now pass in their entirety as passing under\n\"SANITIZE=leak\", which means we'll test them as part of the\n\"linux-leaks\" CI job.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n object-file.c         | 1 +\n t/t3800-mktag.sh      | 1 +\n t/t5302-pack-index.sh | 2 ++\n 3 files changed, 4 insertions(+)\n\ndiff --git a/object-file.c b/object-file.c\nindex 80a0cd3b351..b554266aff4 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -2324,6 +2324,7 @@ static void check_tag(const void *buf, size_t size)\n \tmemset(&t, 0, sizeof(t));\n \tif (parse_tag_buffer(the_repository, &t, buf, size))\n \t\tdie(_(\"corrupt tag\"));\n+\trelease_tag_memory(&t);\n }\n \n static int index_mem(struct index_state *istate,\ndiff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh\nindex e3cf0ffbe59..d3e428ff46e 100755\n--- a/t/t3800-mktag.sh\n+++ b/t/t3800-mktag.sh\n@@ -4,6 +4,7 @@\n \n test_description='git mktag: tag object verify test'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n ###########################################################\ndiff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh\nindex b0095ab41d3..54b11f81c63 100755\n--- a/t/t5302-pack-index.sh\n+++ b/t/t5302-pack-index.sh\n@@ -4,6 +4,8 @@\n #\n \n test_description='pack index with 64-bit offsets and object CRC'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470038","messageId":"patch-v3-16.19-17537e1393e-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v3 16/19] grep.c: refactor free_grep_patterns()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:36Z","receivedAt":"2023-01-10T05:45:23Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Refactor the free_grep_patterns() function to split out the freeing of\nthe \"struct grep_pat\" it contains, right now we're only freeing the\n\"pattern_list\", but we should be freeing another member of the same\ntype, which we'll do in the subsequent commit.\n\nLet's also replace the \"return\" if we don't have an\n\"opt->pattern_expression\" with a conditional call of\nfree_pattern_expr().\n\nBefore db84376f981 (grep.c: remove \"extended\" in favor of\n\"pattern_expression\", fix segfault, 2022-10-11) the pattern here was:\n\n\tif (!x)\n\t\treturn;\n\tfree(y);\n\nBut after the cleanup in db84376f981 (which was a narrow segfault fix,\nand thus avoided refactoring this) we ended up with:\n\n\tif (!x)\n\t\treturn;\n\tfree(x);\n\nLet's instead do:\n\n\tif (x)\n\t\tfree(x);\n\nThis doesn't matter for the subsequent change, but as we're\nrefactoring this function let's make it easier to reason about, and to\nextend in the future, i.e. if we start to free free() members that\ncome after \"pattern_expression\" in the \"struct grep_opt\".\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n grep.c | 14 +++++++++-----\n 1 file changed, 9 insertions(+), 5 deletions(-)\n\ndiff --git a/grep.c b/grep.c\nindex 06eed694936..a4450df4559 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -769,11 +769,11 @@ static void free_pattern_expr(struct grep_expr *x)\n \tfree(x);\n }\n \n-void free_grep_patterns(struct grep_opt *opt)\n+static void free_grep_pat(struct grep_pat *pattern)\n {\n \tstruct grep_pat *p, *n;\n \n-\tfor (p = opt->pattern_list; p; p = n) {\n+\tfor (p = pattern; p; p = n) {\n \t\tn = p->next;\n \t\tswitch (p->token) {\n \t\tcase GREP_PATTERN: /* atom */\n@@ -790,10 +790,14 @@ void free_grep_patterns(struct grep_opt *opt)\n \t\t}\n \t\tfree(p);\n \t}\n+}\n \n-\tif (!opt->pattern_expression)\n-\t\treturn;\n-\tfree_pattern_expr(opt->pattern_expression);\n+void free_grep_patterns(struct grep_opt *opt)\n+{\n+\tfree_grep_pat(opt->pattern_list);\n+\n+\tif (opt->pattern_expression)\n+\t\tfree_pattern_expr(opt->pattern_expression);\n }\n \n static const char *end_of_line(const char *cp, unsigned long *left)\n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470039","messageId":"patch-v3-17.19-e4bd46a343e-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v3 17/19] grep API: plug memory leaks by freeing \"header_list\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:37Z","receivedAt":"2023-01-10T05:45:27Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the \"header_list\" struct member was added in [1] it wasn't made\nto free the list using loop added for the adjacent \"pattern_list\"\nmember, see [2] for when we started freeing it.\n\nThis makes e.g. this command leak-free when run on git.git:\n\n\t./git -P log -1 --color=always --author=A origin/master\n\n1. 80235ba79ef (\"log --author=me --grep=it\" should find intersection,\n   not union, 2010-01-17)\n2. b48fb5b6a95 (grep: free expressions and patterns when done.,\n   2006-09-27)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n grep.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/grep.c b/grep.c\nindex a4450df4559..c908535e0d8 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -795,6 +795,7 @@ static void free_grep_pat(struct grep_pat *pattern)\n void free_grep_patterns(struct grep_opt *opt)\n {\n \tfree_grep_pat(opt->pattern_list);\n+\tfree_grep_pat(opt->header_list);\n \n \tif (opt->pattern_expression)\n \t\tfree_pattern_expr(opt->pattern_expression);\n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470040","messageId":"patch-v3-18.19-3e4b12cb623-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v3 18/19] receive-pack: free() the \"ref_name\" in \"struct command\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:38Z","receivedAt":"2023-01-10T05:45:32Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us since this code was introduced\nin 575f497456e (Add first cut at \"git-receive-pack\", 2005-06-29), see\neb1af2df0b1 (git-receive-pack: start parsing ref update commands,\n2005-06-29) for the later change that refactored the code to add the\n\"ref_name\" member.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/receive-pack.c                | 10 ++++++++++\n t/t5405-send-pack-rewind.sh           |  1 +\n t/t5406-remote-rejects.sh             |  1 +\n t/t5507-remote-environment.sh         |  2 ++\n t/t5522-pull-symlink.sh               |  1 +\n t/t5527-fetch-odd-refs.sh             |  1 +\n t/t5705-session-id-in-capabilities.sh |  1 +\n 7 files changed, 17 insertions(+)\n\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex a90af303630..451bad776c6 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -2032,6 +2032,15 @@ static struct command **queue_command(struct command **tail,\n \treturn &cmd->next;\n }\n \n+static void free_commands(struct command *commands)\n+{\n+\twhile (commands) {\n+\t\tstruct command *next = commands->next;\n+\t\tfree(commands);\n+\t\tcommands = next;\n+\t}\n+}\n+\n static void queue_commands_from_cert(struct command **tail,\n \t\t\t\t     struct strbuf *push_cert)\n {\n@@ -2569,6 +2578,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n \t\trun_receive_hook(commands, \"post-receive\", 1,\n \t\t\t\t &push_options);\n \t\trun_update_post_hook(commands);\n+\t\tfree_commands(commands);\n \t\tstring_list_clear(&push_options, 0);\n \t\tif (auto_gc) {\n \t\t\tstruct child_process proc = CHILD_PROCESS_INIT;\ndiff --git a/t/t5405-send-pack-rewind.sh b/t/t5405-send-pack-rewind.sh\nindex 11f03239a06..1686ac13aa6 100755\n--- a/t/t5405-send-pack-rewind.sh\n+++ b/t/t5405-send-pack-rewind.sh\n@@ -5,6 +5,7 @@ test_description='forced push to replace commit we do not have'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5406-remote-rejects.sh b/t/t5406-remote-rejects.sh\nindex dcbeb420827..d6a99466338 100755\n--- a/t/t5406-remote-rejects.sh\n+++ b/t/t5406-remote-rejects.sh\n@@ -2,6 +2,7 @@\n \n test_description='remote push rejects are reported by client'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t5507-remote-environment.sh b/t/t5507-remote-environment.sh\nindex e6149295b18..c6a6957c500 100755\n--- a/t/t5507-remote-environment.sh\n+++ b/t/t5507-remote-environment.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check environment showed to remote side of transports'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'set up \"remote\" push situation' '\ndiff --git a/t/t5522-pull-symlink.sh b/t/t5522-pull-symlink.sh\nindex bcff460d0a2..394bc60cb8e 100755\n--- a/t/t5522-pull-symlink.sh\n+++ b/t/t5522-pull-symlink.sh\n@@ -2,6 +2,7 @@\n \n test_description='pulling from symlinked subdir'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # The scenario we are building:\ndiff --git a/t/t5527-fetch-odd-refs.sh b/t/t5527-fetch-odd-refs.sh\nindex e2770e4541f..98ece27c6a0 100755\n--- a/t/t5527-fetch-odd-refs.sh\n+++ b/t/t5527-fetch-odd-refs.sh\n@@ -4,6 +4,7 @@ test_description='test fetching of oddly-named refs'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # afterwards we will have:\ndiff --git a/t/t5705-session-id-in-capabilities.sh b/t/t5705-session-id-in-capabilities.sh\nindex ed38c76c290..b8a722ec27e 100755\n--- a/t/t5705-session-id-in-capabilities.sh\n+++ b/t/t5705-session-id-in-capabilities.sh\n@@ -2,6 +2,7 @@\n \n test_description='session ID in capabilities'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n REPO=\"$(pwd)/repo\"\n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470041","messageId":"patch-v3-19.19-d51ed239a8a-20230110T054138Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v3 19/19] push: free_refs() the \"local_refs\" in set_refspecs()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-10T05:43:39Z","receivedAt":"2023-01-10T05:45:34Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us since this code was added in\nca02465b413 (push: use remote.$name.push as a refmap, 2013-12-03).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/push.c                          | 1 +\n t/t1416-ref-transaction-hooks.sh        | 1 +\n t/t5504-fetch-receive-strict.sh         | 1 +\n t/t5523-push-upstream.sh                | 1 +\n t/t5529-push-errors.sh                  | 2 ++\n t/t5546-receive-limits.sh               | 2 ++\n t/t5547-push-quarantine.sh              | 2 ++\n t/t5606-clone-options.sh                | 1 +\n t/t5810-proto-disable-local.sh          | 2 ++\n t/t5813-proto-disable-ssh.sh            | 2 ++\n t/t7409-submodule-detached-work-tree.sh | 1 +\n t/t7416-submodule-dash-url.sh           | 2 ++\n t/t7450-bad-git-dotfiles.sh             | 2 ++\n 13 files changed, 20 insertions(+)\n\ndiff --git a/builtin/push.c b/builtin/push.c\nindex 60ac8017e52..f48e4c6a856 100644\n--- a/builtin/push.c\n+++ b/builtin/push.c\n@@ -129,6 +129,7 @@ static void set_refspecs(const char **refs, int nr, const char *repo)\n \t\t} else\n \t\t\trefspec_append(&rs, ref);\n \t}\n+\tfree_refs(local_refs);\n }\n \n static int push_url_of_remote(struct remote *remote, const char ***url_p)\ndiff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh\nindex 27731722a5b..b32ca798f9f 100755\n--- a/t/t1416-ref-transaction-hooks.sh\n+++ b/t/t1416-ref-transaction-hooks.sh\n@@ -5,6 +5,7 @@ test_description='reference transaction hooks'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh\nindex ac4099ca893..14e8af1f3b7 100755\n--- a/t/t5504-fetch-receive-strict.sh\n+++ b/t/t5504-fetch-receive-strict.sh\n@@ -4,6 +4,7 @@ test_description='fetch/receive strict mode'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup and inject \"corrupt or missing\" object' '\ndiff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh\nindex fdb42920564..c9acc076353 100755\n--- a/t/t5523-push-upstream.sh\n+++ b/t/t5523-push-upstream.sh\n@@ -4,6 +4,7 @@ test_description='push with --set-upstream'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-terminal.sh\n \ndiff --git a/t/t5529-push-errors.sh b/t/t5529-push-errors.sh\nindex ce85fd30ad1..0247137cb36 100755\n--- a/t/t5529-push-errors.sh\n+++ b/t/t5529-push-errors.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='detect some push errors early (before contacting remote)'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup commits' '\ndiff --git a/t/t5546-receive-limits.sh b/t/t5546-receive-limits.sh\nindex 0b0e987fdb7..eed3c9d81ab 100755\n--- a/t/t5546-receive-limits.sh\n+++ b/t/t5546-receive-limits.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check receive input limits'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Let's run tests with different unpack limits: 1 and 10000\ndiff --git a/t/t5547-push-quarantine.sh b/t/t5547-push-quarantine.sh\nindex 1876fb34e51..9f899b8c7d7 100755\n--- a/t/t5547-push-quarantine.sh\n+++ b/t/t5547-push-quarantine.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check quarantine of objects during push'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'create picky dest repo' '\ndiff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh\nindex cf221e92c4d..27f9f776389 100755\n--- a/t/t5606-clone-options.sh\n+++ b/t/t5606-clone-options.sh\n@@ -4,6 +4,7 @@ test_description='basic clone options'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t5810-proto-disable-local.sh b/t/t5810-proto-disable-local.sh\nindex c1ef99b85c2..862610256fb 100755\n--- a/t/t5810-proto-disable-local.sh\n+++ b/t/t5810-proto-disable-local.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test disabling of local paths in clone/fetch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY/lib-proto-disable.sh\"\n \ndiff --git a/t/t5813-proto-disable-ssh.sh b/t/t5813-proto-disable-ssh.sh\nindex 3f084ee3065..2e975dc70ec 100755\n--- a/t/t5813-proto-disable-ssh.sh\n+++ b/t/t5813-proto-disable-ssh.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test disabling of git-over-ssh in clone/fetch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY/lib-proto-disable.sh\"\n \ndiff --git a/t/t7409-submodule-detached-work-tree.sh b/t/t7409-submodule-detached-work-tree.sh\nindex 374ed481e9c..574a6fc526e 100755\n--- a/t/t7409-submodule-detached-work-tree.sh\n+++ b/t/t7409-submodule-detached-work-tree.sh\n@@ -13,6 +13,7 @@ TEST_NO_CREATE_REPO=1\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7416-submodule-dash-url.sh b/t/t7416-submodule-dash-url.sh\nindex 3ebd9859814..7cf72b9a076 100755\n--- a/t/t7416-submodule-dash-url.sh\n+++ b/t/t7416-submodule-dash-url.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check handling of disallowed .gitmodule urls'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7450-bad-git-dotfiles.sh b/t/t7450-bad-git-dotfiles.sh\nindex ba1f569bcbb..0d0c3f2c683 100755\n--- a/t/t7450-bad-git-dotfiles.sh\n+++ b/t/t7450-bad-git-dotfiles.sh\n@@ -12,6 +12,8 @@ Such as:\n \n   - symlinked .gitmodules, etc\n '\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-pack.sh\n \n-- \n2.39.0.1195.gabc92c078c4\n\n"},{"id":"470076","messageId":"71e7d424-b785-9f9e-8b09-955b56fa19b0@web.de","threadId":"59011","inReplyTo":"patch-v3-13.19-6d99fdcc44e-20230110T054138Z-avarab@gmail.com","subject":"Re: [PATCH v3 13/19] builtin/merge.c: always free \"struct strbuf msg\"","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2023-01-10T18:52:27Z","receivedAt":"2023-01-10T18:55:49Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 10.01.23 um 06:43 schrieb Ævar Arnfjörð Bjarmason:\n> Follow-up 465028e0e25 (merge: add missing strbuf_release(),\n> 2021-10-07) and address the \"msg\" memory leak in this block. We could\n> free \"&msg\" before the \"goto done\" here, but even better is to avoid\n> allocating it in the first place.\n\nSo contrary to the subject we don't need to free it anymore.\n\n>\n> By repeating the \"Fast-forward\" string here we can avoid using a\n> \"struct strbuf\" altogether.\n>\n> Suggested-by: René Scharfe <l.s.r@web.de>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  builtin/merge.c                | 11 ++++-------\n>  t/t6439-merge-co-error-msgs.sh |  1 +\n>  2 files changed, 5 insertions(+), 7 deletions(-)\n>\n> diff --git a/builtin/merge.c b/builtin/merge.c\n> index 0f093f2a4f2..91dd5435c59 100644\n> --- a/builtin/merge.c\n> +++ b/builtin/merge.c\n> @@ -1560,7 +1560,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n>  \t\t\t!common->next &&\n>  \t\t\toideq(&common->item->object.oid, &head_commit->object.oid)) {\n>  \t\t/* Again the most common case of merging one remote. */\n> -\t\tstruct strbuf msg = STRBUF_INIT;\n> +\t\tconst char *msg = have_message ?\n> +\t\t\t\"Fast-forward (no commit created; -m option ignored)\" :\n> +\t\t\t\"Fast-forward\";\n>  \t\tstruct commit *commit;\n>\n>  \t\tif (verbosity >= 0) {\n> @@ -1570,10 +1572,6 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n>  \t\t\t       find_unique_abbrev(&remoteheads->item->object.oid,\n>  \t\t\t\t\t\t  DEFAULT_ABBREV));\n>  \t\t}\n> -\t\tstrbuf_addstr(&msg, \"Fast-forward\");\n> -\t\tif (have_message)\n> -\t\t\tstrbuf_addstr(&msg,\n> -\t\t\t\t\" (no commit created; -m option ignored)\");\n>  \t\tcommit = remoteheads->item;\n>  \t\tif (!commit) {\n>  \t\t\tret = 1;\n> @@ -1592,9 +1590,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n>  \t\t\tgoto done;\n>  \t\t}\n>\n> -\t\tfinish(head_commit, remoteheads, &commit->object.oid, msg.buf);\n> +\t\tfinish(head_commit, remoteheads, &commit->object.oid, msg);\n>  \t\tremove_merge_branch_state(the_repository);\n> -\t\tstrbuf_release(&msg);\n>  \t\tgoto done;\n>  \t} else if (!remoteheads->next && common->next)\n>  \t\t;\n> diff --git a/t/t6439-merge-co-error-msgs.sh b/t/t6439-merge-co-error-msgs.sh\n> index 52cf0c87690..0cbec57cdab 100755\n> --- a/t/t6439-merge-co-error-msgs.sh\n> +++ b/t/t6439-merge-co-error-msgs.sh\n> @@ -5,6 +5,7 @@ test_description='unpack-trees error messages'\n>  GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n>  export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n>\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>\n"},{"id":"470302","messageId":"xmqqcz7i2on4.fsf@gitster.g","threadId":"59011","inReplyTo":"71e7d424-b785-9f9e-8b09-955b56fa19b0@web.de","subject":"Re: [PATCH v3 13/19] builtin/merge.c: always free \"struct strbuf msg\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-01-13T19:57:51Z","receivedAt":"2023-01-13T19:58:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"René Scharfe <l.s.r@web.de> writes:\n\n> Am 10.01.23 um 06:43 schrieb Ævar Arnfjörð Bjarmason:\n>> Follow-up 465028e0e25 (merge: add missing strbuf_release(),\n>> 2021-10-07) and address the \"msg\" memory leak in this block. We could\n>> free \"&msg\" before the \"goto done\" here, but even better is to avoid\n>> allocating it in the first place.\n>\n> So contrary to the subject we don't need to free it anymore.\n\n;-)  I appreciate such careful reading.\n"},{"id":"470503","messageId":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com","subject":"[PATCH v4 00/19] leak fixes: various simple leak fixes","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:05Z","receivedAt":"2023-01-17T17:11:35Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"See\nhttps://lore.kernel.org/git/cover-v3-00.19-00000000000-20230110T054138Z-avarab@gmail.com/\nfor the v3. Change since then:\n\n * Reword the subject of a commit message that no longer matched its\n   content/body (thanks René).\n\n * Re-ran \"GIT_TEST_PASSING_SANITIZE_LEAK=check\n   GIT_TEST_SANITIZE_LEAK_LOG=true make SANITIZE=leak test\" with \"git\n   rebase -i -x\", so and updated the leak markings for other fixes\n   that have landed on \"master\" since they were last updated. The tip\n   of this (and all intermediate commits) pass the \"check\" mode.\n\nÆvar Arnfjörð Bjarmason (19):\n  tests: mark tests as passing with SANITIZE=leak\n  bundle.c: don't leak the \"args\" in the \"struct child_process\"\n  commit-graph: use free_commit_graph() instead of UNLEAK()\n  clone: use free() instead of UNLEAK()\n  various: add missing clear_pathspec(), fix leaks\n  name-rev: don't xstrdup() an already dup'd string\n  repack: fix leaks on error with \"goto cleanup\"\n  worktree: fix a trivial leak in prune_worktrees()\n  http-backend.c: fix \"dir\" and \"cmd_arg\" leaks in cmd_main()\n  http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()\n  commit-graph: fix a parse_options_concat() leak\n  show-branch: free() allocated \"head\" before return\n  builtin/merge.c: use fixed strings, not \"strbuf\", fix leak\n  builtin/merge.c: free \"&buf\" on \"Your local changes...\" error\n  object-file.c: release the \"tag\" in check_tag()\n  grep.c: refactor free_grep_patterns()\n  grep API: plug memory leaks by freeing \"header_list\"\n  receive-pack: free() the \"ref_name\" in \"struct command\"\n  push: free_refs() the \"local_refs\" in set_refspecs()\n\n archive.c                                  |  1 +\n builtin/clean.c                            |  1 +\n builtin/clone.c                            |  5 +++--\n builtin/commit-graph.c                     | 10 ++++++----\n builtin/merge.c                            | 14 ++++++-------\n builtin/name-rev.c                         | 23 ++++++++++------------\n builtin/push.c                             |  1 +\n builtin/receive-pack.c                     | 10 ++++++++++\n builtin/repack.c                           | 13 ++++++------\n builtin/reset.c                            | 11 ++++++++---\n builtin/show-branch.c                      |  1 +\n builtin/stash.c                            |  7 +++++--\n builtin/worktree.c                         |  6 +++---\n bundle.c                                   |  6 ++++--\n grep.c                                     | 15 +++++++++-----\n http-backend.c                             |  9 +++++++--\n object-file.c                              |  1 +\n t/t0023-crlf-am.sh                         |  1 +\n t/t1301-shared-repo.sh                     |  1 +\n t/t1302-repo-version.sh                    |  1 +\n t/t1304-default-acl.sh                     |  1 +\n t/t1408-packed-refs.sh                     |  1 +\n t/t1410-reflog.sh                          |  1 +\n t/t1416-ref-transaction-hooks.sh           |  1 +\n t/t2401-worktree-prune.sh                  |  1 +\n t/t2402-worktree-list.sh                   |  1 +\n t/t2406-worktree-repair.sh                 |  1 +\n t/t3203-branch-output.sh                   |  2 ++\n t/t3210-pack-refs.sh                       |  1 +\n t/t3800-mktag.sh                           |  1 +\n t/t4152-am-subjects.sh                     |  2 ++\n t/t4254-am-corrupt.sh                      |  2 ++\n t/t4256-am-format-flowed.sh                |  1 +\n t/t4257-am-interactive.sh                  |  2 ++\n t/t5001-archive-attr.sh                    |  1 +\n t/t5004-archive-corner-cases.sh            |  2 ++\n t/t5302-pack-index.sh                      |  2 ++\n t/t5317-pack-objects-filter-objects.sh     |  1 +\n t/t5330-no-lazy-fetch-with-commit-graph.sh |  1 +\n t/t5403-post-checkout-hook.sh              |  1 +\n t/t5405-send-pack-rewind.sh                |  1 +\n t/t5406-remote-rejects.sh                  |  1 +\n t/t5502-quickfetch.sh                      |  1 +\n t/t5504-fetch-receive-strict.sh            |  1 +\n t/t5507-remote-environment.sh              |  2 ++\n t/t5522-pull-symlink.sh                    |  1 +\n t/t5523-push-upstream.sh                   |  1 +\n t/t5527-fetch-odd-refs.sh                  |  1 +\n t/t5529-push-errors.sh                     |  2 ++\n t/t5546-receive-limits.sh                  |  2 ++\n t/t5547-push-quarantine.sh                 |  2 ++\n t/t5560-http-backend-noserver.sh           |  1 +\n t/t5561-http-backend.sh                    |  1 +\n t/t5562-http-backend-content-length.sh     |  2 ++\n t/t5604-clone-reference.sh                 |  1 +\n t/t5606-clone-options.sh                   |  1 +\n t/t5613-info-alternate.sh                  |  2 ++\n t/t5705-session-id-in-capabilities.sh      |  1 +\n t/t5810-proto-disable-local.sh             |  2 ++\n t/t5813-proto-disable-ssh.sh               |  2 ++\n t/t6011-rev-list-with-bad-commit.sh        |  1 +\n t/t6014-rev-list-all.sh                    |  1 +\n t/t6021-rev-list-exclude-hidden.sh         |  1 +\n t/t6439-merge-co-error-msgs.sh             |  1 +\n t/t7105-reset-patch.sh                     |  2 ++\n t/t7106-reset-unborn-branch.sh             |  2 ++\n t/t7107-reset-pathspec-file.sh             |  1 +\n t/t7301-clean-interactive.sh               |  1 +\n t/t7403-submodule-sync.sh                  |  1 +\n t/t7409-submodule-detached-work-tree.sh    |  1 +\n t/t7416-submodule-dash-url.sh              |  2 ++\n t/t7450-bad-git-dotfiles.sh                |  2 ++\n t/t7701-repack-unpack-unreachable.sh       |  1 +\n 73 files changed, 158 insertions(+), 50 deletions(-)\n\nRange-diff against v3:\n 1:  f5b67f44e2d =  1:  2ed69e3cda3 tests: mark tests as passing with SANITIZE=leak\n 2:  88c6b66be3c =  2:  9993786ba0d bundle.c: don't leak the \"args\" in the \"struct child_process\"\n 3:  8cc8060cd92 =  3:  8e98d7c4ebf commit-graph: use free_commit_graph() instead of UNLEAK()\n 4:  765d5cbcf81 =  4:  966d7657d54 clone: use free() instead of UNLEAK()\n 5:  5087fb73286 =  5:  93a8f8fa1b9 various: add missing clear_pathspec(), fix leaks\n 6:  39cb8aefb58 =  6:  bd15d991ac7 name-rev: don't xstrdup() an already dup'd string\n 7:  a3f1e800127 =  7:  fd890121ebe repack: fix leaks on error with \"goto cleanup\"\n 8:  f918a6f2adc !  8:  1fe25bc6981 worktree: fix a trivial leak in prune_worktrees()\n    @@ t/t2406-worktree-repair.sh\n      . ./test-lib.sh\n      \n      test_expect_success setup '\n    +\n    + ## t/t3203-branch-output.sh ##\n    +@@\n    + #!/bin/sh\n    + \n    + test_description='git branch display tests'\n    ++\n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + . \"$TEST_DIRECTORY\"/lib-terminal.sh\n    + \n 9:  56204806dfd =  9:  6b3dd9b15f0 http-backend.c: fix \"dir\" and \"cmd_arg\" leaks in cmd_main()\n10:  5355e0fc60b = 10:  246f71bb447 http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()\n11:  dfb52dbd1c4 = 11:  ab31d8d10da commit-graph: fix a parse_options_concat() leak\n12:  e44e74dcc58 = 12:  9054b353220 show-branch: free() allocated \"head\" before return\n13:  6d99fdcc44e ! 13:  05836b08e0f builtin/merge.c: always free \"struct strbuf msg\"\n    @@ Metadata\n     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## Commit message ##\n    -    builtin/merge.c: always free \"struct strbuf msg\"\n    +    builtin/merge.c: use fixed strings, not \"strbuf\", fix leak\n     \n         Follow-up 465028e0e25 (merge: add missing strbuf_release(),\n         2021-10-07) and address the \"msg\" memory leak in this block. We could\n14:  a3bf3045597 = 14:  e8ea18b08c2 builtin/merge.c: free \"&buf\" on \"Your local changes...\" error\n15:  7c70bbdebc8 = 15:  66c24afb893 object-file.c: release the \"tag\" in check_tag()\n16:  17537e1393e = 16:  52744d9690f grep.c: refactor free_grep_patterns()\n17:  e4bd46a343e = 17:  8ff63d9095c grep API: plug memory leaks by freeing \"header_list\"\n18:  3e4b12cb623 ! 18:  0ad7d59b881 receive-pack: free() the \"ref_name\" in \"struct command\"\n    @@ t/t5527-fetch-odd-refs.sh: test_description='test fetching of oddly-named refs'\n      \n      # afterwards we will have:\n     \n    + ## t/t5560-http-backend-noserver.sh ##\n    +@@ t/t5560-http-backend-noserver.sh: test_description='test git-http-backend-noserver'\n    + GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n    + export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n    + \n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + \n    + HTTPD_DOCUMENT_ROOT_PATH=\"$TRASH_DIRECTORY\"\n    +\n    + ## t/t5561-http-backend.sh ##\n    +@@ t/t5561-http-backend.sh: test_description='test git-http-backend'\n    + GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n    + export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n    + \n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + . \"$TEST_DIRECTORY\"/lib-httpd.sh\n    + \n    +\n    + ## t/t5562-http-backend-content-length.sh ##\n    +@@\n    + #!/bin/sh\n    + \n    + test_description='test git-http-backend respects CONTENT_LENGTH'\n    ++\n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + \n    + test_lazy_prereq GZIP 'gzip --version'\n    +\n      ## t/t5705-session-id-in-capabilities.sh ##\n     @@\n      \n19:  d51ed239a8a ! 19:  b3aee41d0b4 push: free_refs() the \"local_refs\" in set_refspecs()\n    @@ t/t1416-ref-transaction-hooks.sh: test_description='reference transaction hooks'\n      \n      test_expect_success setup '\n     \n    + ## t/t2402-worktree-list.sh ##\n    +@@ t/t2402-worktree-list.sh: test_description='test git worktree list'\n    + GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n    + export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n    + \n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + \n    + test_expect_success 'setup' '\n    +\n      ## t/t5504-fetch-receive-strict.sh ##\n     @@ t/t5504-fetch-receive-strict.sh: test_description='fetch/receive strict mode'\n      GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470504","messageId":"patch-v4-03.19-8e98d7c4ebf-20230117T151202Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v4 03/19] commit-graph: use free_commit_graph() instead of UNLEAK()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:08Z","receivedAt":"2023-01-17T17:11:38Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"In 0bfb48e6723 (builtin/commit-graph.c: UNLEAK variables, 2018-10-03)\nthis was made to UNLEAK(), but we can just as easily invoke the\nfree_commit_graph() function added in c3756d5b7fc (commit-graph: add\nfree_commit_graph, 2018-07-11) instead.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/commit-graph.c | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/commit-graph.c b/builtin/commit-graph.c\nindex e8f77f535f3..0102ac8540e 100644\n--- a/builtin/commit-graph.c\n+++ b/builtin/commit-graph.c\n@@ -67,6 +67,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix)\n \tint fd;\n \tstruct stat st;\n \tint flags = 0;\n+\tint ret;\n \n \tstatic struct option builtin_commit_graph_verify_options[] = {\n \t\tOPT_BOOL(0, \"shallow\", &opts.shallow,\n@@ -111,8 +112,9 @@ static int graph_verify(int argc, const char **argv, const char *prefix)\n \tif (!graph)\n \t\treturn !!open_ok;\n \n-\tUNLEAK(graph);\n-\treturn verify_commit_graph(the_repository, graph, flags);\n+\tret = verify_commit_graph(the_repository, graph, flags);\n+\tfree_commit_graph(graph);\n+\treturn ret;\n }\n \n extern int read_replace_refs;\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470505","messageId":"patch-v4-04.19-966d7657d54-20230117T151202Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v4 04/19] clone: use free() instead of UNLEAK()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:09Z","receivedAt":"2023-01-17T17:11:42Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change an UNLEAK() added in 0c4542738e6 (clone: free or UNLEAK further\npointers when finished, 2021-03-14) to use a \"to_free\" pattern\ninstead. In this case the \"repo\" can be either this absolute_pathdup()\nvalue, or in the \"else if\" branch seen in the context the the\n\"argv[0]\" argument to \"main()\".\n\nWe can only free() the value in the former case, hence the \"to_free\"\npattern.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/clone.c | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 5453ba5277f..ba82f5e4108 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -892,6 +892,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tint is_bundle = 0, is_local;\n \tint reject_shallow = 0;\n \tconst char *repo_name, *repo, *work_tree, *git_dir;\n+\tchar *repo_to_free = NULL;\n \tchar *path = NULL, *dir, *display_repo = NULL;\n \tint dest_exists, real_dest_exists = 0;\n \tconst struct ref *refs, *remote_head;\n@@ -949,7 +950,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tpath = get_repo_path(repo_name, &is_bundle);\n \tif (path) {\n \t\tFREE_AND_NULL(path);\n-\t\trepo = absolute_pathdup(repo_name);\n+\t\trepo = repo_to_free = absolute_pathdup(repo_name);\n \t} else if (strchr(repo_name, ':')) {\n \t\trepo = repo_name;\n \t\tdisplay_repo = transport_anonymize_url(repo);\n@@ -1413,7 +1414,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tfree(unborn_head);\n \tfree(dir);\n \tfree(path);\n-\tUNLEAK(repo);\n+\tfree(repo_to_free);\n \tjunk_mode = JUNK_LEAVE_ALL;\n \n \ttransport_ls_refs_options_release(&transport_ls_refs_options);\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470506","messageId":"patch-v4-01.19-2ed69e3cda3-20230117T151202Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v4 01/19] tests: mark tests as passing with SANITIZE=leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:06Z","receivedAt":"2023-01-17T17:11:45Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the \"ab/various-leak-fixes\" topic was merged in [1] only t6021\nwould fail if the tests were run in the\n\"GIT_TEST_PASSING_SANITIZE_LEAK=check\" mode, i.e. to check whether we\nmarked all leak-free tests with \"TEST_PASSES_SANITIZE_LEAK=true\".\n\nSince then we've had various tests starting to pass under\nSANITIZE=leak. Let's mark those as passing, this is when they started\nto pass, narrowed down with \"git bisect\":\n\n- t5317-pack-objects-filter-objects.sh: In\n  faebba436e6 (list-objects-filter: plug pattern_list leak, 2022-12-01).\n\n- t3210-pack-refs.sh, t5613-info-alternate.sh,\n  t7403-submodule-sync.sh: In 189e97bc4ba (diff: remove parseopts member\n  from struct diff_options, 2022-12-01).\n\n- t1408-packed-refs.sh: In ab91f6b7c42 (Merge branch\n  'rs/diff-parseopts', 2022-12-19).\n\n- t0023-crlf-am.sh, t4152-am-subjects.sh, t4254-am-corrupt.sh,\n  t4256-am-format-flowed.sh, t4257-am-interactive.sh,\n  t5403-post-checkout-hook.sh: In a658e881c13 (am: don't pass strvec to\n  apply_parse_options(), 2022-12-13)\n\n- t1301-shared-repo.sh, t1302-repo-version.sh: In b07a819c05f (reflog:\n  clear leftovers in reflog_expiry_cleanup(), 2022-12-13).\n\n- t1304-default-acl.sh, t1410-reflog.sh,\n  t5330-no-lazy-fetch-with-commit-graph.sh, t5502-quickfetch.sh,\n  t5604-clone-reference.sh, t6014-rev-list-all.sh,\n  t7701-repack-unpack-unreachable.sh: In b0c61be3209 (Merge branch\n  'rs/reflog-expiry-cleanup', 2022-12-26)\n\n1. 9ea1378d046 (Merge branch 'ab/various-leak-fixes', 2022-12-14)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n t/t0023-crlf-am.sh                         | 1 +\n t/t1301-shared-repo.sh                     | 1 +\n t/t1302-repo-version.sh                    | 1 +\n t/t1304-default-acl.sh                     | 1 +\n t/t1408-packed-refs.sh                     | 1 +\n t/t1410-reflog.sh                          | 1 +\n t/t3210-pack-refs.sh                       | 1 +\n t/t4152-am-subjects.sh                     | 2 ++\n t/t4254-am-corrupt.sh                      | 2 ++\n t/t4256-am-format-flowed.sh                | 1 +\n t/t4257-am-interactive.sh                  | 2 ++\n t/t5317-pack-objects-filter-objects.sh     | 1 +\n t/t5330-no-lazy-fetch-with-commit-graph.sh | 1 +\n t/t5403-post-checkout-hook.sh              | 1 +\n t/t5502-quickfetch.sh                      | 1 +\n t/t5604-clone-reference.sh                 | 1 +\n t/t5613-info-alternate.sh                  | 2 ++\n t/t6014-rev-list-all.sh                    | 1 +\n t/t6021-rev-list-exclude-hidden.sh         | 1 +\n t/t7403-submodule-sync.sh                  | 1 +\n t/t7701-repack-unpack-unreachable.sh       | 1 +\n 21 files changed, 25 insertions(+)\n\ndiff --git a/t/t0023-crlf-am.sh b/t/t0023-crlf-am.sh\nindex f9bbb91f64e..575805513a3 100755\n--- a/t/t0023-crlf-am.sh\n+++ b/t/t0023-crlf-am.sh\n@@ -2,6 +2,7 @@\n \n test_description='Test am with auto.crlf'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n cat >patchfile <<\\EOF\ndiff --git a/t/t1301-shared-repo.sh b/t/t1301-shared-repo.sh\nindex 93a2f91f8a5..a1251f65100 100755\n--- a/t/t1301-shared-repo.sh\n+++ b/t/t1301-shared-repo.sh\n@@ -8,6 +8,7 @@ test_description='Test shared repository initialization'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Remove a default ACL from the test dir if possible.\ndiff --git a/t/t1302-repo-version.sh b/t/t1302-repo-version.sh\nindex 7cf80bf66a6..70389fa2ebb 100755\n--- a/t/t1302-repo-version.sh\n+++ b/t/t1302-repo-version.sh\n@@ -5,6 +5,7 @@\n \n test_description='Test repository version check'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh\nindex c69ae41306c..31b89dd9693 100755\n--- a/t/t1304-default-acl.sh\n+++ b/t/t1304-default-acl.sh\n@@ -9,6 +9,7 @@ test_description='Test repository with default ACL'\n # => this must come before . ./test-lib.sh\n umask 077\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # We need an arbitrary other user give permission to using ACLs. root\ndiff --git a/t/t1408-packed-refs.sh b/t/t1408-packed-refs.sh\nindex 41ba1f1d7fc..9469c79a585 100755\n--- a/t/t1408-packed-refs.sh\n+++ b/t/t1408-packed-refs.sh\n@@ -5,6 +5,7 @@ test_description='packed-refs entries are covered by loose refs'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh\nindex aa59954f6c5..6c45965b1e4 100755\n--- a/t/t1410-reflog.sh\n+++ b/t/t1410-reflog.sh\n@@ -7,6 +7,7 @@ test_description='Test prune and reflog expiration'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n check_have () {\ndiff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh\nindex 577f32dc71f..07a0ff93def 100755\n--- a/t/t3210-pack-refs.sh\n+++ b/t/t3210-pack-refs.sh\n@@ -12,6 +12,7 @@ semantic is still the same.\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'enable reflogs' '\ndiff --git a/t/t4152-am-subjects.sh b/t/t4152-am-subjects.sh\nindex 4c68245acad..9f2edba1f83 100755\n--- a/t/t4152-am-subjects.sh\n+++ b/t/t4152-am-subjects.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test subject preservation with format-patch | am'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n make_patches() {\ndiff --git a/t/t4254-am-corrupt.sh b/t/t4254-am-corrupt.sh\nindex 54be7da1611..45f1d4f95e5 100755\n--- a/t/t4254-am-corrupt.sh\n+++ b/t/t4254-am-corrupt.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git am with corrupt input'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n make_mbox_with_nul () {\ndiff --git a/t/t4256-am-format-flowed.sh b/t/t4256-am-format-flowed.sh\nindex 2369c4e17ad..1015273bc82 100755\n--- a/t/t4256-am-format-flowed.sh\n+++ b/t/t4256-am-format-flowed.sh\n@@ -2,6 +2,7 @@\n \n test_description='test format=flowed support of git am'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t4257-am-interactive.sh b/t/t4257-am-interactive.sh\nindex aed8f4de3d6..f26d7fd2dbd 100755\n--- a/t/t4257-am-interactive.sh\n+++ b/t/t4257-am-interactive.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='am --interactive tests'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'set up patches to apply' '\ndiff --git a/t/t5317-pack-objects-filter-objects.sh b/t/t5317-pack-objects-filter-objects.sh\nindex 5b707d911b5..b26d476c646 100755\n--- a/t/t5317-pack-objects-filter-objects.sh\n+++ b/t/t5317-pack-objects-filter-objects.sh\n@@ -5,6 +5,7 @@ test_description='git pack-objects using object filtering'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Test blob:none filter.\ndiff --git a/t/t5330-no-lazy-fetch-with-commit-graph.sh b/t/t5330-no-lazy-fetch-with-commit-graph.sh\nindex 2cc7fd7a476..5eb28f0512d 100755\n--- a/t/t5330-no-lazy-fetch-with-commit-graph.sh\n+++ b/t/t5330-no-lazy-fetch-with-commit-graph.sh\n@@ -2,6 +2,7 @@\n \n test_description='test for no lazy fetch with the commit-graph'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup: prepare a repository with a commit' '\ndiff --git a/t/t5403-post-checkout-hook.sh b/t/t5403-post-checkout-hook.sh\nindex 978f240cdac..cfaae547398 100755\n--- a/t/t5403-post-checkout-hook.sh\n+++ b/t/t5403-post-checkout-hook.sh\n@@ -7,6 +7,7 @@ test_description='Test the post-checkout hook.'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5502-quickfetch.sh b/t/t5502-quickfetch.sh\nindex b160f8b7fb7..7b3ff21b984 100755\n--- a/t/t5502-quickfetch.sh\n+++ b/t/t5502-quickfetch.sh\n@@ -5,6 +5,7 @@ test_description='test quickfetch from local'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh\nindex 2734e37e880..dc86dea1333 100755\n--- a/t/t5604-clone-reference.sh\n+++ b/t/t5604-clone-reference.sh\n@@ -7,6 +7,7 @@ test_description='test clone --reference'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n base_dir=$(pwd)\ndiff --git a/t/t5613-info-alternate.sh b/t/t5613-info-alternate.sh\nindex 895f46bb911..7708cbafa98 100755\n--- a/t/t5613-info-alternate.sh\n+++ b/t/t5613-info-alternate.sh\n@@ -4,6 +4,8 @@\n #\n \n test_description='test transitive info/alternate entries'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'preparing first repository' '\ndiff --git a/t/t6014-rev-list-all.sh b/t/t6014-rev-list-all.sh\nindex c9bedd29cba..16b8bd1d090 100755\n--- a/t/t6014-rev-list-all.sh\n+++ b/t/t6014-rev-list-all.sh\n@@ -2,6 +2,7 @@\n \n test_description='--all includes detached HEADs'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n \ndiff --git a/t/t6021-rev-list-exclude-hidden.sh b/t/t6021-rev-list-exclude-hidden.sh\nindex 32b2b094138..11c50b7c0dd 100755\n--- a/t/t6021-rev-list-exclude-hidden.sh\n+++ b/t/t6021-rev-list-exclude-hidden.sh\n@@ -2,6 +2,7 @@\n \n test_description='git rev-list --exclude-hidden test'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh\nindex ea92ef52a5e..ff09443a0a4 100755\n--- a/t/t7403-submodule-sync.sh\n+++ b/t/t7403-submodule-sync.sh\n@@ -11,6 +11,7 @@ These tests exercise the \"git submodule sync\" subcommand.\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t7701-repack-unpack-unreachable.sh b/t/t7701-repack-unpack-unreachable.sh\nindex b7ac4f598a8..ebb267855fe 100755\n--- a/t/t7701-repack-unpack-unreachable.sh\n+++ b/t/t7701-repack-unpack-unreachable.sh\n@@ -5,6 +5,7 @@ test_description='git repack works correctly'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n fsha1=\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470507","messageId":"patch-v4-02.19-9993786ba0d-20230117T151202Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v4 02/19] bundle.c: don't leak the \"args\" in the \"struct child_process\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:07Z","receivedAt":"2023-01-17T17:11:50Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a leak that's been here since 7366096de9d (bundle API: change\n\"flags\" to be \"extra_index_pack_args\", 2021-09-05), if can't verify\nthe bundle we didn't call child_process_clear() to clear the \"args\".\n\nBut rather than doing that let's verify the bundle before we start\npreparing the process we're going to spawn, if we get an error we\ndon't need to push anything to the \"args\".\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n bundle.c | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/bundle.c b/bundle.c\nindex 4ef7256aa11..9ebb10a8f72 100644\n--- a/bundle.c\n+++ b/bundle.c\n@@ -627,6 +627,10 @@ int unbundle(struct repository *r, struct bundle_header *header,\n \t     enum verify_bundle_flags flags)\n {\n \tstruct child_process ip = CHILD_PROCESS_INIT;\n+\n+\tif (verify_bundle(r, header, flags))\n+\t\treturn -1;\n+\n \tstrvec_pushl(&ip.args, \"index-pack\", \"--fix-thin\", \"--stdin\", NULL);\n \n \t/* If there is a filter, then we need to create the promisor pack. */\n@@ -638,8 +642,6 @@ int unbundle(struct repository *r, struct bundle_header *header,\n \t\tstrvec_clear(extra_index_pack_args);\n \t}\n \n-\tif (verify_bundle(r, header, flags))\n-\t\treturn -1;\n \tip.in = bundle_fd;\n \tip.no_stdout = 1;\n \tip.git_cmd = 1;\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470508","messageId":"patch-v4-05.19-93a8f8fa1b9-20230117T151202Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v4 05/19] various: add missing clear_pathspec(), fix leaks","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:10Z","receivedAt":"2023-01-17T17:11:56Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix memory leaks resulting from a missing clear_pathspec().\n\n- archive.c: Plug a leak in the \"struct archiver_args\", and\n  clear_pathspec() the \"pathspec\" member that the \"parse_pathspec_arg()\"\n  call in this function populates.\n\n- builtin/clean.c: Fix a memory leak that's been with us since\n  893d839970c (clean: convert to use parse_pathspec, 2013-07-14).\n\n- builtin/reset.c: Add clear_pathspec() calls to cmd_reset(),\n  including to the codepaths where we'd return early.\n\n- builtin/stash.c: Call clear_pathspec() on the pathspec initialized\n  in push_stash().\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n archive.c                       |  1 +\n builtin/clean.c                 |  1 +\n builtin/reset.c                 | 11 ++++++++---\n builtin/stash.c                 |  7 +++++--\n t/t5001-archive-attr.sh         |  1 +\n t/t5004-archive-corner-cases.sh |  2 ++\n t/t7105-reset-patch.sh          |  2 ++\n t/t7106-reset-unborn-branch.sh  |  2 ++\n t/t7107-reset-pathspec-file.sh  |  1 +\n t/t7301-clean-interactive.sh    |  1 +\n 10 files changed, 24 insertions(+), 5 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex 941495f5d78..a2d813e50db 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -710,6 +710,7 @@ int write_archive(int argc, const char **argv, const char *prefix,\n \n \tstring_list_clear_func(&args.extra_files, extra_file_info_clear);\n \tfree(args.refname);\n+\tclear_pathspec(&args.pathspec);\n \n \treturn rc;\n }\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex b2701a28158..b15eab328b7 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -1092,5 +1092,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tstrbuf_release(&buf);\n \tstring_list_clear(&del_list, 0);\n \tstring_list_clear(&exclude_list, 0);\n+\tclear_pathspec(&pathspec);\n \treturn (errors != 0);\n }\ndiff --git a/builtin/reset.c b/builtin/reset.c\nindex fea20a9ba0b..e9c10618cd3 100644\n--- a/builtin/reset.c\n+++ b/builtin/reset.c\n@@ -390,7 +390,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \t\tif (reset_type != NONE)\n \t\t\tdie(_(\"options '%s' and '%s' cannot be used together\"), \"--patch\", \"--{hard,mixed,soft}\");\n \t\ttrace2_cmd_mode(\"patch-interactive\");\n-\t\treturn run_add_interactive(rev, \"--patch=reset\", &pathspec);\n+\t\tupdate_ref_status = run_add_interactive(rev, \"--patch=reset\", &pathspec);\n+\t\tgoto cleanup;\n \t}\n \n \t/* git reset tree [--] paths... can be used to\n@@ -439,8 +440,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \t\t\t\t       LOCK_DIE_ON_ERROR);\n \t\tif (reset_type == MIXED) {\n \t\t\tint flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;\n-\t\t\tif (read_from_tree(&pathspec, &oid, intent_to_add))\n-\t\t\t\treturn 1;\n+\t\t\tif (read_from_tree(&pathspec, &oid, intent_to_add)) {\n+\t\t\t\tupdate_ref_status = 1;\n+\t\t\t\tgoto cleanup;\n+\t\t\t}\n \t\t\tthe_index.updated_skipworktree = 1;\n \t\t\tif (!no_refresh && get_git_work_tree()) {\n \t\t\t\tuint64_t t_begin, t_delta_in_ms;\n@@ -488,5 +491,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \n \tdiscard_index(&the_index);\n \n+cleanup:\n+\tclear_pathspec(&pathspec);\n \treturn update_ref_status;\n }\ndiff --git a/builtin/stash.c b/builtin/stash.c\nindex bb0fd861434..45bffdf54bb 100644\n--- a/builtin/stash.c\n+++ b/builtin/stash.c\n@@ -1727,6 +1727,7 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n \t\tOPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),\n \t\tOPT_END()\n \t};\n+\tint ret;\n \n \tif (argc) {\n \t\tforce_assume = !strcmp(argv[0], \"-p\");\n@@ -1766,8 +1767,10 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n \t\tdie(_(\"the option '%s' requires '%s'\"), \"--pathspec-file-nul\", \"--pathspec-from-file\");\n \t}\n \n-\treturn do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n-\t\t\t     include_untracked, only_staged);\n+\tret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n+\t\t\t    include_untracked, only_staged);\n+\tclear_pathspec(&ps);\n+\treturn ret;\n }\n \n static int push_stash_unassumed(int argc, const char **argv, const char *prefix)\ndiff --git a/t/t5001-archive-attr.sh b/t/t5001-archive-attr.sh\nindex 2f6eef5e372..04d300eeda7 100755\n--- a/t/t5001-archive-attr.sh\n+++ b/t/t5001-archive-attr.sh\n@@ -3,6 +3,7 @@\n test_description='git archive attribute tests'\n \n TEST_CREATE_REPO_NO_TEMPLATE=1\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n SUBSTFORMAT='%H (%h)%n'\ndiff --git a/t/t5004-archive-corner-cases.sh b/t/t5004-archive-corner-cases.sh\nindex ae508e21623..9f2c6da80e8 100755\n--- a/t/t5004-archive-corner-cases.sh\n+++ b/t/t5004-archive-corner-cases.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test corner cases of git-archive'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # the 10knuls.tar file is used to test for an empty git generated tar\ndiff --git a/t/t7105-reset-patch.sh b/t/t7105-reset-patch.sh\nindex fc2a6cf5c7a..9b46da7aaa7 100755\n--- a/t/t7105-reset-patch.sh\n+++ b/t/t7105-reset-patch.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git reset --patch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./lib-patch-mode.sh\n \n test_expect_success PERL 'setup' '\ndiff --git a/t/t7106-reset-unborn-branch.sh b/t/t7106-reset-unborn-branch.sh\nindex ecb85c3b823..a0b67a0b843 100755\n--- a/t/t7106-reset-unborn-branch.sh\n+++ b/t/t7106-reset-unborn-branch.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git reset should work on unborn branch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7107-reset-pathspec-file.sh b/t/t7107-reset-pathspec-file.sh\nindex 523efbecde1..af5ea406db3 100755\n--- a/t/t7107-reset-pathspec-file.sh\n+++ b/t/t7107-reset-pathspec-file.sh\n@@ -2,6 +2,7 @@\n \n test_description='reset --pathspec-from-file'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_tick\ndiff --git a/t/t7301-clean-interactive.sh b/t/t7301-clean-interactive.sh\nindex a07e8b86de2..d82a3210a1d 100755\n--- a/t/t7301-clean-interactive.sh\n+++ b/t/t7301-clean-interactive.sh\n@@ -2,6 +2,7 @@\n \n test_description='git clean -i basic tests'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-terminal.sh\n \n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470509","messageId":"patch-v4-06.19-bd15d991ac7-20230117T151202Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v4 06/19] name-rev: don't xstrdup() an already dup'd string","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:11Z","receivedAt":"2023-01-17T17:12:01Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When \"add_to_tip_table()\" is called with a non-zero\n\"shorten_unambiguous\" we always return an xstrdup()'d string, which\nwe'd then xstrdup() again, leaking memory. See [1] and [2] for how\nthis leak came about.\n\nWe could xstrdup() only if \"shorten_unambiguous\" wasn't true, but\nlet's instead inline this code, so that information on whether we need\nto xstrdup() is contained within add_to_tip_table().\n\n1. 98c5c4ad015 (name-rev: allow to specify a subpath for --refs\n   option, 2013-06-18)\n2. b23e0b9353e (name-rev: allow converting the exact object name at\n   the tip of a ref, 2013-07-07)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/name-rev.c | 23 ++++++++++-------------\n 1 file changed, 10 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin/name-rev.c b/builtin/name-rev.c\nindex 15535e914a6..49fae523694 100644\n--- a/builtin/name-rev.c\n+++ b/builtin/name-rev.c\n@@ -273,17 +273,6 @@ static int subpath_matches(const char *path, const char *filter)\n \treturn -1;\n }\n \n-static const char *name_ref_abbrev(const char *refname, int shorten_unambiguous)\n-{\n-\tif (shorten_unambiguous)\n-\t\trefname = shorten_unambiguous_ref(refname, 0);\n-\telse if (skip_prefix(refname, \"refs/heads/\", &refname))\n-\t\t; /* refname already advanced */\n-\telse\n-\t\tskip_prefix(refname, \"refs/\", &refname);\n-\treturn refname;\n-}\n-\n struct name_ref_data {\n \tint tags_only;\n \tint name_only;\n@@ -309,11 +298,19 @@ static void add_to_tip_table(const struct object_id *oid, const char *refname,\n \t\t\t     int shorten_unambiguous, struct commit *commit,\n \t\t\t     timestamp_t taggerdate, int from_tag, int deref)\n {\n-\trefname = name_ref_abbrev(refname, shorten_unambiguous);\n+\tchar *short_refname = NULL;\n+\n+\tif (shorten_unambiguous)\n+\t\tshort_refname = shorten_unambiguous_ref(refname, 0);\n+\telse if (skip_prefix(refname, \"refs/heads/\", &refname))\n+\t\t; /* refname already advanced */\n+\telse\n+\t\tskip_prefix(refname, \"refs/\", &refname);\n \n \tALLOC_GROW(tip_table.table, tip_table.nr + 1, tip_table.alloc);\n \toidcpy(&tip_table.table[tip_table.nr].oid, oid);\n-\ttip_table.table[tip_table.nr].refname = xstrdup(refname);\n+\ttip_table.table[tip_table.nr].refname = short_refname ?\n+\t\tshort_refname : xstrdup(refname);\n \ttip_table.table[tip_table.nr].commit = commit;\n \ttip_table.table[tip_table.nr].taggerdate = taggerdate;\n \ttip_table.table[tip_table.nr].from_tag = from_tag;\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470510","messageId":"patch-v4-07.19-fd890121ebe-20230117T151202Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v4 07/19] repack: fix leaks on error with \"goto cleanup\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:12Z","receivedAt":"2023-01-17T17:12:03Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change cmd_repack() to \"goto cleanup\" rather than \"return ret\" on\nerror, when we returned we'd potentially skip cleaning up the\nstring_lists and other data we'd allocated in this function.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/repack.c                    | 13 +++++++------\n t/t6011-rev-list-with-bad-commit.sh |  1 +\n 2 files changed, 8 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/repack.c b/builtin/repack.c\nindex c1402ad038f..f6493795318 100644\n--- a/builtin/repack.c\n+++ b/builtin/repack.c\n@@ -948,7 +948,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \n \tret = start_command(&cmd);\n \tif (ret)\n-\t\treturn ret;\n+\t\tgoto cleanup;\n \n \tif (geometry) {\n \t\tFILE *in = xfdopen(cmd.in, \"w\");\n@@ -977,7 +977,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \tfclose(out);\n \tret = finish_command(&cmd);\n \tif (ret)\n-\t\treturn ret;\n+\t\tgoto cleanup;\n \n \tif (!names.nr && !po_args.quiet)\n \t\tprintf_ln(_(\"Nothing new to pack.\"));\n@@ -1007,7 +1007,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\t\t\t       &existing_nonkept_packs,\n \t\t\t\t       &existing_kept_packs);\n \t\tif (ret)\n-\t\t\treturn ret;\n+\t\t\tgoto cleanup;\n \n \t\tif (delete_redundant && expire_to) {\n \t\t\t/*\n@@ -1039,7 +1039,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\t\t\t\t       &existing_nonkept_packs,\n \t\t\t\t\t       &existing_kept_packs);\n \t\t\tif (ret)\n-\t\t\t\treturn ret;\n+\t\t\t\tgoto cleanup;\n \t\t}\n \t}\n \n@@ -1115,7 +1115,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\tstring_list_clear(&include, 0);\n \n \t\tif (ret)\n-\t\t\treturn ret;\n+\t\t\tgoto cleanup;\n \t}\n \n \treprepare_packed_git(the_repository);\n@@ -1172,10 +1172,11 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\twrite_midx_file(get_object_directory(), NULL, NULL, flags);\n \t}\n \n+cleanup:\n \tstring_list_clear(&names, 1);\n \tstring_list_clear(&existing_nonkept_packs, 0);\n \tstring_list_clear(&existing_kept_packs, 0);\n \tclear_pack_geometry(geometry);\n \n-\treturn 0;\n+\treturn ret;\n }\ndiff --git a/t/t6011-rev-list-with-bad-commit.sh b/t/t6011-rev-list-with-bad-commit.sh\nindex bad02cf5b83..b2e422cf0f7 100755\n--- a/t/t6011-rev-list-with-bad-commit.sh\n+++ b/t/t6011-rev-list-with-bad-commit.sh\n@@ -2,6 +2,7 @@\n \n test_description='git rev-list should notice bad commits'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Note:\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470511","messageId":"patch-v4-08.19-1fe25bc6981-20230117T151202Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v4 08/19] worktree: fix a trivial leak in prune_worktrees()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:13Z","receivedAt":"2023-01-17T17:12:05Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"We were leaking both the \"struct strbuf\" in prune_worktrees(), as well\nas the \"path\" we got from should_prune_worktree(). Since these were\nthe only two uses of the \"struct string_list\" let's change it to a\n\"DUP\" and push these to it with \"string_list_append_nodup()\".\n\nFor the string_list_append_nodup() we could also string_list_append()\nthe main_path.buf, and then strbuf_release(&main_path) right away. But\ndoing it this way avoids an allocation, as we already have the \"struct\nstrbuf\" prepared for appending to \"kept\".\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/worktree.c         | 6 +++---\n t/t2401-worktree-prune.sh  | 1 +\n t/t2406-worktree-repair.sh | 1 +\n t/t3203-branch-output.sh   | 2 ++\n 4 files changed, 7 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex 591d659faea..865ce9be22b 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -173,7 +173,7 @@ static void prune_worktrees(void)\n {\n \tstruct strbuf reason = STRBUF_INIT;\n \tstruct strbuf main_path = STRBUF_INIT;\n-\tstruct string_list kept = STRING_LIST_INIT_NODUP;\n+\tstruct string_list kept = STRING_LIST_INIT_DUP;\n \tDIR *dir = opendir(git_path(\"worktrees\"));\n \tstruct dirent *d;\n \tif (!dir)\n@@ -184,14 +184,14 @@ static void prune_worktrees(void)\n \t\tif (should_prune_worktree(d->d_name, &reason, &path, expire))\n \t\t\tprune_worktree(d->d_name, reason.buf);\n \t\telse if (path)\n-\t\t\tstring_list_append(&kept, path)->util = xstrdup(d->d_name);\n+\t\t\tstring_list_append_nodup(&kept, path)->util = xstrdup(d->d_name);\n \t}\n \tclosedir(dir);\n \n \tstrbuf_add_absolute_path(&main_path, get_git_common_dir());\n \t/* massage main worktree absolute path to match 'gitdir' content */\n \tstrbuf_strip_suffix(&main_path, \"/.\");\n-\tstring_list_append(&kept, strbuf_detach(&main_path, NULL));\n+\tstring_list_append_nodup(&kept, strbuf_detach(&main_path, NULL));\n \tprune_dups(&kept);\n \tstring_list_clear(&kept, 1);\n \ndiff --git a/t/t2401-worktree-prune.sh b/t/t2401-worktree-prune.sh\nindex 3d28c7f06b2..568a47ec426 100755\n--- a/t/t2401-worktree-prune.sh\n+++ b/t/t2401-worktree-prune.sh\n@@ -5,6 +5,7 @@ test_description='prune $GIT_DIR/worktrees'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success initialize '\ndiff --git a/t/t2406-worktree-repair.sh b/t/t2406-worktree-repair.sh\nindex 5c44453e1c1..8970780efcc 100755\n--- a/t/t2406-worktree-repair.sh\n+++ b/t/t2406-worktree-repair.sh\n@@ -2,6 +2,7 @@\n \n test_description='test git worktree repair'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh\nindex d34d77f8934..ba8d929d189 100755\n--- a/t/t3203-branch-output.sh\n+++ b/t/t3203-branch-output.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git branch display tests'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-terminal.sh\n \n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470512","messageId":"patch-v4-09.19-6b3dd9b15f0-20230117T151202Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v4 09/19] http-backend.c: fix \"dir\" and \"cmd_arg\" leaks in cmd_main()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:14Z","receivedAt":"2023-01-17T17:12:10Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Free the \"dir\" variable after we're done with it. Before\n917adc03608 (http-backend: add GIT_PROJECT_ROOT environment var,\n2009-10-30) there was no leak here, as we'd get it via getenv(), but\nsince 917adc03608 we've xstrdup()'d it (or the equivalent), so we need\nto free() it.\n\nWe also need to free the \"cmd_arg\" variable, which has been leaked\never since it was added in 2f4038ab337 (Git-aware CGI to provide dumb\nHTTP transport, 2009-10-30).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n http-backend.c | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git a/http-backend.c b/http-backend.c\nindex 6eb3b2fe51c..67819d931ce 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -786,6 +786,7 @@ int cmd_main(int argc, const char **argv)\n \tif (!getenv(\"GIT_HTTP_EXPORT_ALL\") &&\n \t    access(\"git-daemon-export-ok\", F_OK) )\n \t\tnot_found(&hdr, \"Repository not exported: '%s'\", dir);\n+\tfree(dir);\n \n \thttp_config();\n \tmax_request_buffer = git_env_ulong(\"GIT_HTTP_MAX_REQUEST_BUFFER\",\n@@ -795,5 +796,6 @@ int cmd_main(int argc, const char **argv)\n \t\tsetenv(GIT_PROTOCOL_ENVIRONMENT, proto_header, 0);\n \n \tcmd->imp(&hdr, cmd_arg);\n+\tfree(cmd_arg);\n \treturn 0;\n }\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470513","messageId":"patch-v4-11.19-ab31d8d10da-20230117T151202Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v4 11/19] commit-graph: fix a parse_options_concat() leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:16Z","receivedAt":"2023-01-17T17:12:12Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the parse_options_concat() was added to this file in\n84e4484f128 (commit-graph: use parse_options_concat(), 2021-08-23) we\nwouldn't free() it if we returned early in these cases.\n\nSince \"result\" is 0 by default we can \"goto cleanup\" in both cases,\nand only need to set \"result\" if write_commit_graph_reachable() fails.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/commit-graph.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/commit-graph.c b/builtin/commit-graph.c\nindex 0102ac8540e..93704f95a9d 100644\n--- a/builtin/commit-graph.c\n+++ b/builtin/commit-graph.c\n@@ -269,8 +269,8 @@ static int graph_write(int argc, const char **argv, const char *prefix)\n \n \tif (opts.reachable) {\n \t\tif (write_commit_graph_reachable(odb, flags, &write_opts))\n-\t\t\treturn 1;\n-\t\treturn 0;\n+\t\t\tresult = 1;\n+\t\tgoto cleanup;\n \t}\n \n \tif (opts.stdin_packs) {\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470514","messageId":"patch-v4-10.19-246f71bb447-20230117T151202Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v4 10/19] http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:15Z","receivedAt":"2023-01-17T17:12:16Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us ever since\n2f4038ab337 (Git-aware CGI to provide dumb HTTP transport,\n2009-10-30). In this case we're not calling regerror() after a failed\nregexec(), and don't otherwise use \"re\" afterwards.\n\nWe can therefore simplify this code by calling regfree() right after\nthe regexec(). An alternative fix would be to add a regfree() to both\nthe \"return\" and \"break\" path in this for-loop.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n http-backend.c | 7 +++++--\n 1 file changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/http-backend.c b/http-backend.c\nindex 67819d931ce..8ab58e55f85 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -759,10 +759,14 @@ int cmd_main(int argc, const char **argv)\n \t\tstruct service_cmd *c = &services[i];\n \t\tregex_t re;\n \t\tregmatch_t out[1];\n+\t\tint ret;\n \n \t\tif (regcomp(&re, c->pattern, REG_EXTENDED))\n \t\t\tdie(\"Bogus regex in service table: %s\", c->pattern);\n-\t\tif (!regexec(&re, dir, 1, out, 0)) {\n+\t\tret = regexec(&re, dir, 1, out, 0);\n+\t\tregfree(&re);\n+\n+\t\tif (!ret) {\n \t\t\tsize_t n;\n \n \t\t\tif (strcmp(method, c->method))\n@@ -774,7 +778,6 @@ int cmd_main(int argc, const char **argv)\n \t\t\tdir[out[0].rm_so] = 0;\n \t\t\tbreak;\n \t\t}\n-\t\tregfree(&re);\n \t}\n \n \tif (!cmd)\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470515","messageId":"patch-v4-12.19-9054b353220-20230117T151202Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v4 12/19] show-branch: free() allocated \"head\" before return","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:17Z","receivedAt":"2023-01-17T17:12:23Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Stop leaking the \"head\" variable, which we've been leaking since it\nwas originally added in [1], and in its current form since [2]\n\n1. ed378ec7e85 (Make ref resolution saner, 2006-09-11)\n2. d9e557a320b (show-branch: store resolved head in heap buffer,\n   2017-02-14).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/show-branch.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/show-branch.c b/builtin/show-branch.c\nindex c013abaf942..358ac3e519a 100644\n--- a/builtin/show-branch.c\n+++ b/builtin/show-branch.c\n@@ -956,5 +956,6 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)\n \t\tif (shown_merge_point && --extra < 0)\n \t\t\tbreak;\n \t}\n+\tfree(head);\n \treturn 0;\n }\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470516","messageId":"patch-v4-14.19-e8ea18b08c2-20230117T151202Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v4 14/19] builtin/merge.c: free \"&buf\" on \"Your local changes...\" error","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:19Z","receivedAt":"2023-01-17T17:12:33Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Plug a memory leak introduced in [1], since that change didn't follow\nthe \"goto done\" pattern introduced in [2] we'd leak the \"&buf\" memory.\n\n1. e4cdfe84a0d (merge: abort if index does not match HEAD for trivial\n   merges, 2022-07-23)\n2. d5a35c114ab (Copy resolve_ref() return value for longer use,\n   2011-11-13)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/merge.c | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 91dd5435c59..2b13124c497 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -1618,7 +1618,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t\terror(_(\"Your local changes to the following files would be overwritten by merge:\\n  %s\"),\n \t\t\t\t      sb.buf);\n \t\t\t\tstrbuf_release(&sb);\n-\t\t\t\treturn 2;\n+\t\t\t\tret = 2;\n+\t\t\t\tgoto done;\n \t\t\t}\n \n \t\t\t/* See if it is really trivial. */\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470517","messageId":"patch-v4-13.19-05836b08e0f-20230117T151202Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v4 13/19] builtin/merge.c: use fixed strings, not \"strbuf\", fix leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:18Z","receivedAt":"2023-01-17T17:12:38Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Follow-up 465028e0e25 (merge: add missing strbuf_release(),\n2021-10-07) and address the \"msg\" memory leak in this block. We could\nfree \"&msg\" before the \"goto done\" here, but even better is to avoid\nallocating it in the first place.\n\nBy repeating the \"Fast-forward\" string here we can avoid using a\n\"struct strbuf\" altogether.\n\nSuggested-by: René Scharfe <l.s.r@web.de>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/merge.c                | 11 ++++-------\n t/t6439-merge-co-error-msgs.sh |  1 +\n 2 files changed, 5 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 0f093f2a4f2..91dd5435c59 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -1560,7 +1560,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t!common->next &&\n \t\t\toideq(&common->item->object.oid, &head_commit->object.oid)) {\n \t\t/* Again the most common case of merging one remote. */\n-\t\tstruct strbuf msg = STRBUF_INIT;\n+\t\tconst char *msg = have_message ?\n+\t\t\t\"Fast-forward (no commit created; -m option ignored)\" :\n+\t\t\t\"Fast-forward\";\n \t\tstruct commit *commit;\n \n \t\tif (verbosity >= 0) {\n@@ -1570,10 +1572,6 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t       find_unique_abbrev(&remoteheads->item->object.oid,\n \t\t\t\t\t\t  DEFAULT_ABBREV));\n \t\t}\n-\t\tstrbuf_addstr(&msg, \"Fast-forward\");\n-\t\tif (have_message)\n-\t\t\tstrbuf_addstr(&msg,\n-\t\t\t\t\" (no commit created; -m option ignored)\");\n \t\tcommit = remoteheads->item;\n \t\tif (!commit) {\n \t\t\tret = 1;\n@@ -1592,9 +1590,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\tgoto done;\n \t\t}\n \n-\t\tfinish(head_commit, remoteheads, &commit->object.oid, msg.buf);\n+\t\tfinish(head_commit, remoteheads, &commit->object.oid, msg);\n \t\tremove_merge_branch_state(the_repository);\n-\t\tstrbuf_release(&msg);\n \t\tgoto done;\n \t} else if (!remoteheads->next && common->next)\n \t\t;\ndiff --git a/t/t6439-merge-co-error-msgs.sh b/t/t6439-merge-co-error-msgs.sh\nindex 52cf0c87690..0cbec57cdab 100755\n--- a/t/t6439-merge-co-error-msgs.sh\n+++ b/t/t6439-merge-co-error-msgs.sh\n@@ -5,6 +5,7 @@ test_description='unpack-trees error messages'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n \n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470518","messageId":"patch-v4-16.19-52744d9690f-20230117T151202Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v4 16/19] grep.c: refactor free_grep_patterns()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:21Z","receivedAt":"2023-01-17T17:12:45Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Refactor the free_grep_patterns() function to split out the freeing of\nthe \"struct grep_pat\" it contains, right now we're only freeing the\n\"pattern_list\", but we should be freeing another member of the same\ntype, which we'll do in the subsequent commit.\n\nLet's also replace the \"return\" if we don't have an\n\"opt->pattern_expression\" with a conditional call of\nfree_pattern_expr().\n\nBefore db84376f981 (grep.c: remove \"extended\" in favor of\n\"pattern_expression\", fix segfault, 2022-10-11) the pattern here was:\n\n\tif (!x)\n\t\treturn;\n\tfree(y);\n\nBut after the cleanup in db84376f981 (which was a narrow segfault fix,\nand thus avoided refactoring this) we ended up with:\n\n\tif (!x)\n\t\treturn;\n\tfree(x);\n\nLet's instead do:\n\n\tif (x)\n\t\tfree(x);\n\nThis doesn't matter for the subsequent change, but as we're\nrefactoring this function let's make it easier to reason about, and to\nextend in the future, i.e. if we start to free free() members that\ncome after \"pattern_expression\" in the \"struct grep_opt\".\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n grep.c | 14 +++++++++-----\n 1 file changed, 9 insertions(+), 5 deletions(-)\n\ndiff --git a/grep.c b/grep.c\nindex 06eed694936..a4450df4559 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -769,11 +769,11 @@ static void free_pattern_expr(struct grep_expr *x)\n \tfree(x);\n }\n \n-void free_grep_patterns(struct grep_opt *opt)\n+static void free_grep_pat(struct grep_pat *pattern)\n {\n \tstruct grep_pat *p, *n;\n \n-\tfor (p = opt->pattern_list; p; p = n) {\n+\tfor (p = pattern; p; p = n) {\n \t\tn = p->next;\n \t\tswitch (p->token) {\n \t\tcase GREP_PATTERN: /* atom */\n@@ -790,10 +790,14 @@ void free_grep_patterns(struct grep_opt *opt)\n \t\t}\n \t\tfree(p);\n \t}\n+}\n \n-\tif (!opt->pattern_expression)\n-\t\treturn;\n-\tfree_pattern_expr(opt->pattern_expression);\n+void free_grep_patterns(struct grep_opt *opt)\n+{\n+\tfree_grep_pat(opt->pattern_list);\n+\n+\tif (opt->pattern_expression)\n+\t\tfree_pattern_expr(opt->pattern_expression);\n }\n \n static const char *end_of_line(const char *cp, unsigned long *left)\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470519","messageId":"patch-v4-15.19-66c24afb893-20230117T151202Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v4 15/19] object-file.c: release the \"tag\" in check_tag()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:20Z","receivedAt":"2023-01-17T17:12:53Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us ever since c879daa2372 (Make\nhash-object more robust against malformed objects, 2011-02-05). With\n\"HASH_FORMAT_CHECK\" (used by \"hash-object\" and \"replace\") we'll parse\ntags into a throwaway variable on the stack, but weren't freeing the\n\"item->tag\" we might malloc() when doing so.\n\nThe clearing that release_tag_memory() does for us is redundant here,\nbut let's use it as-is anyway. It only has one other existing caller,\nwhich does need the tag to be cleared.\n\nMark the tests that now pass in their entirety as passing under\n\"SANITIZE=leak\", which means we'll test them as part of the\n\"linux-leaks\" CI job.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n object-file.c         | 1 +\n t/t3800-mktag.sh      | 1 +\n t/t5302-pack-index.sh | 2 ++\n 3 files changed, 4 insertions(+)\n\ndiff --git a/object-file.c b/object-file.c\nindex 80a0cd3b351..b554266aff4 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -2324,6 +2324,7 @@ static void check_tag(const void *buf, size_t size)\n \tmemset(&t, 0, sizeof(t));\n \tif (parse_tag_buffer(the_repository, &t, buf, size))\n \t\tdie(_(\"corrupt tag\"));\n+\trelease_tag_memory(&t);\n }\n \n static int index_mem(struct index_state *istate,\ndiff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh\nindex e3cf0ffbe59..d3e428ff46e 100755\n--- a/t/t3800-mktag.sh\n+++ b/t/t3800-mktag.sh\n@@ -4,6 +4,7 @@\n \n test_description='git mktag: tag object verify test'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n ###########################################################\ndiff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh\nindex b0095ab41d3..54b11f81c63 100755\n--- a/t/t5302-pack-index.sh\n+++ b/t/t5302-pack-index.sh\n@@ -4,6 +4,8 @@\n #\n \n test_description='pack index with 64-bit offsets and object CRC'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470520","messageId":"patch-v4-17.19-8ff63d9095c-20230117T151202Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v4 17/19] grep API: plug memory leaks by freeing \"header_list\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:22Z","receivedAt":"2023-01-17T17:13:07Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the \"header_list\" struct member was added in [1] it wasn't made\nto free the list using loop added for the adjacent \"pattern_list\"\nmember, see [2] for when we started freeing it.\n\nThis makes e.g. this command leak-free when run on git.git:\n\n\t./git -P log -1 --color=always --author=A origin/master\n\n1. 80235ba79ef (\"log --author=me --grep=it\" should find intersection,\n   not union, 2010-01-17)\n2. b48fb5b6a95 (grep: free expressions and patterns when done.,\n   2006-09-27)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n grep.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/grep.c b/grep.c\nindex a4450df4559..c908535e0d8 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -795,6 +795,7 @@ static void free_grep_pat(struct grep_pat *pattern)\n void free_grep_patterns(struct grep_opt *opt)\n {\n \tfree_grep_pat(opt->pattern_list);\n+\tfree_grep_pat(opt->header_list);\n \n \tif (opt->pattern_expression)\n \t\tfree_pattern_expr(opt->pattern_expression);\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470521","messageId":"patch-v4-19.19-b3aee41d0b4-20230117T151202Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v4 19/19] push: free_refs() the \"local_refs\" in set_refspecs()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:24Z","receivedAt":"2023-01-17T17:13:14Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us since this code was added in\nca02465b413 (push: use remote.$name.push as a refmap, 2013-12-03).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/push.c                          | 1 +\n t/t1416-ref-transaction-hooks.sh        | 1 +\n t/t2402-worktree-list.sh                | 1 +\n t/t5504-fetch-receive-strict.sh         | 1 +\n t/t5523-push-upstream.sh                | 1 +\n t/t5529-push-errors.sh                  | 2 ++\n t/t5546-receive-limits.sh               | 2 ++\n t/t5547-push-quarantine.sh              | 2 ++\n t/t5606-clone-options.sh                | 1 +\n t/t5810-proto-disable-local.sh          | 2 ++\n t/t5813-proto-disable-ssh.sh            | 2 ++\n t/t7409-submodule-detached-work-tree.sh | 1 +\n t/t7416-submodule-dash-url.sh           | 2 ++\n t/t7450-bad-git-dotfiles.sh             | 2 ++\n 14 files changed, 21 insertions(+)\n\ndiff --git a/builtin/push.c b/builtin/push.c\nindex 60ac8017e52..f48e4c6a856 100644\n--- a/builtin/push.c\n+++ b/builtin/push.c\n@@ -129,6 +129,7 @@ static void set_refspecs(const char **refs, int nr, const char *repo)\n \t\t} else\n \t\t\trefspec_append(&rs, ref);\n \t}\n+\tfree_refs(local_refs);\n }\n \n static int push_url_of_remote(struct remote *remote, const char ***url_p)\ndiff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh\nindex 27731722a5b..b32ca798f9f 100755\n--- a/t/t1416-ref-transaction-hooks.sh\n+++ b/t/t1416-ref-transaction-hooks.sh\n@@ -5,6 +5,7 @@ test_description='reference transaction hooks'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t2402-worktree-list.sh b/t/t2402-worktree-list.sh\nindex 79e0fce2d90..9ad9be0c208 100755\n--- a/t/t2402-worktree-list.sh\n+++ b/t/t2402-worktree-list.sh\n@@ -5,6 +5,7 @@ test_description='test git worktree list'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh\nindex ac4099ca893..14e8af1f3b7 100755\n--- a/t/t5504-fetch-receive-strict.sh\n+++ b/t/t5504-fetch-receive-strict.sh\n@@ -4,6 +4,7 @@ test_description='fetch/receive strict mode'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup and inject \"corrupt or missing\" object' '\ndiff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh\nindex fdb42920564..c9acc076353 100755\n--- a/t/t5523-push-upstream.sh\n+++ b/t/t5523-push-upstream.sh\n@@ -4,6 +4,7 @@ test_description='push with --set-upstream'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-terminal.sh\n \ndiff --git a/t/t5529-push-errors.sh b/t/t5529-push-errors.sh\nindex ce85fd30ad1..0247137cb36 100755\n--- a/t/t5529-push-errors.sh\n+++ b/t/t5529-push-errors.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='detect some push errors early (before contacting remote)'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup commits' '\ndiff --git a/t/t5546-receive-limits.sh b/t/t5546-receive-limits.sh\nindex 0b0e987fdb7..eed3c9d81ab 100755\n--- a/t/t5546-receive-limits.sh\n+++ b/t/t5546-receive-limits.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check receive input limits'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Let's run tests with different unpack limits: 1 and 10000\ndiff --git a/t/t5547-push-quarantine.sh b/t/t5547-push-quarantine.sh\nindex 1876fb34e51..9f899b8c7d7 100755\n--- a/t/t5547-push-quarantine.sh\n+++ b/t/t5547-push-quarantine.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check quarantine of objects during push'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'create picky dest repo' '\ndiff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh\nindex cf221e92c4d..27f9f776389 100755\n--- a/t/t5606-clone-options.sh\n+++ b/t/t5606-clone-options.sh\n@@ -4,6 +4,7 @@ test_description='basic clone options'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t5810-proto-disable-local.sh b/t/t5810-proto-disable-local.sh\nindex c1ef99b85c2..862610256fb 100755\n--- a/t/t5810-proto-disable-local.sh\n+++ b/t/t5810-proto-disable-local.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test disabling of local paths in clone/fetch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY/lib-proto-disable.sh\"\n \ndiff --git a/t/t5813-proto-disable-ssh.sh b/t/t5813-proto-disable-ssh.sh\nindex 3f084ee3065..2e975dc70ec 100755\n--- a/t/t5813-proto-disable-ssh.sh\n+++ b/t/t5813-proto-disable-ssh.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test disabling of git-over-ssh in clone/fetch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY/lib-proto-disable.sh\"\n \ndiff --git a/t/t7409-submodule-detached-work-tree.sh b/t/t7409-submodule-detached-work-tree.sh\nindex 374ed481e9c..574a6fc526e 100755\n--- a/t/t7409-submodule-detached-work-tree.sh\n+++ b/t/t7409-submodule-detached-work-tree.sh\n@@ -13,6 +13,7 @@ TEST_NO_CREATE_REPO=1\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7416-submodule-dash-url.sh b/t/t7416-submodule-dash-url.sh\nindex 3ebd9859814..7cf72b9a076 100755\n--- a/t/t7416-submodule-dash-url.sh\n+++ b/t/t7416-submodule-dash-url.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check handling of disallowed .gitmodule urls'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7450-bad-git-dotfiles.sh b/t/t7450-bad-git-dotfiles.sh\nindex ba1f569bcbb..0d0c3f2c683 100755\n--- a/t/t7450-bad-git-dotfiles.sh\n+++ b/t/t7450-bad-git-dotfiles.sh\n@@ -12,6 +12,8 @@ Such as:\n \n   - symlinked .gitmodules, etc\n '\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-pack.sh\n \n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470522","messageId":"patch-v4-18.19-0ad7d59b881-20230117T151202Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v4 18/19] receive-pack: free() the \"ref_name\" in \"struct command\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-17T17:11:23Z","receivedAt":"2023-01-17T17:13:31Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us since this code was introduced\nin 575f497456e (Add first cut at \"git-receive-pack\", 2005-06-29), see\neb1af2df0b1 (git-receive-pack: start parsing ref update commands,\n2005-06-29) for the later change that refactored the code to add the\n\"ref_name\" member.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/receive-pack.c                 | 10 ++++++++++\n t/t5405-send-pack-rewind.sh            |  1 +\n t/t5406-remote-rejects.sh              |  1 +\n t/t5507-remote-environment.sh          |  2 ++\n t/t5522-pull-symlink.sh                |  1 +\n t/t5527-fetch-odd-refs.sh              |  1 +\n t/t5560-http-backend-noserver.sh       |  1 +\n t/t5561-http-backend.sh                |  1 +\n t/t5562-http-backend-content-length.sh |  2 ++\n t/t5705-session-id-in-capabilities.sh  |  1 +\n 10 files changed, 21 insertions(+)\n\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex a90af303630..451bad776c6 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -2032,6 +2032,15 @@ static struct command **queue_command(struct command **tail,\n \treturn &cmd->next;\n }\n \n+static void free_commands(struct command *commands)\n+{\n+\twhile (commands) {\n+\t\tstruct command *next = commands->next;\n+\t\tfree(commands);\n+\t\tcommands = next;\n+\t}\n+}\n+\n static void queue_commands_from_cert(struct command **tail,\n \t\t\t\t     struct strbuf *push_cert)\n {\n@@ -2569,6 +2578,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n \t\trun_receive_hook(commands, \"post-receive\", 1,\n \t\t\t\t &push_options);\n \t\trun_update_post_hook(commands);\n+\t\tfree_commands(commands);\n \t\tstring_list_clear(&push_options, 0);\n \t\tif (auto_gc) {\n \t\t\tstruct child_process proc = CHILD_PROCESS_INIT;\ndiff --git a/t/t5405-send-pack-rewind.sh b/t/t5405-send-pack-rewind.sh\nindex 11f03239a06..1686ac13aa6 100755\n--- a/t/t5405-send-pack-rewind.sh\n+++ b/t/t5405-send-pack-rewind.sh\n@@ -5,6 +5,7 @@ test_description='forced push to replace commit we do not have'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5406-remote-rejects.sh b/t/t5406-remote-rejects.sh\nindex dcbeb420827..d6a99466338 100755\n--- a/t/t5406-remote-rejects.sh\n+++ b/t/t5406-remote-rejects.sh\n@@ -2,6 +2,7 @@\n \n test_description='remote push rejects are reported by client'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t5507-remote-environment.sh b/t/t5507-remote-environment.sh\nindex e6149295b18..c6a6957c500 100755\n--- a/t/t5507-remote-environment.sh\n+++ b/t/t5507-remote-environment.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check environment showed to remote side of transports'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'set up \"remote\" push situation' '\ndiff --git a/t/t5522-pull-symlink.sh b/t/t5522-pull-symlink.sh\nindex bcff460d0a2..394bc60cb8e 100755\n--- a/t/t5522-pull-symlink.sh\n+++ b/t/t5522-pull-symlink.sh\n@@ -2,6 +2,7 @@\n \n test_description='pulling from symlinked subdir'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # The scenario we are building:\ndiff --git a/t/t5527-fetch-odd-refs.sh b/t/t5527-fetch-odd-refs.sh\nindex e2770e4541f..98ece27c6a0 100755\n--- a/t/t5527-fetch-odd-refs.sh\n+++ b/t/t5527-fetch-odd-refs.sh\n@@ -4,6 +4,7 @@ test_description='test fetching of oddly-named refs'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # afterwards we will have:\ndiff --git a/t/t5560-http-backend-noserver.sh b/t/t5560-http-backend-noserver.sh\nindex d30cf4f5b83..f75068de648 100755\n--- a/t/t5560-http-backend-noserver.sh\n+++ b/t/t5560-http-backend-noserver.sh\n@@ -4,6 +4,7 @@ test_description='test git-http-backend-noserver'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n HTTPD_DOCUMENT_ROOT_PATH=\"$TRASH_DIRECTORY\"\ndiff --git a/t/t5561-http-backend.sh b/t/t5561-http-backend.sh\nindex 9c57d843152..e1d3b8caed0 100755\n--- a/t/t5561-http-backend.sh\n+++ b/t/t5561-http-backend.sh\n@@ -4,6 +4,7 @@ test_description='test git-http-backend'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-httpd.sh\n \ndiff --git a/t/t5562-http-backend-content-length.sh b/t/t5562-http-backend-content-length.sh\nindex b68ec22d3fd..7ee9858a78b 100755\n--- a/t/t5562-http-backend-content-length.sh\n+++ b/t/t5562-http-backend-content-length.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test git-http-backend respects CONTENT_LENGTH'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_lazy_prereq GZIP 'gzip --version'\ndiff --git a/t/t5705-session-id-in-capabilities.sh b/t/t5705-session-id-in-capabilities.sh\nindex ed38c76c290..b8a722ec27e 100755\n--- a/t/t5705-session-id-in-capabilities.sh\n+++ b/t/t5705-session-id-in-capabilities.sh\n@@ -2,6 +2,7 @@\n \n test_description='session ID in capabilities'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n REPO=\"$(pwd)/repo\"\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470539","messageId":"c0c07b89-7eaf-21cd-748e-e14ea57f09fd@web.de","threadId":"59011","inReplyTo":"patch-v4-19.19-b3aee41d0b4-20230117T151202Z-avarab@gmail.com","subject":"Re: [PATCH v4 19/19] push: free_refs() the \"local_refs\" in set_refspecs()","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2023-01-17T19:58:26Z","receivedAt":"2023-01-17T21:37:13Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 17.01.23 um 18:11 schrieb Ævar Arnfjörð Bjarmason:\n> Fix a memory leak that's been with us since this code was added in\n> ca02465b413 (push: use remote.$name.push as a refmap, 2013-12-03).\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  builtin/push.c                          | 1 +\n>  t/t1416-ref-transaction-hooks.sh        | 1 +\n>  t/t2402-worktree-list.sh                | 1 +\n>  t/t5504-fetch-receive-strict.sh         | 1 +\n>  t/t5523-push-upstream.sh                | 1 +\n>  t/t5529-push-errors.sh                  | 2 ++\n>  t/t5546-receive-limits.sh               | 2 ++\n>  t/t5547-push-quarantine.sh              | 2 ++\n>  t/t5606-clone-options.sh                | 1 +\n>  t/t5810-proto-disable-local.sh          | 2 ++\n>  t/t5813-proto-disable-ssh.sh            | 2 ++\n>  t/t7409-submodule-detached-work-tree.sh | 1 +\n>  t/t7416-submodule-dash-url.sh           | 2 ++\n>  t/t7450-bad-git-dotfiles.sh             | 2 ++\n>  14 files changed, 21 insertions(+)\n>\n> diff --git a/builtin/push.c b/builtin/push.c\n> index 60ac8017e52..f48e4c6a856 100644\n> --- a/builtin/push.c\n> +++ b/builtin/push.c\n> @@ -129,6 +129,7 @@ static void set_refspecs(const char **refs, int nr, const char *repo)\n>  \t\t} else\n>  \t\t\trefspec_append(&rs, ref);\n>  \t}\n> +\tfree_refs(local_refs);\n\nOK.\n\nThis can still leak local_refs if remote_get() returns NULL and lazy-\nloading is done over and over.  Unlikely to occur in the wild, I bet --\nwho pushes without a remote?  Does it make sense to also check\nlocal_refs for NULL already in this patch or is it worth its own series?\nNot sure.\n\nremote is still leaked if it isn't NULL, though.  We'd need to export\nremote_clear() to release it properly, no?  And shouldn't\nremotes_remote_get_1() call remote_clear() itself before returning\nNULL?  Not simple, separate series.\n\n>  }\n>\n>  static int push_url_of_remote(struct remote *remote, const char ***url_p)\n> diff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh\n> index 27731722a5b..b32ca798f9f 100755\n> --- a/t/t1416-ref-transaction-hooks.sh\n> +++ b/t/t1416-ref-transaction-hooks.sh\n> @@ -5,6 +5,7 @@ test_description='reference transaction hooks'\n>  GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n>  export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n>\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success setup '\n> diff --git a/t/t2402-worktree-list.sh b/t/t2402-worktree-list.sh\n> index 79e0fce2d90..9ad9be0c208 100755\n> --- a/t/t2402-worktree-list.sh\n> +++ b/t/t2402-worktree-list.sh\n> @@ -5,6 +5,7 @@ test_description='test git worktree list'\n>  GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n>  export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n>\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success 'setup' '\n> diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh\n> index ac4099ca893..14e8af1f3b7 100755\n> --- a/t/t5504-fetch-receive-strict.sh\n> +++ b/t/t5504-fetch-receive-strict.sh\n> @@ -4,6 +4,7 @@ test_description='fetch/receive strict mode'\n>  GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n>  export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n>\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success 'setup and inject \"corrupt or missing\" object' '\n> diff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh\n> index fdb42920564..c9acc076353 100755\n> --- a/t/t5523-push-upstream.sh\n> +++ b/t/t5523-push-upstream.sh\n> @@ -4,6 +4,7 @@ test_description='push with --set-upstream'\n>  GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n>  export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n>\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>  . \"$TEST_DIRECTORY\"/lib-terminal.sh\n>\n> diff --git a/t/t5529-push-errors.sh b/t/t5529-push-errors.sh\n> index ce85fd30ad1..0247137cb36 100755\n> --- a/t/t5529-push-errors.sh\n> +++ b/t/t5529-push-errors.sh\n> @@ -1,6 +1,8 @@\n>  #!/bin/sh\n>\n>  test_description='detect some push errors early (before contacting remote)'\n> +\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success 'setup commits' '\n> diff --git a/t/t5546-receive-limits.sh b/t/t5546-receive-limits.sh\n> index 0b0e987fdb7..eed3c9d81ab 100755\n> --- a/t/t5546-receive-limits.sh\n> +++ b/t/t5546-receive-limits.sh\n> @@ -1,6 +1,8 @@\n>  #!/bin/sh\n>\n>  test_description='check receive input limits'\n> +\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  # Let's run tests with different unpack limits: 1 and 10000\n> diff --git a/t/t5547-push-quarantine.sh b/t/t5547-push-quarantine.sh\n> index 1876fb34e51..9f899b8c7d7 100755\n> --- a/t/t5547-push-quarantine.sh\n> +++ b/t/t5547-push-quarantine.sh\n> @@ -1,6 +1,8 @@\n>  #!/bin/sh\n>\n>  test_description='check quarantine of objects during push'\n> +\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success 'create picky dest repo' '\n> diff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh\n> index cf221e92c4d..27f9f776389 100755\n> --- a/t/t5606-clone-options.sh\n> +++ b/t/t5606-clone-options.sh\n> @@ -4,6 +4,7 @@ test_description='basic clone options'\n>  GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n>  export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n>\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success 'setup' '\n> diff --git a/t/t5810-proto-disable-local.sh b/t/t5810-proto-disable-local.sh\n> index c1ef99b85c2..862610256fb 100755\n> --- a/t/t5810-proto-disable-local.sh\n> +++ b/t/t5810-proto-disable-local.sh\n> @@ -1,6 +1,8 @@\n>  #!/bin/sh\n>\n>  test_description='test disabling of local paths in clone/fetch'\n> +\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>  . \"$TEST_DIRECTORY/lib-proto-disable.sh\"\n>\n> diff --git a/t/t5813-proto-disable-ssh.sh b/t/t5813-proto-disable-ssh.sh\n> index 3f084ee3065..2e975dc70ec 100755\n> --- a/t/t5813-proto-disable-ssh.sh\n> +++ b/t/t5813-proto-disable-ssh.sh\n> @@ -1,6 +1,8 @@\n>  #!/bin/sh\n>\n>  test_description='test disabling of git-over-ssh in clone/fetch'\n> +\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>  . \"$TEST_DIRECTORY/lib-proto-disable.sh\"\n>\n> diff --git a/t/t7409-submodule-detached-work-tree.sh b/t/t7409-submodule-detached-work-tree.sh\n> index 374ed481e9c..574a6fc526e 100755\n> --- a/t/t7409-submodule-detached-work-tree.sh\n> +++ b/t/t7409-submodule-detached-work-tree.sh\n> @@ -13,6 +13,7 @@ TEST_NO_CREATE_REPO=1\n>  GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n>  export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n>\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success 'setup' '\n> diff --git a/t/t7416-submodule-dash-url.sh b/t/t7416-submodule-dash-url.sh\n> index 3ebd9859814..7cf72b9a076 100755\n> --- a/t/t7416-submodule-dash-url.sh\n> +++ b/t/t7416-submodule-dash-url.sh\n> @@ -1,6 +1,8 @@\n>  #!/bin/sh\n>\n>  test_description='check handling of disallowed .gitmodule urls'\n> +\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success 'setup' '\n> diff --git a/t/t7450-bad-git-dotfiles.sh b/t/t7450-bad-git-dotfiles.sh\n> index ba1f569bcbb..0d0c3f2c683 100755\n> --- a/t/t7450-bad-git-dotfiles.sh\n> +++ b/t/t7450-bad-git-dotfiles.sh\n> @@ -12,6 +12,8 @@ Such as:\n>\n>    - symlinked .gitmodules, etc\n>  '\n> +\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>  . \"$TEST_DIRECTORY\"/lib-pack.sh\n>\n"},{"id":"470540","messageId":"7e571cdd-c0fa-7519-848c-b0bc4613abab@web.de","threadId":"59011","inReplyTo":"patch-v4-15.19-66c24afb893-20230117T151202Z-avarab@gmail.com","subject":"Re: [PATCH v4 15/19] object-file.c: release the \"tag\" in check_tag()","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2023-01-17T19:58:24Z","receivedAt":"2023-01-17T21:37:24Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 17.01.23 um 18:11 schrieb Ævar Arnfjörð Bjarmason:\n> Fix a memory leak that's been with us ever since c879daa2372 (Make\n> hash-object more robust against malformed objects, 2011-02-05). With\n> \"HASH_FORMAT_CHECK\" (used by \"hash-object\" and \"replace\") we'll parse\n> tags into a throwaway variable on the stack, but weren't freeing the\n> \"item->tag\" we might malloc() when doing so.\n>\n> The clearing that release_tag_memory() does for us is redundant here,\n> but let's use it as-is anyway. It only has one other existing caller,\n> which does need the tag to be cleared.\n\nCalling it is better than getting our hands dirty with tag internals\nhere.\n\nThere's similar leak in check_commit() in the same file, but plugging it\nwould require exporting unparse_commit().  Or perhaps using the heavy\nhammer that is release_commit_memory()?  Anyway, it doesn't seem simple\nto me, so that would be a patch for a separate series.\n\n>\n> Mark the tests that now pass in their entirety as passing under\n> \"SANITIZE=leak\", which means we'll test them as part of the\n> \"linux-leaks\" CI job.\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  object-file.c         | 1 +\n>  t/t3800-mktag.sh      | 1 +\n>  t/t5302-pack-index.sh | 2 ++\n>  3 files changed, 4 insertions(+)\n>\n> diff --git a/object-file.c b/object-file.c\n> index 80a0cd3b351..b554266aff4 100644\n> --- a/object-file.c\n> +++ b/object-file.c\n> @@ -2324,6 +2324,7 @@ static void check_tag(const void *buf, size_t size)\n>  \tmemset(&t, 0, sizeof(t));\n>  \tif (parse_tag_buffer(the_repository, &t, buf, size))\n>  \t\tdie(_(\"corrupt tag\"));\n> +\trelease_tag_memory(&t);\n>  }\n>\n>  static int index_mem(struct index_state *istate,\n> diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh\n> index e3cf0ffbe59..d3e428ff46e 100755\n> --- a/t/t3800-mktag.sh\n> +++ b/t/t3800-mktag.sh\n> @@ -4,6 +4,7 @@\n>\n>  test_description='git mktag: tag object verify test'\n>\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  ###########################################################\n> diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh\n> index b0095ab41d3..54b11f81c63 100755\n> --- a/t/t5302-pack-index.sh\n> +++ b/t/t5302-pack-index.sh\n> @@ -4,6 +4,8 @@\n>  #\n>\n>  test_description='pack index with 64-bit offsets and object CRC'\n> +\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success 'setup' '\n"},{"id":"470582","messageId":"xmqqedrs8igj.fsf@gitster.g","threadId":"59011","inReplyTo":"patch-v4-08.19-1fe25bc6981-20230117T151202Z-avarab@gmail.com","subject":"Re: [PATCH v4 08/19] worktree: fix a trivial leak in prune_worktrees()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-01-18T06:28:28Z","receivedAt":"2023-01-18T06:55:29Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> We were leaking both the \"struct strbuf\" in prune_worktrees(), as well\n> as the \"path\" we got from should_prune_worktree(). Since these were\n> the only two uses of the \"struct string_list\" let's change it to a\n> \"DUP\" and push these to it with \"string_list_append_nodup()\".\n> ...\n> diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh\n> index d34d77f8934..ba8d929d189 100755\n> --- a/t/t3203-branch-output.sh\n> +++ b/t/t3203-branch-output.sh\n> @@ -1,6 +1,8 @@\n>  #!/bin/sh\n>  \n>  test_description='git branch display tests'\n> +\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>  . \"$TEST_DIRECTORY\"/lib-terminal.sh\n\nThis is wrong, isn't it?\n\nt3203 uses --points-at, which populates filter.points_at by calling\nparse_opt_object_name().  Various members of the ref-filter\nstructure is never freed (and there is no API helper function in\nref-filter subsystem).\n\nOther tests that use --points-at (e.g. t6302 and t7004) are not\nmarked with \"passes_sanitize_leak\", and this one shouldn't be,\neither.\n\nWith the following squashed in, the branch seems to pass, but I am\nnot sure which is lessor of the two evils.  From the point of view\nof the code maintenance, UNLEAK() to mark this singleton variable is\nfar cleaner to deal with than selectively running the leak checks\nwith the \"passes_sanitize_leak\" mechanism (which always feels like a\nlosing whack-a-mole hack).\n\n builtin/branch.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git c/builtin/branch.c w/builtin/branch.c\nindex f63fd45edb..4fe7757670 100644\n--- c/builtin/branch.c\n+++ w/builtin/branch.c\n@@ -742,6 +742,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \tif (filter.abbrev == -1)\n \t\tfilter.abbrev = DEFAULT_ABBREV;\n \tfilter.ignore_case = icase;\n+\tUNLEAK(filter);\n \n \tfinalize_colopts(&colopts, -1);\n \tif (filter.verbose) {\n\n"},{"id":"470585","messageId":"xmqq1qns8gz4.fsf_-_@gitster.g","threadId":"59011","inReplyTo":"xmqqedrs8igj.fsf@gitster.g","subject":"[PATCH v4 20/19] branch: the ref_filter is not cleaned","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-01-18T07:00:31Z","receivedAt":"2023-01-18T07:40:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Recently, a test that uses \"branch --point-at\" was marked\n(incorrectly) as passing the leak tests, but it was premature.\n\nAs there is no API support to release the resource held by the\nref_filter structure when we are done, let's mark the singleton\ninstance that does not grow unbounded as such with UNLEAK() to\nsquelch pointless leak checker errors.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin/branch.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex f63fd45edb..4fe7757670 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -742,6 +742,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \tif (filter.abbrev == -1)\n \t\tfilter.abbrev = DEFAULT_ABBREV;\n \tfilter.ignore_case = icase;\n+\tUNLEAK(filter);\n \n \tfinalize_colopts(&colopts, -1);\n \tif (filter.verbose) {\n-- \n2.39.1-231-ga7caae2729\n\n"},{"id":"470592","messageId":"230118.86o7qwxg4e.gmgdl@evledraar.gmail.com","threadId":"59011","inReplyTo":"xmqqedrs8igj.fsf@gitster.g","subject":"Re: [PATCH v4 08/19] worktree: fix a trivial leak in prune_worktrees()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T10:57:16Z","receivedAt":"2023-01-18T11:42:56Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Tue, Jan 17 2023, Junio C Hamano wrote:\n\n> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n>\n>> We were leaking both the \"struct strbuf\" in prune_worktrees(), as well\n>> as the \"path\" we got from should_prune_worktree(). Since these were\n>> the only two uses of the \"struct string_list\" let's change it to a\n>> \"DUP\" and push these to it with \"string_list_append_nodup()\".\n>> ...\n>> diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh\n>> index d34d77f8934..ba8d929d189 100755\n>> --- a/t/t3203-branch-output.sh\n>> +++ b/t/t3203-branch-output.sh\n>> @@ -1,6 +1,8 @@\n>>  #!/bin/sh\n>>  \n>>  test_description='git branch display tests'\n>> +\n>> +TEST_PASSES_SANITIZE_LEAK=true\n>>  . ./test-lib.sh\n>>  . \"$TEST_DIRECTORY\"/lib-terminal.sh\n>\n> This is wrong, isn't it?\n>\n> t3203 uses --points-at, which populates filter.points_at by calling\n> parse_opt_object_name().  Various members of the ref-filter\n> structure is never freed (and there is no API helper function in\n> ref-filter subsystem).\n>\n> Other tests that use --points-at (e.g. t6302 and t7004) are not\n> marked with \"passes_sanitize_leak\", and this one shouldn't be,\n> either.\n>\n> With the following squashed in, the branch seems to pass, but I am\n> not sure which is lessor of the two evils.  From the point of view\n> of the code maintenance, UNLEAK() to mark this singleton variable is\n> far cleaner to deal with than selectively running the leak checks\n> with the \"passes_sanitize_leak\" mechanism (which always feels like a\n> losing whack-a-mole hack).\n>\n>  builtin/branch.c | 1 +\n>  1 file changed, 1 insertion(+)\n>\n> diff --git c/builtin/branch.c w/builtin/branch.c\n> index f63fd45edb..4fe7757670 100644\n> --- c/builtin/branch.c\n> +++ w/builtin/branch.c\n> @@ -742,6 +742,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n>  \tif (filter.abbrev == -1)\n>  \t\tfilter.abbrev = DEFAULT_ABBREV;\n>  \tfilter.ignore_case = icase;\n> +\tUNLEAK(filter);\n>  \n>  \tfinalize_colopts(&colopts, -1);\n>  \tif (filter.verbose) {\n\nI'll send a v5 re-roll without this change, sorry.\n\nThis is a case where the version of GCC I was testing with doesn't\nreport the leak, but clang does (and probably other versions of GCC),\nsorry.\n"},{"id":"470601","messageId":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com","subject":"[PATCH v5 00/19] leak fixes: various simple leak fixes","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:13Z","receivedAt":"2023-01-18T12:46:34Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"See\nhttps://lore.kernel.org/git/cover-v4-00.19-00000000000-20230117T151201Z-avarab@gmail.com/\nfor the v4. Change since then:\n\n* Don't mark t/t3203-branch-output.sh as passing, which was new in\n  v4. As noted in\n  https://lore.kernel.org/git/xmqq1qns8gz4.fsf_-_@gitster.g/ it still\n  leaked.\n\n  As I noted in\n  https://lore.kernel.org/git/230118.86o7qwxg4e.gmgdl@evledraar.gmail.com/\n  this was a gcc v.s. clang difference.\n\n  I a fix for that \"filter\" leak as a follow-up, let's just fix it for\n  real at some point, rather than using the UNLEAK(), sorry about the\n  churn.\n\n* The couple of things René pointed out on v4 I both took (and he\n  seems to think so) as suggestions for eventual follow-ups.\n\n  In general I agree that some of the fixes here have deeper\n  root-cause fixes that are worth doing at some point, but in the\n  meantime having some simple leak fixes (and CI regression testing\n  for them) is an improvement.\n\nÆvar Arnfjörð Bjarmason (19):\n  tests: mark tests as passing with SANITIZE=leak\n  bundle.c: don't leak the \"args\" in the \"struct child_process\"\n  commit-graph: use free_commit_graph() instead of UNLEAK()\n  clone: use free() instead of UNLEAK()\n  various: add missing clear_pathspec(), fix leaks\n  name-rev: don't xstrdup() an already dup'd string\n  repack: fix leaks on error with \"goto cleanup\"\n  worktree: fix a trivial leak in prune_worktrees()\n  http-backend.c: fix \"dir\" and \"cmd_arg\" leaks in cmd_main()\n  http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()\n  commit-graph: fix a parse_options_concat() leak\n  show-branch: free() allocated \"head\" before return\n  builtin/merge.c: use fixed strings, not \"strbuf\", fix leak\n  builtin/merge.c: free \"&buf\" on \"Your local changes...\" error\n  object-file.c: release the \"tag\" in check_tag()\n  grep.c: refactor free_grep_patterns()\n  grep API: plug memory leaks by freeing \"header_list\"\n  receive-pack: free() the \"ref_name\" in \"struct command\"\n  push: free_refs() the \"local_refs\" in set_refspecs()\n\n archive.c                                  |  1 +\n builtin/clean.c                            |  1 +\n builtin/clone.c                            |  5 +++--\n builtin/commit-graph.c                     | 10 ++++++----\n builtin/merge.c                            | 14 ++++++-------\n builtin/name-rev.c                         | 23 ++++++++++------------\n builtin/push.c                             |  1 +\n builtin/receive-pack.c                     | 10 ++++++++++\n builtin/repack.c                           | 13 ++++++------\n builtin/reset.c                            | 11 ++++++++---\n builtin/show-branch.c                      |  1 +\n builtin/stash.c                            |  7 +++++--\n builtin/worktree.c                         |  6 +++---\n bundle.c                                   |  6 ++++--\n grep.c                                     | 15 +++++++++-----\n http-backend.c                             |  9 +++++++--\n object-file.c                              |  1 +\n t/t0023-crlf-am.sh                         |  1 +\n t/t1301-shared-repo.sh                     |  1 +\n t/t1302-repo-version.sh                    |  1 +\n t/t1304-default-acl.sh                     |  1 +\n t/t1408-packed-refs.sh                     |  1 +\n t/t1410-reflog.sh                          |  1 +\n t/t1416-ref-transaction-hooks.sh           |  1 +\n t/t2401-worktree-prune.sh                  |  1 +\n t/t2402-worktree-list.sh                   |  1 +\n t/t2406-worktree-repair.sh                 |  1 +\n t/t3210-pack-refs.sh                       |  1 +\n t/t3800-mktag.sh                           |  1 +\n t/t4152-am-subjects.sh                     |  2 ++\n t/t4254-am-corrupt.sh                      |  2 ++\n t/t4256-am-format-flowed.sh                |  1 +\n t/t4257-am-interactive.sh                  |  2 ++\n t/t5001-archive-attr.sh                    |  1 +\n t/t5004-archive-corner-cases.sh            |  2 ++\n t/t5302-pack-index.sh                      |  2 ++\n t/t5317-pack-objects-filter-objects.sh     |  1 +\n t/t5330-no-lazy-fetch-with-commit-graph.sh |  1 +\n t/t5403-post-checkout-hook.sh              |  1 +\n t/t5405-send-pack-rewind.sh                |  1 +\n t/t5406-remote-rejects.sh                  |  1 +\n t/t5502-quickfetch.sh                      |  1 +\n t/t5504-fetch-receive-strict.sh            |  1 +\n t/t5507-remote-environment.sh              |  2 ++\n t/t5522-pull-symlink.sh                    |  1 +\n t/t5523-push-upstream.sh                   |  1 +\n t/t5527-fetch-odd-refs.sh                  |  1 +\n t/t5529-push-errors.sh                     |  2 ++\n t/t5546-receive-limits.sh                  |  2 ++\n t/t5547-push-quarantine.sh                 |  2 ++\n t/t5560-http-backend-noserver.sh           |  1 +\n t/t5561-http-backend.sh                    |  1 +\n t/t5562-http-backend-content-length.sh     |  2 ++\n t/t5604-clone-reference.sh                 |  1 +\n t/t5606-clone-options.sh                   |  1 +\n t/t5613-info-alternate.sh                  |  2 ++\n t/t5705-session-id-in-capabilities.sh      |  1 +\n t/t5810-proto-disable-local.sh             |  2 ++\n t/t5813-proto-disable-ssh.sh               |  2 ++\n t/t6011-rev-list-with-bad-commit.sh        |  1 +\n t/t6014-rev-list-all.sh                    |  1 +\n t/t6021-rev-list-exclude-hidden.sh         |  1 +\n t/t6439-merge-co-error-msgs.sh             |  1 +\n t/t7105-reset-patch.sh                     |  2 ++\n t/t7106-reset-unborn-branch.sh             |  2 ++\n t/t7107-reset-pathspec-file.sh             |  1 +\n t/t7301-clean-interactive.sh               |  1 +\n t/t7403-submodule-sync.sh                  |  1 +\n t/t7409-submodule-detached-work-tree.sh    |  1 +\n t/t7416-submodule-dash-url.sh              |  2 ++\n t/t7450-bad-git-dotfiles.sh                |  2 ++\n t/t7701-repack-unpack-unreachable.sh       |  1 +\n 72 files changed, 156 insertions(+), 50 deletions(-)\n\nRange-diff against v4:\n 1:  2ed69e3cda3 =  1:  c47fc0fb637 tests: mark tests as passing with SANITIZE=leak\n 2:  9993786ba0d =  2:  9eb758117dc bundle.c: don't leak the \"args\" in the \"struct child_process\"\n 3:  8e98d7c4ebf =  3:  01b6229f18a commit-graph: use free_commit_graph() instead of UNLEAK()\n 4:  966d7657d54 =  4:  f4f3aef2861 clone: use free() instead of UNLEAK()\n 5:  93a8f8fa1b9 =  5:  8d10fbe0b8f various: add missing clear_pathspec(), fix leaks\n 6:  bd15d991ac7 =  6:  eb5dc3ac192 name-rev: don't xstrdup() an already dup'd string\n 7:  fd890121ebe =  7:  1fac90c306a repack: fix leaks on error with \"goto cleanup\"\n 8:  1fe25bc6981 !  8:  02248aca3eb worktree: fix a trivial leak in prune_worktrees()\n    @@ t/t2406-worktree-repair.sh\n      . ./test-lib.sh\n      \n      test_expect_success setup '\n    -\n    - ## t/t3203-branch-output.sh ##\n    -@@\n    - #!/bin/sh\n    - \n    - test_description='git branch display tests'\n    -+\n    -+TEST_PASSES_SANITIZE_LEAK=true\n    - . ./test-lib.sh\n    - . \"$TEST_DIRECTORY\"/lib-terminal.sh\n    - \n 9:  6b3dd9b15f0 =  9:  b39d6d29dd5 http-backend.c: fix \"dir\" and \"cmd_arg\" leaks in cmd_main()\n10:  246f71bb447 = 10:  928dea2d4ee http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()\n11:  ab31d8d10da = 11:  5770b9eb764 commit-graph: fix a parse_options_concat() leak\n12:  9054b353220 = 12:  3ff86cb808c show-branch: free() allocated \"head\" before return\n13:  05836b08e0f = 13:  1f3e3524580 builtin/merge.c: use fixed strings, not \"strbuf\", fix leak\n14:  e8ea18b08c2 = 14:  15e4b8db805 builtin/merge.c: free \"&buf\" on \"Your local changes...\" error\n15:  66c24afb893 = 15:  d36ad1f818a object-file.c: release the \"tag\" in check_tag()\n16:  52744d9690f = 16:  10959760dfc grep.c: refactor free_grep_patterns()\n17:  8ff63d9095c = 17:  6a8f4a567aa grep API: plug memory leaks by freeing \"header_list\"\n18:  0ad7d59b881 = 18:  3c3d48df04b receive-pack: free() the \"ref_name\" in \"struct command\"\n19:  b3aee41d0b4 = 19:  f29500a4abc push: free_refs() the \"local_refs\" in set_refspecs()\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470602","messageId":"patch-v5-02.19-9eb758117dc-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v5 02/19] bundle.c: don't leak the \"args\" in the \"struct child_process\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:15Z","receivedAt":"2023-01-18T12:46:39Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a leak that's been here since 7366096de9d (bundle API: change\n\"flags\" to be \"extra_index_pack_args\", 2021-09-05), if can't verify\nthe bundle we didn't call child_process_clear() to clear the \"args\".\n\nBut rather than doing that let's verify the bundle before we start\npreparing the process we're going to spawn, if we get an error we\ndon't need to push anything to the \"args\".\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n bundle.c | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/bundle.c b/bundle.c\nindex 4ef7256aa11..9ebb10a8f72 100644\n--- a/bundle.c\n+++ b/bundle.c\n@@ -627,6 +627,10 @@ int unbundle(struct repository *r, struct bundle_header *header,\n \t     enum verify_bundle_flags flags)\n {\n \tstruct child_process ip = CHILD_PROCESS_INIT;\n+\n+\tif (verify_bundle(r, header, flags))\n+\t\treturn -1;\n+\n \tstrvec_pushl(&ip.args, \"index-pack\", \"--fix-thin\", \"--stdin\", NULL);\n \n \t/* If there is a filter, then we need to create the promisor pack. */\n@@ -638,8 +642,6 @@ int unbundle(struct repository *r, struct bundle_header *header,\n \t\tstrvec_clear(extra_index_pack_args);\n \t}\n \n-\tif (verify_bundle(r, header, flags))\n-\t\treturn -1;\n \tip.in = bundle_fd;\n \tip.no_stdout = 1;\n \tip.git_cmd = 1;\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470603","messageId":"patch-v5-01.19-c47fc0fb637-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v5 01/19] tests: mark tests as passing with SANITIZE=leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:14Z","receivedAt":"2023-01-18T12:46:41Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the \"ab/various-leak-fixes\" topic was merged in [1] only t6021\nwould fail if the tests were run in the\n\"GIT_TEST_PASSING_SANITIZE_LEAK=check\" mode, i.e. to check whether we\nmarked all leak-free tests with \"TEST_PASSES_SANITIZE_LEAK=true\".\n\nSince then we've had various tests starting to pass under\nSANITIZE=leak. Let's mark those as passing, this is when they started\nto pass, narrowed down with \"git bisect\":\n\n- t5317-pack-objects-filter-objects.sh: In\n  faebba436e6 (list-objects-filter: plug pattern_list leak, 2022-12-01).\n\n- t3210-pack-refs.sh, t5613-info-alternate.sh,\n  t7403-submodule-sync.sh: In 189e97bc4ba (diff: remove parseopts member\n  from struct diff_options, 2022-12-01).\n\n- t1408-packed-refs.sh: In ab91f6b7c42 (Merge branch\n  'rs/diff-parseopts', 2022-12-19).\n\n- t0023-crlf-am.sh, t4152-am-subjects.sh, t4254-am-corrupt.sh,\n  t4256-am-format-flowed.sh, t4257-am-interactive.sh,\n  t5403-post-checkout-hook.sh: In a658e881c13 (am: don't pass strvec to\n  apply_parse_options(), 2022-12-13)\n\n- t1301-shared-repo.sh, t1302-repo-version.sh: In b07a819c05f (reflog:\n  clear leftovers in reflog_expiry_cleanup(), 2022-12-13).\n\n- t1304-default-acl.sh, t1410-reflog.sh,\n  t5330-no-lazy-fetch-with-commit-graph.sh, t5502-quickfetch.sh,\n  t5604-clone-reference.sh, t6014-rev-list-all.sh,\n  t7701-repack-unpack-unreachable.sh: In b0c61be3209 (Merge branch\n  'rs/reflog-expiry-cleanup', 2022-12-26)\n\n1. 9ea1378d046 (Merge branch 'ab/various-leak-fixes', 2022-12-14)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n t/t0023-crlf-am.sh                         | 1 +\n t/t1301-shared-repo.sh                     | 1 +\n t/t1302-repo-version.sh                    | 1 +\n t/t1304-default-acl.sh                     | 1 +\n t/t1408-packed-refs.sh                     | 1 +\n t/t1410-reflog.sh                          | 1 +\n t/t3210-pack-refs.sh                       | 1 +\n t/t4152-am-subjects.sh                     | 2 ++\n t/t4254-am-corrupt.sh                      | 2 ++\n t/t4256-am-format-flowed.sh                | 1 +\n t/t4257-am-interactive.sh                  | 2 ++\n t/t5317-pack-objects-filter-objects.sh     | 1 +\n t/t5330-no-lazy-fetch-with-commit-graph.sh | 1 +\n t/t5403-post-checkout-hook.sh              | 1 +\n t/t5502-quickfetch.sh                      | 1 +\n t/t5604-clone-reference.sh                 | 1 +\n t/t5613-info-alternate.sh                  | 2 ++\n t/t6014-rev-list-all.sh                    | 1 +\n t/t6021-rev-list-exclude-hidden.sh         | 1 +\n t/t7403-submodule-sync.sh                  | 1 +\n t/t7701-repack-unpack-unreachable.sh       | 1 +\n 21 files changed, 25 insertions(+)\n\ndiff --git a/t/t0023-crlf-am.sh b/t/t0023-crlf-am.sh\nindex f9bbb91f64e..575805513a3 100755\n--- a/t/t0023-crlf-am.sh\n+++ b/t/t0023-crlf-am.sh\n@@ -2,6 +2,7 @@\n \n test_description='Test am with auto.crlf'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n cat >patchfile <<\\EOF\ndiff --git a/t/t1301-shared-repo.sh b/t/t1301-shared-repo.sh\nindex 93a2f91f8a5..a1251f65100 100755\n--- a/t/t1301-shared-repo.sh\n+++ b/t/t1301-shared-repo.sh\n@@ -8,6 +8,7 @@ test_description='Test shared repository initialization'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Remove a default ACL from the test dir if possible.\ndiff --git a/t/t1302-repo-version.sh b/t/t1302-repo-version.sh\nindex 7cf80bf66a6..70389fa2ebb 100755\n--- a/t/t1302-repo-version.sh\n+++ b/t/t1302-repo-version.sh\n@@ -5,6 +5,7 @@\n \n test_description='Test repository version check'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh\nindex c69ae41306c..31b89dd9693 100755\n--- a/t/t1304-default-acl.sh\n+++ b/t/t1304-default-acl.sh\n@@ -9,6 +9,7 @@ test_description='Test repository with default ACL'\n # => this must come before . ./test-lib.sh\n umask 077\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # We need an arbitrary other user give permission to using ACLs. root\ndiff --git a/t/t1408-packed-refs.sh b/t/t1408-packed-refs.sh\nindex 41ba1f1d7fc..9469c79a585 100755\n--- a/t/t1408-packed-refs.sh\n+++ b/t/t1408-packed-refs.sh\n@@ -5,6 +5,7 @@ test_description='packed-refs entries are covered by loose refs'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh\nindex aa59954f6c5..6c45965b1e4 100755\n--- a/t/t1410-reflog.sh\n+++ b/t/t1410-reflog.sh\n@@ -7,6 +7,7 @@ test_description='Test prune and reflog expiration'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n check_have () {\ndiff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh\nindex 577f32dc71f..07a0ff93def 100755\n--- a/t/t3210-pack-refs.sh\n+++ b/t/t3210-pack-refs.sh\n@@ -12,6 +12,7 @@ semantic is still the same.\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'enable reflogs' '\ndiff --git a/t/t4152-am-subjects.sh b/t/t4152-am-subjects.sh\nindex 4c68245acad..9f2edba1f83 100755\n--- a/t/t4152-am-subjects.sh\n+++ b/t/t4152-am-subjects.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test subject preservation with format-patch | am'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n make_patches() {\ndiff --git a/t/t4254-am-corrupt.sh b/t/t4254-am-corrupt.sh\nindex 54be7da1611..45f1d4f95e5 100755\n--- a/t/t4254-am-corrupt.sh\n+++ b/t/t4254-am-corrupt.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git am with corrupt input'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n make_mbox_with_nul () {\ndiff --git a/t/t4256-am-format-flowed.sh b/t/t4256-am-format-flowed.sh\nindex 2369c4e17ad..1015273bc82 100755\n--- a/t/t4256-am-format-flowed.sh\n+++ b/t/t4256-am-format-flowed.sh\n@@ -2,6 +2,7 @@\n \n test_description='test format=flowed support of git am'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t4257-am-interactive.sh b/t/t4257-am-interactive.sh\nindex aed8f4de3d6..f26d7fd2dbd 100755\n--- a/t/t4257-am-interactive.sh\n+++ b/t/t4257-am-interactive.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='am --interactive tests'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'set up patches to apply' '\ndiff --git a/t/t5317-pack-objects-filter-objects.sh b/t/t5317-pack-objects-filter-objects.sh\nindex 5b707d911b5..b26d476c646 100755\n--- a/t/t5317-pack-objects-filter-objects.sh\n+++ b/t/t5317-pack-objects-filter-objects.sh\n@@ -5,6 +5,7 @@ test_description='git pack-objects using object filtering'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Test blob:none filter.\ndiff --git a/t/t5330-no-lazy-fetch-with-commit-graph.sh b/t/t5330-no-lazy-fetch-with-commit-graph.sh\nindex 2cc7fd7a476..5eb28f0512d 100755\n--- a/t/t5330-no-lazy-fetch-with-commit-graph.sh\n+++ b/t/t5330-no-lazy-fetch-with-commit-graph.sh\n@@ -2,6 +2,7 @@\n \n test_description='test for no lazy fetch with the commit-graph'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup: prepare a repository with a commit' '\ndiff --git a/t/t5403-post-checkout-hook.sh b/t/t5403-post-checkout-hook.sh\nindex 978f240cdac..cfaae547398 100755\n--- a/t/t5403-post-checkout-hook.sh\n+++ b/t/t5403-post-checkout-hook.sh\n@@ -7,6 +7,7 @@ test_description='Test the post-checkout hook.'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5502-quickfetch.sh b/t/t5502-quickfetch.sh\nindex b160f8b7fb7..7b3ff21b984 100755\n--- a/t/t5502-quickfetch.sh\n+++ b/t/t5502-quickfetch.sh\n@@ -5,6 +5,7 @@ test_description='test quickfetch from local'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh\nindex 2734e37e880..dc86dea1333 100755\n--- a/t/t5604-clone-reference.sh\n+++ b/t/t5604-clone-reference.sh\n@@ -7,6 +7,7 @@ test_description='test clone --reference'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n base_dir=$(pwd)\ndiff --git a/t/t5613-info-alternate.sh b/t/t5613-info-alternate.sh\nindex 895f46bb911..7708cbafa98 100755\n--- a/t/t5613-info-alternate.sh\n+++ b/t/t5613-info-alternate.sh\n@@ -4,6 +4,8 @@\n #\n \n test_description='test transitive info/alternate entries'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'preparing first repository' '\ndiff --git a/t/t6014-rev-list-all.sh b/t/t6014-rev-list-all.sh\nindex c9bedd29cba..16b8bd1d090 100755\n--- a/t/t6014-rev-list-all.sh\n+++ b/t/t6014-rev-list-all.sh\n@@ -2,6 +2,7 @@\n \n test_description='--all includes detached HEADs'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n \ndiff --git a/t/t6021-rev-list-exclude-hidden.sh b/t/t6021-rev-list-exclude-hidden.sh\nindex 32b2b094138..11c50b7c0dd 100755\n--- a/t/t6021-rev-list-exclude-hidden.sh\n+++ b/t/t6021-rev-list-exclude-hidden.sh\n@@ -2,6 +2,7 @@\n \n test_description='git rev-list --exclude-hidden test'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh\nindex ea92ef52a5e..ff09443a0a4 100755\n--- a/t/t7403-submodule-sync.sh\n+++ b/t/t7403-submodule-sync.sh\n@@ -11,6 +11,7 @@ These tests exercise the \"git submodule sync\" subcommand.\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t7701-repack-unpack-unreachable.sh b/t/t7701-repack-unpack-unreachable.sh\nindex b7ac4f598a8..ebb267855fe 100755\n--- a/t/t7701-repack-unpack-unreachable.sh\n+++ b/t/t7701-repack-unpack-unreachable.sh\n@@ -5,6 +5,7 @@ test_description='git repack works correctly'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n fsha1=\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470604","messageId":"patch-v5-07.19-1fac90c306a-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v5 07/19] repack: fix leaks on error with \"goto cleanup\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:20Z","receivedAt":"2023-01-18T12:46:44Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change cmd_repack() to \"goto cleanup\" rather than \"return ret\" on\nerror, when we returned we'd potentially skip cleaning up the\nstring_lists and other data we'd allocated in this function.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/repack.c                    | 13 +++++++------\n t/t6011-rev-list-with-bad-commit.sh |  1 +\n 2 files changed, 8 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/repack.c b/builtin/repack.c\nindex c1402ad038f..f6493795318 100644\n--- a/builtin/repack.c\n+++ b/builtin/repack.c\n@@ -948,7 +948,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \n \tret = start_command(&cmd);\n \tif (ret)\n-\t\treturn ret;\n+\t\tgoto cleanup;\n \n \tif (geometry) {\n \t\tFILE *in = xfdopen(cmd.in, \"w\");\n@@ -977,7 +977,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \tfclose(out);\n \tret = finish_command(&cmd);\n \tif (ret)\n-\t\treturn ret;\n+\t\tgoto cleanup;\n \n \tif (!names.nr && !po_args.quiet)\n \t\tprintf_ln(_(\"Nothing new to pack.\"));\n@@ -1007,7 +1007,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\t\t\t       &existing_nonkept_packs,\n \t\t\t\t       &existing_kept_packs);\n \t\tif (ret)\n-\t\t\treturn ret;\n+\t\t\tgoto cleanup;\n \n \t\tif (delete_redundant && expire_to) {\n \t\t\t/*\n@@ -1039,7 +1039,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\t\t\t\t       &existing_nonkept_packs,\n \t\t\t\t\t       &existing_kept_packs);\n \t\t\tif (ret)\n-\t\t\t\treturn ret;\n+\t\t\t\tgoto cleanup;\n \t\t}\n \t}\n \n@@ -1115,7 +1115,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\tstring_list_clear(&include, 0);\n \n \t\tif (ret)\n-\t\t\treturn ret;\n+\t\t\tgoto cleanup;\n \t}\n \n \treprepare_packed_git(the_repository);\n@@ -1172,10 +1172,11 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\twrite_midx_file(get_object_directory(), NULL, NULL, flags);\n \t}\n \n+cleanup:\n \tstring_list_clear(&names, 1);\n \tstring_list_clear(&existing_nonkept_packs, 0);\n \tstring_list_clear(&existing_kept_packs, 0);\n \tclear_pack_geometry(geometry);\n \n-\treturn 0;\n+\treturn ret;\n }\ndiff --git a/t/t6011-rev-list-with-bad-commit.sh b/t/t6011-rev-list-with-bad-commit.sh\nindex bad02cf5b83..b2e422cf0f7 100755\n--- a/t/t6011-rev-list-with-bad-commit.sh\n+++ b/t/t6011-rev-list-with-bad-commit.sh\n@@ -2,6 +2,7 @@\n \n test_description='git rev-list should notice bad commits'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Note:\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470605","messageId":"patch-v5-06.19-eb5dc3ac192-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v5 06/19] name-rev: don't xstrdup() an already dup'd string","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:19Z","receivedAt":"2023-01-18T12:46:48Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When \"add_to_tip_table()\" is called with a non-zero\n\"shorten_unambiguous\" we always return an xstrdup()'d string, which\nwe'd then xstrdup() again, leaking memory. See [1] and [2] for how\nthis leak came about.\n\nWe could xstrdup() only if \"shorten_unambiguous\" wasn't true, but\nlet's instead inline this code, so that information on whether we need\nto xstrdup() is contained within add_to_tip_table().\n\n1. 98c5c4ad015 (name-rev: allow to specify a subpath for --refs\n   option, 2013-06-18)\n2. b23e0b9353e (name-rev: allow converting the exact object name at\n   the tip of a ref, 2013-07-07)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/name-rev.c | 23 ++++++++++-------------\n 1 file changed, 10 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin/name-rev.c b/builtin/name-rev.c\nindex 15535e914a6..49fae523694 100644\n--- a/builtin/name-rev.c\n+++ b/builtin/name-rev.c\n@@ -273,17 +273,6 @@ static int subpath_matches(const char *path, const char *filter)\n \treturn -1;\n }\n \n-static const char *name_ref_abbrev(const char *refname, int shorten_unambiguous)\n-{\n-\tif (shorten_unambiguous)\n-\t\trefname = shorten_unambiguous_ref(refname, 0);\n-\telse if (skip_prefix(refname, \"refs/heads/\", &refname))\n-\t\t; /* refname already advanced */\n-\telse\n-\t\tskip_prefix(refname, \"refs/\", &refname);\n-\treturn refname;\n-}\n-\n struct name_ref_data {\n \tint tags_only;\n \tint name_only;\n@@ -309,11 +298,19 @@ static void add_to_tip_table(const struct object_id *oid, const char *refname,\n \t\t\t     int shorten_unambiguous, struct commit *commit,\n \t\t\t     timestamp_t taggerdate, int from_tag, int deref)\n {\n-\trefname = name_ref_abbrev(refname, shorten_unambiguous);\n+\tchar *short_refname = NULL;\n+\n+\tif (shorten_unambiguous)\n+\t\tshort_refname = shorten_unambiguous_ref(refname, 0);\n+\telse if (skip_prefix(refname, \"refs/heads/\", &refname))\n+\t\t; /* refname already advanced */\n+\telse\n+\t\tskip_prefix(refname, \"refs/\", &refname);\n \n \tALLOC_GROW(tip_table.table, tip_table.nr + 1, tip_table.alloc);\n \toidcpy(&tip_table.table[tip_table.nr].oid, oid);\n-\ttip_table.table[tip_table.nr].refname = xstrdup(refname);\n+\ttip_table.table[tip_table.nr].refname = short_refname ?\n+\t\tshort_refname : xstrdup(refname);\n \ttip_table.table[tip_table.nr].commit = commit;\n \ttip_table.table[tip_table.nr].taggerdate = taggerdate;\n \ttip_table.table[tip_table.nr].from_tag = from_tag;\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470606","messageId":"patch-v5-03.19-01b6229f18a-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v5 03/19] commit-graph: use free_commit_graph() instead of UNLEAK()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:16Z","receivedAt":"2023-01-18T12:46:53Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"In 0bfb48e6723 (builtin/commit-graph.c: UNLEAK variables, 2018-10-03)\nthis was made to UNLEAK(), but we can just as easily invoke the\nfree_commit_graph() function added in c3756d5b7fc (commit-graph: add\nfree_commit_graph, 2018-07-11) instead.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/commit-graph.c | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/commit-graph.c b/builtin/commit-graph.c\nindex e8f77f535f3..0102ac8540e 100644\n--- a/builtin/commit-graph.c\n+++ b/builtin/commit-graph.c\n@@ -67,6 +67,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix)\n \tint fd;\n \tstruct stat st;\n \tint flags = 0;\n+\tint ret;\n \n \tstatic struct option builtin_commit_graph_verify_options[] = {\n \t\tOPT_BOOL(0, \"shallow\", &opts.shallow,\n@@ -111,8 +112,9 @@ static int graph_verify(int argc, const char **argv, const char *prefix)\n \tif (!graph)\n \t\treturn !!open_ok;\n \n-\tUNLEAK(graph);\n-\treturn verify_commit_graph(the_repository, graph, flags);\n+\tret = verify_commit_graph(the_repository, graph, flags);\n+\tfree_commit_graph(graph);\n+\treturn ret;\n }\n \n extern int read_replace_refs;\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470607","messageId":"patch-v5-04.19-f4f3aef2861-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v5 04/19] clone: use free() instead of UNLEAK()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:17Z","receivedAt":"2023-01-18T12:47:01Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change an UNLEAK() added in 0c4542738e6 (clone: free or UNLEAK further\npointers when finished, 2021-03-14) to use a \"to_free\" pattern\ninstead. In this case the \"repo\" can be either this absolute_pathdup()\nvalue, or in the \"else if\" branch seen in the context the the\n\"argv[0]\" argument to \"main()\".\n\nWe can only free() the value in the former case, hence the \"to_free\"\npattern.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/clone.c | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 5453ba5277f..ba82f5e4108 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -892,6 +892,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tint is_bundle = 0, is_local;\n \tint reject_shallow = 0;\n \tconst char *repo_name, *repo, *work_tree, *git_dir;\n+\tchar *repo_to_free = NULL;\n \tchar *path = NULL, *dir, *display_repo = NULL;\n \tint dest_exists, real_dest_exists = 0;\n \tconst struct ref *refs, *remote_head;\n@@ -949,7 +950,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tpath = get_repo_path(repo_name, &is_bundle);\n \tif (path) {\n \t\tFREE_AND_NULL(path);\n-\t\trepo = absolute_pathdup(repo_name);\n+\t\trepo = repo_to_free = absolute_pathdup(repo_name);\n \t} else if (strchr(repo_name, ':')) {\n \t\trepo = repo_name;\n \t\tdisplay_repo = transport_anonymize_url(repo);\n@@ -1413,7 +1414,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tfree(unborn_head);\n \tfree(dir);\n \tfree(path);\n-\tUNLEAK(repo);\n+\tfree(repo_to_free);\n \tjunk_mode = JUNK_LEAVE_ALL;\n \n \ttransport_ls_refs_options_release(&transport_ls_refs_options);\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470608","messageId":"patch-v5-05.19-8d10fbe0b8f-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v5 05/19] various: add missing clear_pathspec(), fix leaks","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:18Z","receivedAt":"2023-01-18T12:47:07Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix memory leaks resulting from a missing clear_pathspec().\n\n- archive.c: Plug a leak in the \"struct archiver_args\", and\n  clear_pathspec() the \"pathspec\" member that the \"parse_pathspec_arg()\"\n  call in this function populates.\n\n- builtin/clean.c: Fix a memory leak that's been with us since\n  893d839970c (clean: convert to use parse_pathspec, 2013-07-14).\n\n- builtin/reset.c: Add clear_pathspec() calls to cmd_reset(),\n  including to the codepaths where we'd return early.\n\n- builtin/stash.c: Call clear_pathspec() on the pathspec initialized\n  in push_stash().\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n archive.c                       |  1 +\n builtin/clean.c                 |  1 +\n builtin/reset.c                 | 11 ++++++++---\n builtin/stash.c                 |  7 +++++--\n t/t5001-archive-attr.sh         |  1 +\n t/t5004-archive-corner-cases.sh |  2 ++\n t/t7105-reset-patch.sh          |  2 ++\n t/t7106-reset-unborn-branch.sh  |  2 ++\n t/t7107-reset-pathspec-file.sh  |  1 +\n t/t7301-clean-interactive.sh    |  1 +\n 10 files changed, 24 insertions(+), 5 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex 941495f5d78..a2d813e50db 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -710,6 +710,7 @@ int write_archive(int argc, const char **argv, const char *prefix,\n \n \tstring_list_clear_func(&args.extra_files, extra_file_info_clear);\n \tfree(args.refname);\n+\tclear_pathspec(&args.pathspec);\n \n \treturn rc;\n }\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex b2701a28158..b15eab328b7 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -1092,5 +1092,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tstrbuf_release(&buf);\n \tstring_list_clear(&del_list, 0);\n \tstring_list_clear(&exclude_list, 0);\n+\tclear_pathspec(&pathspec);\n \treturn (errors != 0);\n }\ndiff --git a/builtin/reset.c b/builtin/reset.c\nindex fea20a9ba0b..e9c10618cd3 100644\n--- a/builtin/reset.c\n+++ b/builtin/reset.c\n@@ -390,7 +390,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \t\tif (reset_type != NONE)\n \t\t\tdie(_(\"options '%s' and '%s' cannot be used together\"), \"--patch\", \"--{hard,mixed,soft}\");\n \t\ttrace2_cmd_mode(\"patch-interactive\");\n-\t\treturn run_add_interactive(rev, \"--patch=reset\", &pathspec);\n+\t\tupdate_ref_status = run_add_interactive(rev, \"--patch=reset\", &pathspec);\n+\t\tgoto cleanup;\n \t}\n \n \t/* git reset tree [--] paths... can be used to\n@@ -439,8 +440,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \t\t\t\t       LOCK_DIE_ON_ERROR);\n \t\tif (reset_type == MIXED) {\n \t\t\tint flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;\n-\t\t\tif (read_from_tree(&pathspec, &oid, intent_to_add))\n-\t\t\t\treturn 1;\n+\t\t\tif (read_from_tree(&pathspec, &oid, intent_to_add)) {\n+\t\t\t\tupdate_ref_status = 1;\n+\t\t\t\tgoto cleanup;\n+\t\t\t}\n \t\t\tthe_index.updated_skipworktree = 1;\n \t\t\tif (!no_refresh && get_git_work_tree()) {\n \t\t\t\tuint64_t t_begin, t_delta_in_ms;\n@@ -488,5 +491,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \n \tdiscard_index(&the_index);\n \n+cleanup:\n+\tclear_pathspec(&pathspec);\n \treturn update_ref_status;\n }\ndiff --git a/builtin/stash.c b/builtin/stash.c\nindex bb0fd861434..45bffdf54bb 100644\n--- a/builtin/stash.c\n+++ b/builtin/stash.c\n@@ -1727,6 +1727,7 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n \t\tOPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),\n \t\tOPT_END()\n \t};\n+\tint ret;\n \n \tif (argc) {\n \t\tforce_assume = !strcmp(argv[0], \"-p\");\n@@ -1766,8 +1767,10 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n \t\tdie(_(\"the option '%s' requires '%s'\"), \"--pathspec-file-nul\", \"--pathspec-from-file\");\n \t}\n \n-\treturn do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n-\t\t\t     include_untracked, only_staged);\n+\tret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n+\t\t\t    include_untracked, only_staged);\n+\tclear_pathspec(&ps);\n+\treturn ret;\n }\n \n static int push_stash_unassumed(int argc, const char **argv, const char *prefix)\ndiff --git a/t/t5001-archive-attr.sh b/t/t5001-archive-attr.sh\nindex 2f6eef5e372..04d300eeda7 100755\n--- a/t/t5001-archive-attr.sh\n+++ b/t/t5001-archive-attr.sh\n@@ -3,6 +3,7 @@\n test_description='git archive attribute tests'\n \n TEST_CREATE_REPO_NO_TEMPLATE=1\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n SUBSTFORMAT='%H (%h)%n'\ndiff --git a/t/t5004-archive-corner-cases.sh b/t/t5004-archive-corner-cases.sh\nindex ae508e21623..9f2c6da80e8 100755\n--- a/t/t5004-archive-corner-cases.sh\n+++ b/t/t5004-archive-corner-cases.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test corner cases of git-archive'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # the 10knuls.tar file is used to test for an empty git generated tar\ndiff --git a/t/t7105-reset-patch.sh b/t/t7105-reset-patch.sh\nindex fc2a6cf5c7a..9b46da7aaa7 100755\n--- a/t/t7105-reset-patch.sh\n+++ b/t/t7105-reset-patch.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git reset --patch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./lib-patch-mode.sh\n \n test_expect_success PERL 'setup' '\ndiff --git a/t/t7106-reset-unborn-branch.sh b/t/t7106-reset-unborn-branch.sh\nindex ecb85c3b823..a0b67a0b843 100755\n--- a/t/t7106-reset-unborn-branch.sh\n+++ b/t/t7106-reset-unborn-branch.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git reset should work on unborn branch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7107-reset-pathspec-file.sh b/t/t7107-reset-pathspec-file.sh\nindex 523efbecde1..af5ea406db3 100755\n--- a/t/t7107-reset-pathspec-file.sh\n+++ b/t/t7107-reset-pathspec-file.sh\n@@ -2,6 +2,7 @@\n \n test_description='reset --pathspec-from-file'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_tick\ndiff --git a/t/t7301-clean-interactive.sh b/t/t7301-clean-interactive.sh\nindex a07e8b86de2..d82a3210a1d 100755\n--- a/t/t7301-clean-interactive.sh\n+++ b/t/t7301-clean-interactive.sh\n@@ -2,6 +2,7 @@\n \n test_description='git clean -i basic tests'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-terminal.sh\n \n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470609","messageId":"patch-v5-10.19-928dea2d4ee-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v5 10/19] http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:23Z","receivedAt":"2023-01-18T12:47:11Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us ever since\n2f4038ab337 (Git-aware CGI to provide dumb HTTP transport,\n2009-10-30). In this case we're not calling regerror() after a failed\nregexec(), and don't otherwise use \"re\" afterwards.\n\nWe can therefore simplify this code by calling regfree() right after\nthe regexec(). An alternative fix would be to add a regfree() to both\nthe \"return\" and \"break\" path in this for-loop.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n http-backend.c | 7 +++++--\n 1 file changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/http-backend.c b/http-backend.c\nindex 67819d931ce..8ab58e55f85 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -759,10 +759,14 @@ int cmd_main(int argc, const char **argv)\n \t\tstruct service_cmd *c = &services[i];\n \t\tregex_t re;\n \t\tregmatch_t out[1];\n+\t\tint ret;\n \n \t\tif (regcomp(&re, c->pattern, REG_EXTENDED))\n \t\t\tdie(\"Bogus regex in service table: %s\", c->pattern);\n-\t\tif (!regexec(&re, dir, 1, out, 0)) {\n+\t\tret = regexec(&re, dir, 1, out, 0);\n+\t\tregfree(&re);\n+\n+\t\tif (!ret) {\n \t\t\tsize_t n;\n \n \t\t\tif (strcmp(method, c->method))\n@@ -774,7 +778,6 @@ int cmd_main(int argc, const char **argv)\n \t\t\tdir[out[0].rm_so] = 0;\n \t\t\tbreak;\n \t\t}\n-\t\tregfree(&re);\n \t}\n \n \tif (!cmd)\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470610","messageId":"patch-v5-08.19-02248aca3eb-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v5 08/19] worktree: fix a trivial leak in prune_worktrees()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:21Z","receivedAt":"2023-01-18T12:47:11Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"We were leaking both the \"struct strbuf\" in prune_worktrees(), as well\nas the \"path\" we got from should_prune_worktree(). Since these were\nthe only two uses of the \"struct string_list\" let's change it to a\n\"DUP\" and push these to it with \"string_list_append_nodup()\".\n\nFor the string_list_append_nodup() we could also string_list_append()\nthe main_path.buf, and then strbuf_release(&main_path) right away. But\ndoing it this way avoids an allocation, as we already have the \"struct\nstrbuf\" prepared for appending to \"kept\".\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/worktree.c         | 6 +++---\n t/t2401-worktree-prune.sh  | 1 +\n t/t2406-worktree-repair.sh | 1 +\n 3 files changed, 5 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex 591d659faea..865ce9be22b 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -173,7 +173,7 @@ static void prune_worktrees(void)\n {\n \tstruct strbuf reason = STRBUF_INIT;\n \tstruct strbuf main_path = STRBUF_INIT;\n-\tstruct string_list kept = STRING_LIST_INIT_NODUP;\n+\tstruct string_list kept = STRING_LIST_INIT_DUP;\n \tDIR *dir = opendir(git_path(\"worktrees\"));\n \tstruct dirent *d;\n \tif (!dir)\n@@ -184,14 +184,14 @@ static void prune_worktrees(void)\n \t\tif (should_prune_worktree(d->d_name, &reason, &path, expire))\n \t\t\tprune_worktree(d->d_name, reason.buf);\n \t\telse if (path)\n-\t\t\tstring_list_append(&kept, path)->util = xstrdup(d->d_name);\n+\t\t\tstring_list_append_nodup(&kept, path)->util = xstrdup(d->d_name);\n \t}\n \tclosedir(dir);\n \n \tstrbuf_add_absolute_path(&main_path, get_git_common_dir());\n \t/* massage main worktree absolute path to match 'gitdir' content */\n \tstrbuf_strip_suffix(&main_path, \"/.\");\n-\tstring_list_append(&kept, strbuf_detach(&main_path, NULL));\n+\tstring_list_append_nodup(&kept, strbuf_detach(&main_path, NULL));\n \tprune_dups(&kept);\n \tstring_list_clear(&kept, 1);\n \ndiff --git a/t/t2401-worktree-prune.sh b/t/t2401-worktree-prune.sh\nindex 3d28c7f06b2..568a47ec426 100755\n--- a/t/t2401-worktree-prune.sh\n+++ b/t/t2401-worktree-prune.sh\n@@ -5,6 +5,7 @@ test_description='prune $GIT_DIR/worktrees'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success initialize '\ndiff --git a/t/t2406-worktree-repair.sh b/t/t2406-worktree-repair.sh\nindex 5c44453e1c1..8970780efcc 100755\n--- a/t/t2406-worktree-repair.sh\n+++ b/t/t2406-worktree-repair.sh\n@@ -2,6 +2,7 @@\n \n test_description='test git worktree repair'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470611","messageId":"patch-v5-11.19-5770b9eb764-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v5 11/19] commit-graph: fix a parse_options_concat() leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:24Z","receivedAt":"2023-01-18T12:47:13Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the parse_options_concat() was added to this file in\n84e4484f128 (commit-graph: use parse_options_concat(), 2021-08-23) we\nwouldn't free() it if we returned early in these cases.\n\nSince \"result\" is 0 by default we can \"goto cleanup\" in both cases,\nand only need to set \"result\" if write_commit_graph_reachable() fails.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/commit-graph.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/commit-graph.c b/builtin/commit-graph.c\nindex 0102ac8540e..93704f95a9d 100644\n--- a/builtin/commit-graph.c\n+++ b/builtin/commit-graph.c\n@@ -269,8 +269,8 @@ static int graph_write(int argc, const char **argv, const char *prefix)\n \n \tif (opts.reachable) {\n \t\tif (write_commit_graph_reachable(odb, flags, &write_opts))\n-\t\t\treturn 1;\n-\t\treturn 0;\n+\t\t\tresult = 1;\n+\t\tgoto cleanup;\n \t}\n \n \tif (opts.stdin_packs) {\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470612","messageId":"patch-v5-12.19-3ff86cb808c-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v5 12/19] show-branch: free() allocated \"head\" before return","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:25Z","receivedAt":"2023-01-18T12:47:15Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Stop leaking the \"head\" variable, which we've been leaking since it\nwas originally added in [1], and in its current form since [2]\n\n1. ed378ec7e85 (Make ref resolution saner, 2006-09-11)\n2. d9e557a320b (show-branch: store resolved head in heap buffer,\n   2017-02-14).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/show-branch.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/show-branch.c b/builtin/show-branch.c\nindex c013abaf942..358ac3e519a 100644\n--- a/builtin/show-branch.c\n+++ b/builtin/show-branch.c\n@@ -956,5 +956,6 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)\n \t\tif (shown_merge_point && --extra < 0)\n \t\t\tbreak;\n \t}\n+\tfree(head);\n \treturn 0;\n }\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470613","messageId":"patch-v5-09.19-b39d6d29dd5-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v5 09/19] http-backend.c: fix \"dir\" and \"cmd_arg\" leaks in cmd_main()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:22Z","receivedAt":"2023-01-18T12:47:18Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Free the \"dir\" variable after we're done with it. Before\n917adc03608 (http-backend: add GIT_PROJECT_ROOT environment var,\n2009-10-30) there was no leak here, as we'd get it via getenv(), but\nsince 917adc03608 we've xstrdup()'d it (or the equivalent), so we need\nto free() it.\n\nWe also need to free the \"cmd_arg\" variable, which has been leaked\never since it was added in 2f4038ab337 (Git-aware CGI to provide dumb\nHTTP transport, 2009-10-30).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n http-backend.c | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git a/http-backend.c b/http-backend.c\nindex 6eb3b2fe51c..67819d931ce 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -786,6 +786,7 @@ int cmd_main(int argc, const char **argv)\n \tif (!getenv(\"GIT_HTTP_EXPORT_ALL\") &&\n \t    access(\"git-daemon-export-ok\", F_OK) )\n \t\tnot_found(&hdr, \"Repository not exported: '%s'\", dir);\n+\tfree(dir);\n \n \thttp_config();\n \tmax_request_buffer = git_env_ulong(\"GIT_HTTP_MAX_REQUEST_BUFFER\",\n@@ -795,5 +796,6 @@ int cmd_main(int argc, const char **argv)\n \t\tsetenv(GIT_PROTOCOL_ENVIRONMENT, proto_header, 0);\n \n \tcmd->imp(&hdr, cmd_arg);\n+\tfree(cmd_arg);\n \treturn 0;\n }\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470614","messageId":"patch-v5-17.19-6a8f4a567aa-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v5 17/19] grep API: plug memory leaks by freeing \"header_list\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:30Z","receivedAt":"2023-01-18T12:47:18Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the \"header_list\" struct member was added in [1] it wasn't made\nto free the list using loop added for the adjacent \"pattern_list\"\nmember, see [2] for when we started freeing it.\n\nThis makes e.g. this command leak-free when run on git.git:\n\n\t./git -P log -1 --color=always --author=A origin/master\n\n1. 80235ba79ef (\"log --author=me --grep=it\" should find intersection,\n   not union, 2010-01-17)\n2. b48fb5b6a95 (grep: free expressions and patterns when done.,\n   2006-09-27)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n grep.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/grep.c b/grep.c\nindex a4450df4559..c908535e0d8 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -795,6 +795,7 @@ static void free_grep_pat(struct grep_pat *pattern)\n void free_grep_patterns(struct grep_opt *opt)\n {\n \tfree_grep_pat(opt->pattern_list);\n+\tfree_grep_pat(opt->header_list);\n \n \tif (opt->pattern_expression)\n \t\tfree_pattern_expr(opt->pattern_expression);\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470615","messageId":"patch-v5-15.19-d36ad1f818a-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v5 15/19] object-file.c: release the \"tag\" in check_tag()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:28Z","receivedAt":"2023-01-18T12:47:23Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us ever since c879daa2372 (Make\nhash-object more robust against malformed objects, 2011-02-05). With\n\"HASH_FORMAT_CHECK\" (used by \"hash-object\" and \"replace\") we'll parse\ntags into a throwaway variable on the stack, but weren't freeing the\n\"item->tag\" we might malloc() when doing so.\n\nThe clearing that release_tag_memory() does for us is redundant here,\nbut let's use it as-is anyway. It only has one other existing caller,\nwhich does need the tag to be cleared.\n\nMark the tests that now pass in their entirety as passing under\n\"SANITIZE=leak\", which means we'll test them as part of the\n\"linux-leaks\" CI job.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n object-file.c         | 1 +\n t/t3800-mktag.sh      | 1 +\n t/t5302-pack-index.sh | 2 ++\n 3 files changed, 4 insertions(+)\n\ndiff --git a/object-file.c b/object-file.c\nindex 80a0cd3b351..b554266aff4 100644\n--- a/object-file.c\n+++ b/object-file.c\n@@ -2324,6 +2324,7 @@ static void check_tag(const void *buf, size_t size)\n \tmemset(&t, 0, sizeof(t));\n \tif (parse_tag_buffer(the_repository, &t, buf, size))\n \t\tdie(_(\"corrupt tag\"));\n+\trelease_tag_memory(&t);\n }\n \n static int index_mem(struct index_state *istate,\ndiff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh\nindex e3cf0ffbe59..d3e428ff46e 100755\n--- a/t/t3800-mktag.sh\n+++ b/t/t3800-mktag.sh\n@@ -4,6 +4,7 @@\n \n test_description='git mktag: tag object verify test'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n ###########################################################\ndiff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh\nindex b0095ab41d3..54b11f81c63 100755\n--- a/t/t5302-pack-index.sh\n+++ b/t/t5302-pack-index.sh\n@@ -4,6 +4,8 @@\n #\n \n test_description='pack index with 64-bit offsets and object CRC'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470616","messageId":"patch-v5-19.19-f29500a4abc-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v5 19/19] push: free_refs() the \"local_refs\" in set_refspecs()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:32Z","receivedAt":"2023-01-18T12:47:27Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us since this code was added in\nca02465b413 (push: use remote.$name.push as a refmap, 2013-12-03).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/push.c                          | 1 +\n t/t1416-ref-transaction-hooks.sh        | 1 +\n t/t2402-worktree-list.sh                | 1 +\n t/t5504-fetch-receive-strict.sh         | 1 +\n t/t5523-push-upstream.sh                | 1 +\n t/t5529-push-errors.sh                  | 2 ++\n t/t5546-receive-limits.sh               | 2 ++\n t/t5547-push-quarantine.sh              | 2 ++\n t/t5606-clone-options.sh                | 1 +\n t/t5810-proto-disable-local.sh          | 2 ++\n t/t5813-proto-disable-ssh.sh            | 2 ++\n t/t7409-submodule-detached-work-tree.sh | 1 +\n t/t7416-submodule-dash-url.sh           | 2 ++\n t/t7450-bad-git-dotfiles.sh             | 2 ++\n 14 files changed, 21 insertions(+)\n\ndiff --git a/builtin/push.c b/builtin/push.c\nindex 60ac8017e52..f48e4c6a856 100644\n--- a/builtin/push.c\n+++ b/builtin/push.c\n@@ -129,6 +129,7 @@ static void set_refspecs(const char **refs, int nr, const char *repo)\n \t\t} else\n \t\t\trefspec_append(&rs, ref);\n \t}\n+\tfree_refs(local_refs);\n }\n \n static int push_url_of_remote(struct remote *remote, const char ***url_p)\ndiff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh\nindex 27731722a5b..b32ca798f9f 100755\n--- a/t/t1416-ref-transaction-hooks.sh\n+++ b/t/t1416-ref-transaction-hooks.sh\n@@ -5,6 +5,7 @@ test_description='reference transaction hooks'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t2402-worktree-list.sh b/t/t2402-worktree-list.sh\nindex 79e0fce2d90..9ad9be0c208 100755\n--- a/t/t2402-worktree-list.sh\n+++ b/t/t2402-worktree-list.sh\n@@ -5,6 +5,7 @@ test_description='test git worktree list'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh\nindex ac4099ca893..14e8af1f3b7 100755\n--- a/t/t5504-fetch-receive-strict.sh\n+++ b/t/t5504-fetch-receive-strict.sh\n@@ -4,6 +4,7 @@ test_description='fetch/receive strict mode'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup and inject \"corrupt or missing\" object' '\ndiff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh\nindex fdb42920564..c9acc076353 100755\n--- a/t/t5523-push-upstream.sh\n+++ b/t/t5523-push-upstream.sh\n@@ -4,6 +4,7 @@ test_description='push with --set-upstream'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-terminal.sh\n \ndiff --git a/t/t5529-push-errors.sh b/t/t5529-push-errors.sh\nindex ce85fd30ad1..0247137cb36 100755\n--- a/t/t5529-push-errors.sh\n+++ b/t/t5529-push-errors.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='detect some push errors early (before contacting remote)'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup commits' '\ndiff --git a/t/t5546-receive-limits.sh b/t/t5546-receive-limits.sh\nindex 0b0e987fdb7..eed3c9d81ab 100755\n--- a/t/t5546-receive-limits.sh\n+++ b/t/t5546-receive-limits.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check receive input limits'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Let's run tests with different unpack limits: 1 and 10000\ndiff --git a/t/t5547-push-quarantine.sh b/t/t5547-push-quarantine.sh\nindex 1876fb34e51..9f899b8c7d7 100755\n--- a/t/t5547-push-quarantine.sh\n+++ b/t/t5547-push-quarantine.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check quarantine of objects during push'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'create picky dest repo' '\ndiff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh\nindex cf221e92c4d..27f9f776389 100755\n--- a/t/t5606-clone-options.sh\n+++ b/t/t5606-clone-options.sh\n@@ -4,6 +4,7 @@ test_description='basic clone options'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t5810-proto-disable-local.sh b/t/t5810-proto-disable-local.sh\nindex c1ef99b85c2..862610256fb 100755\n--- a/t/t5810-proto-disable-local.sh\n+++ b/t/t5810-proto-disable-local.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test disabling of local paths in clone/fetch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY/lib-proto-disable.sh\"\n \ndiff --git a/t/t5813-proto-disable-ssh.sh b/t/t5813-proto-disable-ssh.sh\nindex 3f084ee3065..2e975dc70ec 100755\n--- a/t/t5813-proto-disable-ssh.sh\n+++ b/t/t5813-proto-disable-ssh.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test disabling of git-over-ssh in clone/fetch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY/lib-proto-disable.sh\"\n \ndiff --git a/t/t7409-submodule-detached-work-tree.sh b/t/t7409-submodule-detached-work-tree.sh\nindex 374ed481e9c..574a6fc526e 100755\n--- a/t/t7409-submodule-detached-work-tree.sh\n+++ b/t/t7409-submodule-detached-work-tree.sh\n@@ -13,6 +13,7 @@ TEST_NO_CREATE_REPO=1\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7416-submodule-dash-url.sh b/t/t7416-submodule-dash-url.sh\nindex 3ebd9859814..7cf72b9a076 100755\n--- a/t/t7416-submodule-dash-url.sh\n+++ b/t/t7416-submodule-dash-url.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check handling of disallowed .gitmodule urls'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7450-bad-git-dotfiles.sh b/t/t7450-bad-git-dotfiles.sh\nindex ba1f569bcbb..0d0c3f2c683 100755\n--- a/t/t7450-bad-git-dotfiles.sh\n+++ b/t/t7450-bad-git-dotfiles.sh\n@@ -12,6 +12,8 @@ Such as:\n \n   - symlinked .gitmodules, etc\n '\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-pack.sh\n \n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470617","messageId":"patch-v5-13.19-1f3e3524580-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v5 13/19] builtin/merge.c: use fixed strings, not \"strbuf\", fix leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:26Z","receivedAt":"2023-01-18T12:47:29Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Follow-up 465028e0e25 (merge: add missing strbuf_release(),\n2021-10-07) and address the \"msg\" memory leak in this block. We could\nfree \"&msg\" before the \"goto done\" here, but even better is to avoid\nallocating it in the first place.\n\nBy repeating the \"Fast-forward\" string here we can avoid using a\n\"struct strbuf\" altogether.\n\nSuggested-by: René Scharfe <l.s.r@web.de>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/merge.c                | 11 ++++-------\n t/t6439-merge-co-error-msgs.sh |  1 +\n 2 files changed, 5 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 0f093f2a4f2..91dd5435c59 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -1560,7 +1560,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t!common->next &&\n \t\t\toideq(&common->item->object.oid, &head_commit->object.oid)) {\n \t\t/* Again the most common case of merging one remote. */\n-\t\tstruct strbuf msg = STRBUF_INIT;\n+\t\tconst char *msg = have_message ?\n+\t\t\t\"Fast-forward (no commit created; -m option ignored)\" :\n+\t\t\t\"Fast-forward\";\n \t\tstruct commit *commit;\n \n \t\tif (verbosity >= 0) {\n@@ -1570,10 +1572,6 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t       find_unique_abbrev(&remoteheads->item->object.oid,\n \t\t\t\t\t\t  DEFAULT_ABBREV));\n \t\t}\n-\t\tstrbuf_addstr(&msg, \"Fast-forward\");\n-\t\tif (have_message)\n-\t\t\tstrbuf_addstr(&msg,\n-\t\t\t\t\" (no commit created; -m option ignored)\");\n \t\tcommit = remoteheads->item;\n \t\tif (!commit) {\n \t\t\tret = 1;\n@@ -1592,9 +1590,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\tgoto done;\n \t\t}\n \n-\t\tfinish(head_commit, remoteheads, &commit->object.oid, msg.buf);\n+\t\tfinish(head_commit, remoteheads, &commit->object.oid, msg);\n \t\tremove_merge_branch_state(the_repository);\n-\t\tstrbuf_release(&msg);\n \t\tgoto done;\n \t} else if (!remoteheads->next && common->next)\n \t\t;\ndiff --git a/t/t6439-merge-co-error-msgs.sh b/t/t6439-merge-co-error-msgs.sh\nindex 52cf0c87690..0cbec57cdab 100755\n--- a/t/t6439-merge-co-error-msgs.sh\n+++ b/t/t6439-merge-co-error-msgs.sh\n@@ -5,6 +5,7 @@ test_description='unpack-trees error messages'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n \n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470618","messageId":"patch-v5-16.19-10959760dfc-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v5 16/19] grep.c: refactor free_grep_patterns()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:29Z","receivedAt":"2023-01-18T12:47:32Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Refactor the free_grep_patterns() function to split out the freeing of\nthe \"struct grep_pat\" it contains, right now we're only freeing the\n\"pattern_list\", but we should be freeing another member of the same\ntype, which we'll do in the subsequent commit.\n\nLet's also replace the \"return\" if we don't have an\n\"opt->pattern_expression\" with a conditional call of\nfree_pattern_expr().\n\nBefore db84376f981 (grep.c: remove \"extended\" in favor of\n\"pattern_expression\", fix segfault, 2022-10-11) the pattern here was:\n\n\tif (!x)\n\t\treturn;\n\tfree(y);\n\nBut after the cleanup in db84376f981 (which was a narrow segfault fix,\nand thus avoided refactoring this) we ended up with:\n\n\tif (!x)\n\t\treturn;\n\tfree(x);\n\nLet's instead do:\n\n\tif (x)\n\t\tfree(x);\n\nThis doesn't matter for the subsequent change, but as we're\nrefactoring this function let's make it easier to reason about, and to\nextend in the future, i.e. if we start to free free() members that\ncome after \"pattern_expression\" in the \"struct grep_opt\".\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n grep.c | 14 +++++++++-----\n 1 file changed, 9 insertions(+), 5 deletions(-)\n\ndiff --git a/grep.c b/grep.c\nindex 06eed694936..a4450df4559 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -769,11 +769,11 @@ static void free_pattern_expr(struct grep_expr *x)\n \tfree(x);\n }\n \n-void free_grep_patterns(struct grep_opt *opt)\n+static void free_grep_pat(struct grep_pat *pattern)\n {\n \tstruct grep_pat *p, *n;\n \n-\tfor (p = opt->pattern_list; p; p = n) {\n+\tfor (p = pattern; p; p = n) {\n \t\tn = p->next;\n \t\tswitch (p->token) {\n \t\tcase GREP_PATTERN: /* atom */\n@@ -790,10 +790,14 @@ void free_grep_patterns(struct grep_opt *opt)\n \t\t}\n \t\tfree(p);\n \t}\n+}\n \n-\tif (!opt->pattern_expression)\n-\t\treturn;\n-\tfree_pattern_expr(opt->pattern_expression);\n+void free_grep_patterns(struct grep_opt *opt)\n+{\n+\tfree_grep_pat(opt->pattern_list);\n+\n+\tif (opt->pattern_expression)\n+\t\tfree_pattern_expr(opt->pattern_expression);\n }\n \n static const char *end_of_line(const char *cp, unsigned long *left)\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470619","messageId":"patch-v5-14.19-15e4b8db805-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v5 14/19] builtin/merge.c: free \"&buf\" on \"Your local changes...\" error","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:27Z","receivedAt":"2023-01-18T12:47:35Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Plug a memory leak introduced in [1], since that change didn't follow\nthe \"goto done\" pattern introduced in [2] we'd leak the \"&buf\" memory.\n\n1. e4cdfe84a0d (merge: abort if index does not match HEAD for trivial\n   merges, 2022-07-23)\n2. d5a35c114ab (Copy resolve_ref() return value for longer use,\n   2011-11-13)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/merge.c | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 91dd5435c59..2b13124c497 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -1618,7 +1618,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t\terror(_(\"Your local changes to the following files would be overwritten by merge:\\n  %s\"),\n \t\t\t\t      sb.buf);\n \t\t\t\tstrbuf_release(&sb);\n-\t\t\t\treturn 2;\n+\t\t\t\tret = 2;\n+\t\t\t\tgoto done;\n \t\t\t}\n \n \t\t\t/* See if it is really trivial. */\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470620","messageId":"patch-v5-18.19-3c3d48df04b-20230118T120334Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v5 18/19] receive-pack: free() the \"ref_name\" in \"struct command\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T12:08:31Z","receivedAt":"2023-01-18T12:47:38Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us since this code was introduced\nin 575f497456e (Add first cut at \"git-receive-pack\", 2005-06-29), see\neb1af2df0b1 (git-receive-pack: start parsing ref update commands,\n2005-06-29) for the later change that refactored the code to add the\n\"ref_name\" member.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/receive-pack.c                 | 10 ++++++++++\n t/t5405-send-pack-rewind.sh            |  1 +\n t/t5406-remote-rejects.sh              |  1 +\n t/t5507-remote-environment.sh          |  2 ++\n t/t5522-pull-symlink.sh                |  1 +\n t/t5527-fetch-odd-refs.sh              |  1 +\n t/t5560-http-backend-noserver.sh       |  1 +\n t/t5561-http-backend.sh                |  1 +\n t/t5562-http-backend-content-length.sh |  2 ++\n t/t5705-session-id-in-capabilities.sh  |  1 +\n 10 files changed, 21 insertions(+)\n\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex a90af303630..451bad776c6 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -2032,6 +2032,15 @@ static struct command **queue_command(struct command **tail,\n \treturn &cmd->next;\n }\n \n+static void free_commands(struct command *commands)\n+{\n+\twhile (commands) {\n+\t\tstruct command *next = commands->next;\n+\t\tfree(commands);\n+\t\tcommands = next;\n+\t}\n+}\n+\n static void queue_commands_from_cert(struct command **tail,\n \t\t\t\t     struct strbuf *push_cert)\n {\n@@ -2569,6 +2578,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n \t\trun_receive_hook(commands, \"post-receive\", 1,\n \t\t\t\t &push_options);\n \t\trun_update_post_hook(commands);\n+\t\tfree_commands(commands);\n \t\tstring_list_clear(&push_options, 0);\n \t\tif (auto_gc) {\n \t\t\tstruct child_process proc = CHILD_PROCESS_INIT;\ndiff --git a/t/t5405-send-pack-rewind.sh b/t/t5405-send-pack-rewind.sh\nindex 11f03239a06..1686ac13aa6 100755\n--- a/t/t5405-send-pack-rewind.sh\n+++ b/t/t5405-send-pack-rewind.sh\n@@ -5,6 +5,7 @@ test_description='forced push to replace commit we do not have'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5406-remote-rejects.sh b/t/t5406-remote-rejects.sh\nindex dcbeb420827..d6a99466338 100755\n--- a/t/t5406-remote-rejects.sh\n+++ b/t/t5406-remote-rejects.sh\n@@ -2,6 +2,7 @@\n \n test_description='remote push rejects are reported by client'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t5507-remote-environment.sh b/t/t5507-remote-environment.sh\nindex e6149295b18..c6a6957c500 100755\n--- a/t/t5507-remote-environment.sh\n+++ b/t/t5507-remote-environment.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check environment showed to remote side of transports'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'set up \"remote\" push situation' '\ndiff --git a/t/t5522-pull-symlink.sh b/t/t5522-pull-symlink.sh\nindex bcff460d0a2..394bc60cb8e 100755\n--- a/t/t5522-pull-symlink.sh\n+++ b/t/t5522-pull-symlink.sh\n@@ -2,6 +2,7 @@\n \n test_description='pulling from symlinked subdir'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # The scenario we are building:\ndiff --git a/t/t5527-fetch-odd-refs.sh b/t/t5527-fetch-odd-refs.sh\nindex e2770e4541f..98ece27c6a0 100755\n--- a/t/t5527-fetch-odd-refs.sh\n+++ b/t/t5527-fetch-odd-refs.sh\n@@ -4,6 +4,7 @@ test_description='test fetching of oddly-named refs'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # afterwards we will have:\ndiff --git a/t/t5560-http-backend-noserver.sh b/t/t5560-http-backend-noserver.sh\nindex d30cf4f5b83..f75068de648 100755\n--- a/t/t5560-http-backend-noserver.sh\n+++ b/t/t5560-http-backend-noserver.sh\n@@ -4,6 +4,7 @@ test_description='test git-http-backend-noserver'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n HTTPD_DOCUMENT_ROOT_PATH=\"$TRASH_DIRECTORY\"\ndiff --git a/t/t5561-http-backend.sh b/t/t5561-http-backend.sh\nindex 9c57d843152..e1d3b8caed0 100755\n--- a/t/t5561-http-backend.sh\n+++ b/t/t5561-http-backend.sh\n@@ -4,6 +4,7 @@ test_description='test git-http-backend'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-httpd.sh\n \ndiff --git a/t/t5562-http-backend-content-length.sh b/t/t5562-http-backend-content-length.sh\nindex b68ec22d3fd..7ee9858a78b 100755\n--- a/t/t5562-http-backend-content-length.sh\n+++ b/t/t5562-http-backend-content-length.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test git-http-backend respects CONTENT_LENGTH'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_lazy_prereq GZIP 'gzip --version'\ndiff --git a/t/t5705-session-id-in-capabilities.sh b/t/t5705-session-id-in-capabilities.sh\nindex ed38c76c290..b8a722ec27e 100755\n--- a/t/t5705-session-id-in-capabilities.sh\n+++ b/t/t5705-session-id-in-capabilities.sh\n@@ -2,6 +2,7 @@\n \n test_description='session ID in capabilities'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n REPO=\"$(pwd)/repo\"\n-- \n2.39.0.1225.g30a3d88132d\n\n"},{"id":"470638","messageId":"xmqqedrr6cnp.fsf@gitster.g","threadId":"59011","inReplyTo":"230118.86o7qwxg4e.gmgdl@evledraar.gmail.com","subject":"Re: [PATCH v4 08/19] worktree: fix a trivial leak in prune_worktrees()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-01-18T16:16:42Z","receivedAt":"2023-01-18T16:20:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n>> diff --git c/builtin/branch.c w/builtin/branch.c\n>> index f63fd45edb..4fe7757670 100644\n>> --- c/builtin/branch.c\n>> +++ w/builtin/branch.c\n>> @@ -742,6 +742,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n>>  \tif (filter.abbrev == -1)\n>>  \t\tfilter.abbrev = DEFAULT_ABBREV;\n>>  \tfilter.ignore_case = icase;\n>> +\tUNLEAK(filter);\n>>  \n>>  \tfinalize_colopts(&colopts, -1);\n>>  \tif (filter.verbose) {\n>\n> I'll send a v5 re-roll without this change, sorry.\n\nI'd rather see your reroll with the above addition of UNLEAK() than\nwithout it, to fix the breakage.\n"},{"id":"470650","messageId":"Y8gqJESD/wbEHZYb@coredump.intra.peff.net","threadId":"59011","inReplyTo":"7e571cdd-c0fa-7519-848c-b0bc4613abab@web.de","subject":"Re: [PATCH v4 15/19] object-file.c: release the \"tag\" in check_tag()","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2023-01-18T17:19:32Z","receivedAt":"2023-01-18T17:19:54Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Jan 17, 2023 at 08:58:24PM +0100, René Scharfe wrote:\n\n> Am 17.01.23 um 18:11 schrieb Ævar Arnfjörð Bjarmason:\n> > Fix a memory leak that's been with us ever since c879daa2372 (Make\n> > hash-object more robust against malformed objects, 2011-02-05). With\n> > \"HASH_FORMAT_CHECK\" (used by \"hash-object\" and \"replace\") we'll parse\n> > tags into a throwaway variable on the stack, but weren't freeing the\n> > \"item->tag\" we might malloc() when doing so.\n> >\n> > The clearing that release_tag_memory() does for us is redundant here,\n> > but let's use it as-is anyway. It only has one other existing caller,\n> > which does need the tag to be cleared.\n> \n> Calling it is better than getting our hands dirty with tag internals\n> here.\n> \n> There's similar leak in check_commit() in the same file, but plugging it\n> would require exporting unparse_commit().  Or perhaps using the heavy\n> hammer that is release_commit_memory()?  Anyway, it doesn't seem simple\n> to me, so that would be a patch for a separate series.\n\nI think both of these cases are a bit sketchy, because they create an\nobject struct on the stack, and not via alloc_*_node(), which may\nviolate assumptions elsewhere. In the case of the tag, it's probably OK.\nFor the commit, though, the \"index\" field is going to be 0, which may\nconfuse release_commit_memory(). It calls free_commit_buffer(), which is\ngoing to use that index to try to free from the buffer slab.\n\nSo I'd be wary of calling that. I'm also slightly skeptical of the\nexisting code that calls parse_commit_buffer(), but I think it works. We\ndo not attach the buffer to the commit object there (good), and we pass\n\"0\" for check_graph, so the graph code (which IIRC also uses the index\nfor some slab lookups) isn't run.\n\nI think this code would be better off either:\n\n  1. Just allocating an object struct in the usual way. I understand the\n     desire not to spend extra memory, but parse_commit_buffer() is\n     going to allocate structs under the hood for the tree and parent\n     commits anyway.\n\n  2. The point of this code is to find malformed input to hash-object.\n     We're probably better off feeding the buffer to fsck_commit(), etc.\n     It does more thorough checks, and these days it does not need an\n     object struct at all.\n\nEither of which would naturally fix the leak for tags. I'm not sure\nthere actually is a leak for commits, as commit structs don't store any\nstrings themselves.\n\nI don't think any of that needs to hold up Ævar's current series,\nthough. Fixing the leak this way in the meantime is OK, and then if we\nswitch to one of the other techniques, the problem just goes away.\n\n-Peff\n"},{"id":"470652","messageId":"fd883d86-0c85-6c72-a331-2e8b2064befe@web.de","threadId":"59011","inReplyTo":"Y8gqJESD/wbEHZYb@coredump.intra.peff.net","subject":"Re: [PATCH v4 15/19] object-file.c: release the \"tag\" in check_tag()","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2023-01-18T18:05:32Z","receivedAt":"2023-01-18T18:07:48Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 18.01.23 um 18:19 schrieb Jeff King:\n> On Tue, Jan 17, 2023 at 08:58:24PM +0100, René Scharfe wrote:\n>\n>> Am 17.01.23 um 18:11 schrieb Ævar Arnfjörð Bjarmason:\n>>> Fix a memory leak that's been with us ever since c879daa2372 (Make\n>>> hash-object more robust against malformed objects, 2011-02-05). With\n>>> \"HASH_FORMAT_CHECK\" (used by \"hash-object\" and \"replace\") we'll parse\n>>> tags into a throwaway variable on the stack, but weren't freeing the\n>>> \"item->tag\" we might malloc() when doing so.\n>>>\n>>> The clearing that release_tag_memory() does for us is redundant here,\n>>> but let's use it as-is anyway. It only has one other existing caller,\n>>> which does need the tag to be cleared.\n>>\n>> Calling it is better than getting our hands dirty with tag internals\n>> here.\n>>\n>> There's similar leak in check_commit() in the same file, but plugging it\n>> would require exporting unparse_commit().  Or perhaps using the heavy\n>> hammer that is release_commit_memory()?  Anyway, it doesn't seem simple\n>> to me, so that would be a patch for a separate series.\n>\n> I think both of these cases are a bit sketchy, because they create an\n> object struct on the stack, and not via alloc_*_node(), which may\n> violate assumptions elsewhere. In the case of the tag, it's probably OK.\n> For the commit, though, the \"index\" field is going to be 0, which may\n> confuse release_commit_memory(). It calls free_commit_buffer(), which is\n> going to use that index to try to free from the buffer slab.\n>\n> So I'd be wary of calling that. I'm also slightly skeptical of the\n> existing code that calls parse_commit_buffer(), but I think it works. We\n> do not attach the buffer to the commit object there (good), and we pass\n> \"0\" for check_graph, so the graph code (which IIRC also uses the index\n> for some slab lookups) isn't run.\n>\n> I think this code would be better off either:\n>\n>   1. Just allocating an object struct in the usual way. I understand the\n>      desire not to spend extra memory, but parse_commit_buffer() is\n>      going to allocate structs under the hood for the tree and parent\n>      commits anyway.\n>\n>   2. The point of this code is to find malformed input to hash-object.\n>      We're probably better off feeding the buffer to fsck_commit(), etc.\n>      It does more thorough checks, and these days it does not need an\n>      object struct at all.\n\nI like the second one, as long as it won't check too much.  c879daa237\n(Make hash-object more robust against malformed objects, 2011-02-05) added\nthe checks that are now in object-file.c and intended to only validate the\ninternal structure of objects, not relations between.  It gave the example\nto allow adding a commit before its tree, which should be allowed.  And\nIIUC fsck_object() fits that bill.\n\n> Either of which would naturally fix the leak for tags. I'm not sure\n> there actually is a leak for commits, as commit structs don't store any\n> strings themselves.\n\nparse_commit_buffer() allocates the list of parents.\n\nHmm, and it looks them up.  Doesn't this violate the goal to allow\ndangling references?\n\n> I don't think any of that needs to hold up Ævar's current series,\n> though. Fixing the leak this way in the meantime is OK, and then if we\n> switch to one of the other techniques, the problem just goes away.\n\nRight.\n\nRené\n"},{"id":"470654","messageId":"Y8g84mABtIiHmxTI@coredump.intra.peff.net","threadId":"59011","inReplyTo":"fd883d86-0c85-6c72-a331-2e8b2064befe@web.de","subject":"Re: [PATCH v4 15/19] object-file.c: release the \"tag\" in check_tag()","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2023-01-18T18:39:30Z","receivedAt":"2023-01-18T18:39:45Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jan 18, 2023 at 07:05:32PM +0100, René Scharfe wrote:\n\n> >   2. The point of this code is to find malformed input to hash-object.\n> >      We're probably better off feeding the buffer to fsck_commit(), etc.\n> >      It does more thorough checks, and these days it does not need an\n> >      object struct at all.\n> \n> I like the second one, as long as it won't check too much.  c879daa237\n> (Make hash-object more robust against malformed objects, 2011-02-05) added\n> the checks that are now in object-file.c and intended to only validate the\n> internal structure of objects, not relations between.  It gave the example\n> to allow adding a commit before its tree, which should be allowed.  And\n> IIUC fsck_object() fits that bill.\n\nYes, I think it will do what the right thing here. And having just\nwritten up a quick series, the only tests which needed changes were ones\nwith syntactic problems. :)\n\nI'll send it out in a few minutes.\n\n> > Either of which would naturally fix the leak for tags. I'm not sure\n> > there actually is a leak for commits, as commit structs don't store any\n> > strings themselves.\n> \n> parse_commit_buffer() allocates the list of parents.\n\nYes, but it does so with lookup_commit(), so the resulting commit\nobjects are themselves reachable from the usual obj_hash, and thus not\nleaked.\n\n> Hmm, and it looks them up.  Doesn't this violate the goal to allow\n> dangling references?\n\nNo, because lookup_commit() is just about creating an in-process struct.\nIt doesn't look at the object database at all (though it would complain\nif we had seen the same oid in-process as another type).\n\n-Peff\n"},{"id":"470656","messageId":"d30e2fb2-e9dc-20e0-0761-3b585a053586@web.de","threadId":"59011","inReplyTo":"Y8g84mABtIiHmxTI@coredump.intra.peff.net","subject":"Re: [PATCH v4 15/19] object-file.c: release the \"tag\" in check_tag()","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2023-01-18T18:54:41Z","receivedAt":"2023-01-18T18:55:03Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 18.01.23 um 19:39 schrieb Jeff King:\n> On Wed, Jan 18, 2023 at 07:05:32PM +0100, René Scharfe wrote:\n>\n>>>   2. The point of this code is to find malformed input to hash-object.\n>>>      We're probably better off feeding the buffer to fsck_commit(), etc.\n>>>      It does more thorough checks, and these days it does not need an\n>>>      object struct at all.\n>>\n>> I like the second one, as long as it won't check too much.  c879daa237\n>> (Make hash-object more robust against malformed objects, 2011-02-05) added\n>> the checks that are now in object-file.c and intended to only validate the\n>> internal structure of objects, not relations between.  It gave the example\n>> to allow adding a commit before its tree, which should be allowed.  And\n>> IIUC fsck_object() fits that bill.\n>\n> Yes, I think it will do what the right thing here. And having just\n> written up a quick series, the only tests which needed changes were ones\n> with syntactic problems. :)\n>\n> I'll send it out in a few minutes.\n\nGreat! :)\n\n>>> Either of which would naturally fix the leak for tags. I'm not sure\n>>> there actually is a leak for commits, as commit structs don't store any\n>>> strings themselves.\n>>\n>> parse_commit_buffer() allocates the list of parents.\n>\n> Yes, but it does so with lookup_commit(), so the resulting commit\n> objects are themselves reachable from the usual obj_hash, and thus not\n> leaked.\n\nThe commit_list structures are leaked, no?\n\n>\n>> Hmm, and it looks them up.  Doesn't this violate the goal to allow\n>> dangling references?\n>\n> No, because lookup_commit() is just about creating an in-process struct.\n> It doesn't look at the object database at all (though it would complain\n> if we had seen the same oid in-process as another type).\n\nAh, good.\n\nRené\n"},{"id":"470657","messageId":"Y8hFs3V7lSKtOTdo@coredump.intra.peff.net","threadId":"59011","inReplyTo":"d30e2fb2-e9dc-20e0-0761-3b585a053586@web.de","subject":"Re: [PATCH v4 15/19] object-file.c: release the \"tag\" in check_tag()","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2023-01-18T19:17:07Z","receivedAt":"2023-01-18T19:17:13Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jan 18, 2023 at 07:54:41PM +0100, René Scharfe wrote:\n\n> > Yes, but it does so with lookup_commit(), so the resulting commit\n> > objects are themselves reachable from the usual obj_hash, and thus not\n> > leaked.\n> \n> The commit_list structures are leaked, no?\n\nAh, yeah, you're right.\n\n-Peff\n"},{"id":"470679","messageId":"230119.86h6wnwihp.gmgdl@evledraar.gmail.com","threadId":"59011","inReplyTo":"xmqqedrr6cnp.fsf@gitster.g","subject":"Re: [PATCH v4 08/19] worktree: fix a trivial leak in prune_worktrees()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-01-18T23:03:48Z","receivedAt":"2023-01-18T23:06:28Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Jan 18 2023, Junio C Hamano wrote:\n\n> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n>\n>>> diff --git c/builtin/branch.c w/builtin/branch.c\n>>> index f63fd45edb..4fe7757670 100644\n>>> --- c/builtin/branch.c\n>>> +++ w/builtin/branch.c\n>>> @@ -742,6 +742,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n>>>  \tif (filter.abbrev == -1)\n>>>  \t\tfilter.abbrev = DEFAULT_ABBREV;\n>>>  \tfilter.ignore_case = icase;\n>>> +\tUNLEAK(filter);\n>>>  \n>>>  \tfinalize_colopts(&colopts, -1);\n>>>  \tif (filter.verbose) {\n>>\n>> I'll send a v5 re-roll without this change, sorry.\n>\n> I'd rather see your reroll with the above addition of UNLEAK() than\n> without it, to fix the breakage.\n\nI don't mind that UNLEAK() being in-tree until a better fix for that\nleak, but doesn't the v5 I sent also address this?\n\nThe issue was that I mis-marked a test as passing, when it only passed\ndepending on my local compiler (-fsanitize=leak is fickle\nsometimes). Now that we're not marking that test as leak-free there's no\nneed for the UNLEAK() for now, no?\n\nOr is there some edge case I didn't spot/notice?\n\n1. https://lore.kernel.org/git/cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com/\n"},{"id":"470683","messageId":"xmqq7cxj4egt.fsf@gitster.g","threadId":"59011","inReplyTo":"230119.86h6wnwihp.gmgdl@evledraar.gmail.com","subject":"Re: [PATCH v4 08/19] worktree: fix a trivial leak in prune_worktrees()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-01-18T23:20:34Z","receivedAt":"2023-01-18T23:20:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n>> I'd rather see your reroll with the above addition of UNLEAK() than\n>> without it, to fix the breakage.\n>\n> I don't mind that UNLEAK() being in-tree until a better fix for that\n> leak, but doesn't the v5 I sent also address this?\n>\n> The issue was that I mis-marked a test as passing, when it only passed\n> depending on my local compiler (-fsanitize=leak is fickle\n> sometimes). Now that we're not marking that test as leak-free there's no\n> need for the UNLEAK() for now, no?\n>\n> Or is there some edge case I didn't spot/notice?\n\nThe top-level singleton instance of \"filter\" that is used once and\nnever grows unbounded is a perfect use case for UNLEAK().  And with\nit, the test DOES get leak-free, so it would be appropriate to keep\nthe PASSES variable added to the script (until it gets broken\nagain).\n\nOr did you have any other uses of tools with leaks in the script,\nother than the one that is fixed with the UNLEAK()?\n"},{"id":"471041","messageId":"CABPp-BHg00gpwo6emQXPK63Ub=7xRR=3w2jw6uWdpnpJWPZruQ@mail.gmail.com","threadId":"59011","inReplyTo":"patch-v5-07.19-1fac90c306a-20230118T120334Z-avarab@gmail.com","subject":"Re: [PATCH v5 07/19] repack: fix leaks on error with \"goto cleanup\"","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2023-01-26T01:36:00Z","receivedAt":"2023-01-26T01:36:36Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Wed, Jan 18, 2023 at 5:10 AM Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n>\n> Change cmd_repack() to \"goto cleanup\" rather than \"return ret\" on\n> error, when we returned we'd potentially skip cleaning up the\n> string_lists and other data we'd allocated in this function.\n\nThis is hard to parse; the comma followed by \"when\" suggests you are\nonly changing things under a certain set of conditions rather than\nexplaining why you are making an unconditional change.  Perhaps:\n\nIn cmd_repack() when we hit an error, replace \"return ret\" with \"goto\ncleanup\" to ensure we free the necessary data structures.\n\n\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  builtin/repack.c                    | 13 +++++++------\n>  t/t6011-rev-list-with-bad-commit.sh |  1 +\n>  2 files changed, 8 insertions(+), 6 deletions(-)\n>\n> diff --git a/builtin/repack.c b/builtin/repack.c\n> index c1402ad038f..f6493795318 100644\n> --- a/builtin/repack.c\n> +++ b/builtin/repack.c\n> @@ -948,7 +948,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n>\n>         ret = start_command(&cmd);\n>         if (ret)\n> -               return ret;\n> +               goto cleanup;\n>\n>         if (geometry) {\n>                 FILE *in = xfdopen(cmd.in, \"w\");\n> @@ -977,7 +977,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n>         fclose(out);\n>         ret = finish_command(&cmd);\n>         if (ret)\n> -               return ret;\n> +               goto cleanup;\n>\n>         if (!names.nr && !po_args.quiet)\n>                 printf_ln(_(\"Nothing new to pack.\"));\n> @@ -1007,7 +1007,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n>                                        &existing_nonkept_packs,\n>                                        &existing_kept_packs);\n>                 if (ret)\n> -                       return ret;\n> +                       goto cleanup;\n>\n>                 if (delete_redundant && expire_to) {\n>                         /*\n> @@ -1039,7 +1039,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n>                                                &existing_nonkept_packs,\n>                                                &existing_kept_packs);\n>                         if (ret)\n> -                               return ret;\n> +                               goto cleanup;\n>                 }\n>         }\n>\n> @@ -1115,7 +1115,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n>                 string_list_clear(&include, 0);\n>\n>                 if (ret)\n> -                       return ret;\n> +                       goto cleanup;\n>         }\n>\n>         reprepare_packed_git(the_repository);\n> @@ -1172,10 +1172,11 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n>                 write_midx_file(get_object_directory(), NULL, NULL, flags);\n>         }\n>\n> +cleanup:\n>         string_list_clear(&names, 1);\n>         string_list_clear(&existing_nonkept_packs, 0);\n>         string_list_clear(&existing_kept_packs, 0);\n>         clear_pack_geometry(geometry);\n>\n> -       return 0;\n> +       return ret;\n>  }\n> diff --git a/t/t6011-rev-list-with-bad-commit.sh b/t/t6011-rev-list-with-bad-commit.sh\n> index bad02cf5b83..b2e422cf0f7 100755\n> --- a/t/t6011-rev-list-with-bad-commit.sh\n> +++ b/t/t6011-rev-list-with-bad-commit.sh\n> @@ -2,6 +2,7 @@\n>\n>  test_description='git rev-list should notice bad commits'\n>\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  # Note:\n> --\n> 2.39.0.1225.g30a3d88132d\n\nCode changes look fine.\n"},{"id":"471042","messageId":"CABPp-BHyHJLXHU2q9sLsJM54GZzMY5f7dS4SLEfDbWzDKxz_Yg@mail.gmail.com","threadId":"59011","inReplyTo":"patch-v5-02.19-9eb758117dc-20230118T120334Z-avarab@gmail.com","subject":"Re: [PATCH v5 02/19] bundle.c: don't leak the \"args\" in the \"struct child_process\"","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2023-01-26T01:38:00Z","receivedAt":"2023-01-26T01:39:07Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Wed, Jan 18, 2023 at 5:16 AM Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n>\n> Fix a leak that's been here since 7366096de9d (bundle API: change\n> \"flags\" to be \"extra_index_pack_args\", 2021-09-05), if can't verify\n> the bundle we didn't call child_process_clear() to clear the \"args\".\n\nThat's really hard to parse.  Perhaps:\n\nFix a leak that's been here since 7366096de9d (bundle API: change\n\"flags\" to be \"extra_index_pack_args\", 2021-09-05).  If we can't verify\nthe bundle, we didn't call child_process_clear() to clear the \"args\".\n\n> But rather than doing that let's verify the bundle before we start\n> preparing the process we're going to spawn, if we get an error we\n> don't need to push anything to the \"args\".\n\nAlso hard to parse.  Perhaps:\n\nBut rather than adding an additional child_process_clear() call, let's\nverify the bundle before we start\npreparing the process we're going to spawn.  If we fail to verify, we\ndon't need to push anything to the child_process \"args\".\n\n\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  bundle.c | 6 ++++--\n>  1 file changed, 4 insertions(+), 2 deletions(-)\n>\n> diff --git a/bundle.c b/bundle.c\n> index 4ef7256aa11..9ebb10a8f72 100644\n> --- a/bundle.c\n> +++ b/bundle.c\n> @@ -627,6 +627,10 @@ int unbundle(struct repository *r, struct bundle_header *header,\n>              enum verify_bundle_flags flags)\n>  {\n>         struct child_process ip = CHILD_PROCESS_INIT;\n> +\n> +       if (verify_bundle(r, header, flags))\n> +               return -1;\n> +\n>         strvec_pushl(&ip.args, \"index-pack\", \"--fix-thin\", \"--stdin\", NULL);\n>\n>         /* If there is a filter, then we need to create the promisor pack. */\n> @@ -638,8 +642,6 @@ int unbundle(struct repository *r, struct bundle_header *header,\n>                 strvec_clear(extra_index_pack_args);\n>         }\n>\n> -       if (verify_bundle(r, header, flags))\n> -               return -1;\n>         ip.in = bundle_fd;\n>         ip.no_stdout = 1;\n>         ip.git_cmd = 1;\n> --\n> 2.39.0.1225.g30a3d88132d\n"},{"id":"471043","messageId":"CABPp-BHtOirqYbHdmHi8H1nWaRdKx5pN7g-5x_jbgiUnKoh5BQ@mail.gmail.com","threadId":"59011","inReplyTo":"patch-v5-14.19-15e4b8db805-20230118T120334Z-avarab@gmail.com","subject":"Re: [PATCH v5 14/19] builtin/merge.c: free \"&buf\" on \"Your local changes...\" error","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2023-01-26T01:54:00Z","receivedAt":"2023-01-26T01:54:17Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Wed, Jan 18, 2023 at 5:14 AM Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n>\n> Plug a memory leak introduced in [1], since that change didn't follow\n> the \"goto done\" pattern introduced in [2] we'd leak the \"&buf\" memory.\n>\n> 1. e4cdfe84a0d (merge: abort if index does not match HEAD for trivial\n>    merges, 2022-07-23)\n> 2. d5a35c114ab (Copy resolve_ref() return value for longer use,\n>    2011-11-13)\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  builtin/merge.c | 3 ++-\n>  1 file changed, 2 insertions(+), 1 deletion(-)\n>\n> diff --git a/builtin/merge.c b/builtin/merge.c\n> index 91dd5435c59..2b13124c497 100644\n> --- a/builtin/merge.c\n> +++ b/builtin/merge.c\n> @@ -1618,7 +1618,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n>                                 error(_(\"Your local changes to the following files would be overwritten by merge:\\n  %s\"),\n>                                       sb.buf);\n>                                 strbuf_release(&sb);\n> -                               return 2;\n> +                               ret = 2;\n> +                               goto done;\n>                         }\n>\n>                         /* See if it is really trivial. */\n> --\n> 2.39.0.1225.g30a3d88132d\n\nThanks for fixing my bug!\n"},{"id":"471045","messageId":"CABPp-BGucUNYP8TK_aDs4AEPWg2NwaqDXbnqzNX9OZ5aFc4daQ@mail.gmail.com","threadId":"59011","inReplyTo":"patch-v5-16.19-10959760dfc-20230118T120334Z-avarab@gmail.com","subject":"Re: [PATCH v5 16/19] grep.c: refactor free_grep_patterns()","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2023-01-26T02:26:00Z","receivedAt":"2023-01-26T02:26:41Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Wed, Jan 18, 2023 at 5:35 AM Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n>\n> Refactor the free_grep_patterns() function to split out the freeing of\n> the \"struct grep_pat\" it contains, right now we're only freeing the\n> \"pattern_list\", but we should be freeing another member of the same\n> type, which we'll do in the subsequent commit.\n\ns/contains, right/contains. Right/\n\n> Let's also replace the \"return\" if we don't have an\n> \"opt->pattern_expression\" with a conditional call of\n> free_pattern_expr().\n>\n> Before db84376f981 (grep.c: remove \"extended\" in favor of\n> \"pattern_expression\", fix segfault, 2022-10-11) the pattern here was:\n>\n>         if (!x)\n>                 return;\n>         free(y);\n>\n> But after the cleanup in db84376f981 (which was a narrow segfault fix,\n> and thus avoided refactoring this) we ended up with:\n\nFor most of your commits, I like the extended history, but in this\ncase I think it's just a distraction.  I think I'd replace the above\nblock with just five words:\n\n    While at it, instead of:\n\n>         if (!x)\n>                 return;\n>         free(x);\n>\n> Let's instead do:\n>\n>         if (x)\n>                 free(x);\n\nThis is slightly confusing, because \"if(x) free(x)\" can be compressed\nto \"free(x)\".  I think you meant \"free_pattern_expr\" rather than\n\"free\", which cannot (currently) be similarly compressed.\n\n> This doesn't matter for the subsequent change, but as we're\n> refactoring this function let's make it easier to reason about, and to\n> extend in the future, i.e. if we start to free free() members that\n> come after \"pattern_expression\" in the \"struct grep_opt\".\n\nPerhaps just simplify this paragraph to:\n\nThis will make it easier to free additional members from\nfree_grep_patterns() in the future.\n\n\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  grep.c | 14 +++++++++-----\n>  1 file changed, 9 insertions(+), 5 deletions(-)\n>\n> diff --git a/grep.c b/grep.c\n> index 06eed694936..a4450df4559 100644\n> --- a/grep.c\n> +++ b/grep.c\n> @@ -769,11 +769,11 @@ static void free_pattern_expr(struct grep_expr *x)\n>         free(x);\n>  }\n>\n> -void free_grep_patterns(struct grep_opt *opt)\n> +static void free_grep_pat(struct grep_pat *pattern)\n>  {\n>         struct grep_pat *p, *n;\n>\n> -       for (p = opt->pattern_list; p; p = n) {\n> +       for (p = pattern; p; p = n) {\n>                 n = p->next;\n>                 switch (p->token) {\n>                 case GREP_PATTERN: /* atom */\n> @@ -790,10 +790,14 @@ void free_grep_patterns(struct grep_opt *opt)\n>                 }\n>                 free(p);\n>         }\n> +}\n>\n> -       if (!opt->pattern_expression)\n> -               return;\n> -       free_pattern_expr(opt->pattern_expression);\n> +void free_grep_patterns(struct grep_opt *opt)\n> +{\n> +       free_grep_pat(opt->pattern_list);\n> +\n> +       if (opt->pattern_expression)\n> +               free_pattern_expr(opt->pattern_expression);\n>  }\n\nI think this last function would read even better as:\n\n+void free_grep_patterns(struct grep_opt *opt)\n+{\n+       free_grep_pat(opt->pattern_list);\n+       free_pattern_expr(opt->pattern_expression);\n }\n\nafter modifying free_pattern_expr() to return early if passed a NULL argument.\n"},{"id":"471046","messageId":"CABPp-BFtR81jdjnEMKMaFnD71hdmCfgoQMSRuAEk8oMb3_AYFw@mail.gmail.com","threadId":"59011","inReplyTo":"patch-v5-17.19-6a8f4a567aa-20230118T120334Z-avarab@gmail.com","subject":"Re: [PATCH v5 17/19] grep API: plug memory leaks by freeing \"header_list\"","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2023-01-26T02:33:00Z","receivedAt":"2023-01-26T02:34:35Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"I had the same reaction to this patch that Rene did on v1.  The commit\nmessage of the previous patch should probably be reworked so as to not\nmislead.\n\nOn Wed, Jan 18, 2023 at 5:15 AM Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n>\n> When the \"header_list\" struct member was added in [1] it wasn't made\n> to free the list using loop added for the adjacent \"pattern_list\"\n> member, see [2] for when we started freeing it.\n>\n> This makes e.g. this command leak-free when run on git.git:\n>\n>         ./git -P log -1 --color=always --author=A origin/master\n>\n> 1. 80235ba79ef (\"log --author=me --grep=it\" should find intersection,\n>    not union, 2010-01-17)\n> 2. b48fb5b6a95 (grep: free expressions and patterns when done.,\n>    2006-09-27)\n\nThat paragraph is really hard to parse for me.  Maybe change the above\nto something like\n\n\"\"\"\nWhen the \"header_list\" struct member was added in [1], freeing this\nfield was neglected.  Fix that now, so that commands like\n\n    ./git -P log -1 --color=always --author=A origin/master\n\nwill run leak-free.\n\n1. 80235ba79ef (\"log --author=me --grep=it\" should find intersection,\n    not union, 2010-01-17)\n\"\"\"\n\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  grep.c | 1 +\n>  1 file changed, 1 insertion(+)\n>\n> diff --git a/grep.c b/grep.c\n> index a4450df4559..c908535e0d8 100644\n> --- a/grep.c\n> +++ b/grep.c\n> @@ -795,6 +795,7 @@ static void free_grep_pat(struct grep_pat *pattern)\n>  void free_grep_patterns(struct grep_opt *opt)\n>  {\n>         free_grep_pat(opt->pattern_list);\n> +       free_grep_pat(opt->header_list);\n>\n>         if (opt->pattern_expression)\n>                 free_pattern_expr(opt->pattern_expression);\n> --\n> 2.39.0.1225.g30a3d88132d\n\nActual code change looks good.\n"},{"id":"471047","messageId":"CABPp-BFpmEDHXaeXcmXpAuC0xue2b8wrYA560aC7d7tnO25LTw@mail.gmail.com","threadId":"59011","inReplyTo":"patch-v5-18.19-3c3d48df04b-20230118T120334Z-avarab@gmail.com","subject":"Re: [PATCH v5 18/19] receive-pack: free() the \"ref_name\" in \"struct command\"","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2023-01-26T02:37:00Z","receivedAt":"2023-01-26T02:38:42Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Wed, Jan 18, 2023 at 4:54 AM Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n>\n> Fix a memory leak that's been with us since this code was introduced\n> in 575f497456e (Add first cut at \"git-receive-pack\", 2005-06-29), see\n> eb1af2df0b1 (git-receive-pack: start parsing ref update commands,\n> 2005-06-29) for the later change that refactored the code to add the\n> \"ref_name\" member.\n\nThis should be two sentences, not one.  s/), see/). See/ should do it.\n\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  builtin/receive-pack.c                 | 10 ++++++++++\n>  t/t5405-send-pack-rewind.sh            |  1 +\n>  t/t5406-remote-rejects.sh              |  1 +\n>  t/t5507-remote-environment.sh          |  2 ++\n>  t/t5522-pull-symlink.sh                |  1 +\n>  t/t5527-fetch-odd-refs.sh              |  1 +\n>  t/t5560-http-backend-noserver.sh       |  1 +\n>  t/t5561-http-backend.sh                |  1 +\n>  t/t5562-http-backend-content-length.sh |  2 ++\n>  t/t5705-session-id-in-capabilities.sh  |  1 +\n>  10 files changed, 21 insertions(+)\n>\n[...]\n\nCode changes look good.\n"},{"id":"471048","messageId":"CABPp-BFScBjpDtSU4zTDRa2X+V4OZr2bNfXW39paDvtFaiSyww@mail.gmail.com","threadId":"59011","inReplyTo":"patch-v5-19.19-f29500a4abc-20230118T120334Z-avarab@gmail.com","subject":"Re: [PATCH v5 19/19] push: free_refs() the \"local_refs\" in set_refspecs()","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2023-01-26T02:44:00Z","receivedAt":"2023-01-26T02:45:04Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Wed, Jan 18, 2023 at 5:08 AM Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n>\n> Fix a memory leak that's been with us since this code was added in\n> ca02465b413 (push: use remote.$name.push as a refmap, 2013-12-03).\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  builtin/push.c                          | 1 +\n>  t/t1416-ref-transaction-hooks.sh        | 1 +\n>  t/t2402-worktree-list.sh                | 1 +\n>  t/t5504-fetch-receive-strict.sh         | 1 +\n>  t/t5523-push-upstream.sh                | 1 +\n>  t/t5529-push-errors.sh                  | 2 ++\n>  t/t5546-receive-limits.sh               | 2 ++\n>  t/t5547-push-quarantine.sh              | 2 ++\n>  t/t5606-clone-options.sh                | 1 +\n>  t/t5810-proto-disable-local.sh          | 2 ++\n>  t/t5813-proto-disable-ssh.sh            | 2 ++\n>  t/t7409-submodule-detached-work-tree.sh | 1 +\n>  t/t7416-submodule-dash-url.sh           | 2 ++\n>  t/t7450-bad-git-dotfiles.sh             | 2 ++\n>  14 files changed, 21 insertions(+)\n>\n> diff --git a/builtin/push.c b/builtin/push.c\n> index 60ac8017e52..f48e4c6a856 100644\n> --- a/builtin/push.c\n> +++ b/builtin/push.c\n> @@ -129,6 +129,7 @@ static void set_refspecs(const char **refs, int nr, const char *repo)\n>                 } else\n>                         refspec_append(&rs, ref);\n>         }\n> +       free_refs(local_refs);\n\nIn the cover letter, you said you took Rene's feedback as a possible\nfuture improvement, but perhaps it's at least calling out in the code\nwith a TODO comment?\n\n\n>  }\n>\n>  static int push_url_of_remote(struct remote *remote, const char ***url_p)\n> diff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh\n> index 27731722a5b..b32ca798f9f 100755\n> --- a/t/t1416-ref-transaction-hooks.sh\n> +++ b/t/t1416-ref-transaction-hooks.sh\n> @@ -5,6 +5,7 @@ test_description='reference transaction hooks'\n>  GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n>  export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n>\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success setup '\n> diff --git a/t/t2402-worktree-list.sh b/t/t2402-worktree-list.sh\n> index 79e0fce2d90..9ad9be0c208 100755\n> --- a/t/t2402-worktree-list.sh\n> +++ b/t/t2402-worktree-list.sh\n> @@ -5,6 +5,7 @@ test_description='test git worktree list'\n>  GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n>  export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n>\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success 'setup' '\n> diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh\n> index ac4099ca893..14e8af1f3b7 100755\n> --- a/t/t5504-fetch-receive-strict.sh\n> +++ b/t/t5504-fetch-receive-strict.sh\n> @@ -4,6 +4,7 @@ test_description='fetch/receive strict mode'\n>  GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n>  export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n>\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success 'setup and inject \"corrupt or missing\" object' '\n> diff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh\n> index fdb42920564..c9acc076353 100755\n> --- a/t/t5523-push-upstream.sh\n> +++ b/t/t5523-push-upstream.sh\n> @@ -4,6 +4,7 @@ test_description='push with --set-upstream'\n>  GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n>  export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n>\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>  . \"$TEST_DIRECTORY\"/lib-terminal.sh\n>\n> diff --git a/t/t5529-push-errors.sh b/t/t5529-push-errors.sh\n> index ce85fd30ad1..0247137cb36 100755\n> --- a/t/t5529-push-errors.sh\n> +++ b/t/t5529-push-errors.sh\n> @@ -1,6 +1,8 @@\n>  #!/bin/sh\n>\n>  test_description='detect some push errors early (before contacting remote)'\n> +\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success 'setup commits' '\n> diff --git a/t/t5546-receive-limits.sh b/t/t5546-receive-limits.sh\n> index 0b0e987fdb7..eed3c9d81ab 100755\n> --- a/t/t5546-receive-limits.sh\n> +++ b/t/t5546-receive-limits.sh\n> @@ -1,6 +1,8 @@\n>  #!/bin/sh\n>\n>  test_description='check receive input limits'\n> +\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  # Let's run tests with different unpack limits: 1 and 10000\n> diff --git a/t/t5547-push-quarantine.sh b/t/t5547-push-quarantine.sh\n> index 1876fb34e51..9f899b8c7d7 100755\n> --- a/t/t5547-push-quarantine.sh\n> +++ b/t/t5547-push-quarantine.sh\n> @@ -1,6 +1,8 @@\n>  #!/bin/sh\n>\n>  test_description='check quarantine of objects during push'\n> +\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success 'create picky dest repo' '\n> diff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh\n> index cf221e92c4d..27f9f776389 100755\n> --- a/t/t5606-clone-options.sh\n> +++ b/t/t5606-clone-options.sh\n> @@ -4,6 +4,7 @@ test_description='basic clone options'\n>  GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n>  export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n>\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success 'setup' '\n> diff --git a/t/t5810-proto-disable-local.sh b/t/t5810-proto-disable-local.sh\n> index c1ef99b85c2..862610256fb 100755\n> --- a/t/t5810-proto-disable-local.sh\n> +++ b/t/t5810-proto-disable-local.sh\n> @@ -1,6 +1,8 @@\n>  #!/bin/sh\n>\n>  test_description='test disabling of local paths in clone/fetch'\n> +\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>  . \"$TEST_DIRECTORY/lib-proto-disable.sh\"\n>\n> diff --git a/t/t5813-proto-disable-ssh.sh b/t/t5813-proto-disable-ssh.sh\n> index 3f084ee3065..2e975dc70ec 100755\n> --- a/t/t5813-proto-disable-ssh.sh\n> +++ b/t/t5813-proto-disable-ssh.sh\n> @@ -1,6 +1,8 @@\n>  #!/bin/sh\n>\n>  test_description='test disabling of git-over-ssh in clone/fetch'\n> +\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>  . \"$TEST_DIRECTORY/lib-proto-disable.sh\"\n>\n> diff --git a/t/t7409-submodule-detached-work-tree.sh b/t/t7409-submodule-detached-work-tree.sh\n> index 374ed481e9c..574a6fc526e 100755\n> --- a/t/t7409-submodule-detached-work-tree.sh\n> +++ b/t/t7409-submodule-detached-work-tree.sh\n> @@ -13,6 +13,7 @@ TEST_NO_CREATE_REPO=1\n>  GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n>  export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n>\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success 'setup' '\n> diff --git a/t/t7416-submodule-dash-url.sh b/t/t7416-submodule-dash-url.sh\n> index 3ebd9859814..7cf72b9a076 100755\n> --- a/t/t7416-submodule-dash-url.sh\n> +++ b/t/t7416-submodule-dash-url.sh\n> @@ -1,6 +1,8 @@\n>  #!/bin/sh\n>\n>  test_description='check handling of disallowed .gitmodule urls'\n> +\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>\n>  test_expect_success 'setup' '\n> diff --git a/t/t7450-bad-git-dotfiles.sh b/t/t7450-bad-git-dotfiles.sh\n> index ba1f569bcbb..0d0c3f2c683 100755\n> --- a/t/t7450-bad-git-dotfiles.sh\n> +++ b/t/t7450-bad-git-dotfiles.sh\n> @@ -12,6 +12,8 @@ Such as:\n>\n>    - symlinked .gitmodules, etc\n>  '\n> +\n> +TEST_PASSES_SANITIZE_LEAK=true\n>  . ./test-lib.sh\n>  . \"$TEST_DIRECTORY\"/lib-pack.sh\n>\n> --\n> 2.39.0.1225.g30a3d88132d\n>\n"},{"id":"471325","messageId":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com","subject":"[PATCH v6 00/19] leak fixes: various simple leak fixes","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:31Z","receivedAt":"2023-02-02T09:53:09Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"See\nhttps://lore.kernel.org/git/cover-v5-00.19-00000000000-20230118T120334Z-avarab@gmail.com/\nfor the v5. Changes since then:\n\n* Rebased on master, the recent \"fsck\" changes made the check_tag()\n  patch here redundant, and made various existing tests leak-free,\n  which we now mark as such.\n\n* Took major rewrites of commit messages from Elijah, thanks. Added a\n  corresponding Helped-by footer to those. Fixed other typos etc. in\n  commit messages.\n\n* Add a new 18/19 which addreses the TODO issue René & Elijah pointed\n  out in previous rounds.\n\n  I was hoping to keep larger changes like that out of this topic, but\n  if we need to explain with a \"FIXME\" comment or similar what exactly\n  we need to fix here (as was suggested), then we might as well just\n  fix it instead.\n\n* The subsequent free_refs() patch is the same, but we now explain why\n  we're not leaking the \"remote\" (it's free'd by\n  \"the_repository->remote_state\" cleanup).\n\nCI & branch for this at:\nhttps://github.com/avar/git/tree/avar/leak-fixes-more-misc-trivial-6\n\nÆvar Arnfjörð Bjarmason (19):\n  tests: mark tests as passing with SANITIZE=leak\n  bundle.c: don't leak the \"args\" in the \"struct child_process\"\n  commit-graph: use free_commit_graph() instead of UNLEAK()\n  clone: use free() instead of UNLEAK()\n  various: add missing clear_pathspec(), fix leaks\n  name-rev: don't xstrdup() an already dup'd string\n  repack: fix leaks on error with \"goto cleanup\"\n  worktree: fix a trivial leak in prune_worktrees()\n  http-backend.c: fix \"dir\" and \"cmd_arg\" leaks in cmd_main()\n  http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()\n  commit-graph: fix a parse_options_concat() leak\n  show-branch: free() allocated \"head\" before return\n  builtin/merge.c: use fixed strings, not \"strbuf\", fix leak\n  builtin/merge.c: free \"&buf\" on \"Your local changes...\" error\n  grep.c: refactor free_grep_patterns()\n  grep API: plug memory leaks by freeing \"header_list\"\n  receive-pack: free() the \"ref_name\" in \"struct command\"\n  push: refactor refspec_append_mapped() for subsequent leak-fix\n  push: free_refs() the \"local_refs\" in set_refspecs()\n\n archive.c                                  |  1 +\n builtin/clean.c                            |  1 +\n builtin/clone.c                            |  5 ++--\n builtin/commit-graph.c                     | 10 +++++---\n builtin/merge.c                            | 14 +++++-----\n builtin/name-rev.c                         | 23 ++++++++---------\n builtin/push.c                             | 30 +++++++++++++---------\n builtin/receive-pack.c                     | 10 ++++++++\n builtin/repack.c                           | 13 +++++-----\n builtin/reset.c                            | 11 +++++---\n builtin/show-branch.c                      |  1 +\n builtin/stash.c                            |  7 +++--\n builtin/worktree.c                         |  6 ++---\n bundle.c                                   |  6 +++--\n grep.c                                     | 15 +++++++----\n http-backend.c                             |  9 +++++--\n t/t0023-crlf-am.sh                         |  1 +\n t/t1301-shared-repo.sh                     |  1 +\n t/t1302-repo-version.sh                    |  1 +\n t/t1304-default-acl.sh                     |  1 +\n t/t1408-packed-refs.sh                     |  1 +\n t/t1410-reflog.sh                          |  1 +\n t/t1416-ref-transaction-hooks.sh           |  1 +\n t/t1451-fsck-buffer.sh                     |  2 ++\n t/t2401-worktree-prune.sh                  |  1 +\n t/t2402-worktree-list.sh                   |  1 +\n t/t2406-worktree-repair.sh                 |  1 +\n t/t3210-pack-refs.sh                       |  1 +\n t/t3800-mktag.sh                           |  1 +\n t/t4152-am-subjects.sh                     |  2 ++\n t/t4254-am-corrupt.sh                      |  2 ++\n t/t4256-am-format-flowed.sh                |  1 +\n t/t4257-am-interactive.sh                  |  2 ++\n t/t5001-archive-attr.sh                    |  1 +\n t/t5004-archive-corner-cases.sh            |  2 ++\n t/t5302-pack-index.sh                      |  2 ++\n t/t5306-pack-nobase.sh                     |  2 ++\n t/t5312-prune-corruption.sh                |  1 +\n t/t5317-pack-objects-filter-objects.sh     |  1 +\n t/t5330-no-lazy-fetch-with-commit-graph.sh |  1 +\n t/t5403-post-checkout-hook.sh              |  1 +\n t/t5405-send-pack-rewind.sh                |  1 +\n t/t5406-remote-rejects.sh                  |  1 +\n t/t5502-quickfetch.sh                      |  1 +\n t/t5504-fetch-receive-strict.sh            |  1 +\n t/t5507-remote-environment.sh              |  2 ++\n t/t5522-pull-symlink.sh                    |  1 +\n t/t5523-push-upstream.sh                   |  1 +\n t/t5527-fetch-odd-refs.sh                  |  1 +\n t/t5529-push-errors.sh                     |  2 ++\n t/t5546-receive-limits.sh                  |  2 ++\n t/t5547-push-quarantine.sh                 |  2 ++\n t/t5560-http-backend-noserver.sh           |  1 +\n t/t5561-http-backend.sh                    |  1 +\n t/t5562-http-backend-content-length.sh     |  2 ++\n t/t5573-pull-verify-signatures.sh          |  2 ++\n t/t5604-clone-reference.sh                 |  1 +\n t/t5606-clone-options.sh                   |  1 +\n t/t5613-info-alternate.sh                  |  2 ++\n t/t5705-session-id-in-capabilities.sh      |  1 +\n t/t5810-proto-disable-local.sh             |  2 ++\n t/t5813-proto-disable-ssh.sh               |  2 ++\n t/t6011-rev-list-with-bad-commit.sh        |  1 +\n t/t6014-rev-list-all.sh                    |  1 +\n t/t6021-rev-list-exclude-hidden.sh         |  1 +\n t/t6439-merge-co-error-msgs.sh             |  1 +\n t/t6501-freshen-objects.sh                 |  1 +\n t/t7105-reset-patch.sh                     |  2 ++\n t/t7106-reset-unborn-branch.sh             |  2 ++\n t/t7107-reset-pathspec-file.sh             |  1 +\n t/t7301-clean-interactive.sh               |  1 +\n t/t7403-submodule-sync.sh                  |  1 +\n t/t7409-submodule-detached-work-tree.sh    |  1 +\n t/t7416-submodule-dash-url.sh              |  2 ++\n t/t7450-bad-git-dotfiles.sh                |  2 ++\n t/t7612-merge-verify-signatures.sh         |  1 +\n t/t7701-repack-unpack-unreachable.sh       |  1 +\n 77 files changed, 181 insertions(+), 62 deletions(-)\n\nRange-diff against v5:\n 1:  c47fc0fb637 !  1:  36da48d4db9 tests: mark tests as passing with SANITIZE=leak\n    @@ Commit message\n           t7701-repack-unpack-unreachable.sh: In b0c61be3209 (Merge branch\n           'rs/reflog-expiry-cleanup', 2022-12-26)\n     \n    +    - t3800-mktag.sh, t5302-pack-index.sh, t5306-pack-nobase.sh,\n    +      t5573-pull-verify-signatures.sh, t7612-merge-verify-signatures.sh: In\n    +      69bbbe484ba (hash-object: use fsck for object checks, 2023-01-18).\n    +\n    +    - t1451-fsck-buffer.sh: In 8e4309038f0 (fsck: do not assume\n    +      NUL-termination of buffers, 2023-01-19).\n    +\n    +    - t6501-freshen-objects.sh: In abf2bb895b4 (Merge branch\n    +      'jk/hash-object-fsck', 2023-01-30)\n    +\n         1. 9ea1378d046 (Merge branch 'ab/various-leak-fixes', 2022-12-14)\n     \n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n    @@ t/t0023-crlf-am.sh\n      cat >patchfile <<\\EOF\n     \n      ## t/t1301-shared-repo.sh ##\n    -@@ t/t1301-shared-repo.sh: test_description='Test shared repository initialization'\n    - GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n    +@@ t/t1301-shared-repo.sh: GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n      export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n      \n    + TEST_CREATE_REPO_NO_TEMPLATE=1\n     +TEST_PASSES_SANITIZE_LEAK=true\n      . ./test-lib.sh\n      \n    @@ t/t1410-reflog.sh: test_description='Test prune and reflog expiration'\n      \n      check_have () {\n     \n    + ## t/t1451-fsck-buffer.sh ##\n    +@@ t/t1451-fsck-buffer.sh: so.\n    + These tests _might_ catch such overruns in normal use, but should be run with\n    + ASan or valgrind for more confidence.\n    + '\n    ++\n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + \n    + # the general idea for tags and commits is to build up the \"base\" file\n    +\n      ## t/t3210-pack-refs.sh ##\n     @@ t/t3210-pack-refs.sh: semantic is still the same.\n      GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n    @@ t/t3210-pack-refs.sh: semantic is still the same.\n      \n      test_expect_success 'enable reflogs' '\n     \n    + ## t/t3800-mktag.sh ##\n    +@@\n    + \n    + test_description='git mktag: tag object verify test'\n    + \n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + \n    + ###########################################################\n    +\n      ## t/t4152-am-subjects.sh ##\n     @@\n      #!/bin/sh\n    @@ t/t4257-am-interactive.sh\n      \n      test_expect_success 'set up patches to apply' '\n     \n    + ## t/t5302-pack-index.sh ##\n    +@@\n    + #\n    + \n    + test_description='pack index with 64-bit offsets and object CRC'\n    ++\n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + \n    + test_expect_success 'setup' '\n    +\n    + ## t/t5306-pack-nobase.sh ##\n    +@@\n    + test_description='git-pack-object with missing base\n    + \n    + '\n    ++\n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + \n    + # Create A-B chain\n    +\n      ## t/t5317-pack-objects-filter-objects.sh ##\n     @@ t/t5317-pack-objects-filter-objects.sh: test_description='git pack-objects using object filtering'\n      GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n    @@ t/t5502-quickfetch.sh: test_description='test quickfetch from local'\n      \n      test_expect_success setup '\n     \n    + ## t/t5573-pull-verify-signatures.sh ##\n    +@@\n    + #!/bin/sh\n    + \n    + test_description='pull signature verification tests'\n    ++\n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + . \"$TEST_DIRECTORY/lib-gpg.sh\"\n    + \n    +\n      ## t/t5604-clone-reference.sh ##\n     @@ t/t5604-clone-reference.sh: test_description='test clone --reference'\n      GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n    @@ t/t6021-rev-list-exclude-hidden.sh\n      \n      test_expect_success 'setup' '\n     \n    + ## t/t6501-freshen-objects.sh ##\n    +@@ t/t6501-freshen-objects.sh: test_description='check pruning of dependent objects'\n    + GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n    + export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n    + \n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + \n    + # We care about reachability, so we do not want to use\n    +\n      ## t/t7403-submodule-sync.sh ##\n     @@ t/t7403-submodule-sync.sh: These tests exercise the \"git submodule sync\" subcommand.\n      GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n    @@ t/t7403-submodule-sync.sh: These tests exercise the \"git submodule sync\" subcomm\n      \n      test_expect_success setup '\n     \n    + ## t/t7612-merge-verify-signatures.sh ##\n    +@@ t/t7612-merge-verify-signatures.sh: test_description='merge signature verification tests'\n    + GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n    + export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n    + \n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + . \"$TEST_DIRECTORY/lib-gpg.sh\"\n    + \n    +\n      ## t/t7701-repack-unpack-unreachable.sh ##\n     @@ t/t7701-repack-unpack-unreachable.sh: test_description='git repack works correctly'\n      GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n 2:  9eb758117dc !  2:  f0f1a388350 bundle.c: don't leak the \"args\" in the \"struct child_process\"\n    @@ Commit message\n         bundle.c: don't leak the \"args\" in the \"struct child_process\"\n     \n         Fix a leak that's been here since 7366096de9d (bundle API: change\n    -    \"flags\" to be \"extra_index_pack_args\", 2021-09-05), if can't verify\n    -    the bundle we didn't call child_process_clear() to clear the \"args\".\n    +    \"flags\" to be \"extra_index_pack_args\", 2021-09-05). If we can't verify\n    +    the bundle, we didn't call child_process_clear() to clear the \"args\".\n     \n    -    But rather than doing that let's verify the bundle before we start\n    -    preparing the process we're going to spawn, if we get an error we\n    -    don't need to push anything to the \"args\".\n    +    But rather than adding an additional child_process_clear() call, let's\n    +    verify the bundle before we start preparing the process we're going to\n    +    spawn. If we fail to verify, we don't need to push anything to the\n    +    child_process \"args\".\n     \n    +    Helped-by: Elijah Newren <newren@gmail.com>\n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## bundle.c ##\n 3:  01b6229f18a =  3:  cf0dddf4e8c commit-graph: use free_commit_graph() instead of UNLEAK()\n 4:  f4f3aef2861 =  4:  0430c1fec1b clone: use free() instead of UNLEAK()\n 5:  8d10fbe0b8f =  5:  fb2d9875c73 various: add missing clear_pathspec(), fix leaks\n 6:  eb5dc3ac192 =  6:  bca659788de name-rev: don't xstrdup() an already dup'd string\n 7:  1fac90c306a !  7:  09950d92940 repack: fix leaks on error with \"goto cleanup\"\n    @@ Metadata\n      ## Commit message ##\n         repack: fix leaks on error with \"goto cleanup\"\n     \n    -    Change cmd_repack() to \"goto cleanup\" rather than \"return ret\" on\n    -    error, when we returned we'd potentially skip cleaning up the\n    -    string_lists and other data we'd allocated in this function.\n    +    In cmd_repack() when we hit an error, replace \"return ret\" with \"goto\n    +    cleanup\" to ensure we free the necessary data structures.\n     \n    +    Helped-by: Elijah Newren <newren@gmail.com>\n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## builtin/repack.c ##\n    @@ builtin/repack.c: int cmd_repack(int argc, const char **argv, const char *prefix\n     +\treturn ret;\n      }\n     \n    + ## t/t5312-prune-corruption.sh ##\n    +@@ t/t5312-prune-corruption.sh: what currently happens. If that changes, these tests should be revisited.\n    + GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n    + export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n    + \n    ++TEST_PASSES_SANITIZE_LEAK=true\n    + . ./test-lib.sh\n    + \n    + test_expect_success 'disable reflogs' '\n    +\n      ## t/t6011-rev-list-with-bad-commit.sh ##\n     @@\n      \n 8:  02248aca3eb =  8:  cd3eb9e68ff worktree: fix a trivial leak in prune_worktrees()\n 9:  b39d6d29dd5 =  9:  e80a719913b http-backend.c: fix \"dir\" and \"cmd_arg\" leaks in cmd_main()\n10:  928dea2d4ee = 10:  9d9df0caf17 http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()\n11:  5770b9eb764 = 11:  65e25377791 commit-graph: fix a parse_options_concat() leak\n12:  3ff86cb808c = 12:  3b1d47b9d62 show-branch: free() allocated \"head\" before return\n13:  1f3e3524580 = 13:  a85e5f3b14e builtin/merge.c: use fixed strings, not \"strbuf\", fix leak\n14:  15e4b8db805 = 14:  7dbc422d5b4 builtin/merge.c: free \"&buf\" on \"Your local changes...\" error\n15:  d36ad1f818a <  -:  ----------- object-file.c: release the \"tag\" in check_tag()\n16:  10959760dfc ! 15:  aa51668b70d grep.c: refactor free_grep_patterns()\n    @@ Commit message\n         grep.c: refactor free_grep_patterns()\n     \n         Refactor the free_grep_patterns() function to split out the freeing of\n    -    the \"struct grep_pat\" it contains, right now we're only freeing the\n    +    the \"struct grep_pat\" it contains. Right now we're only freeing the\n         \"pattern_list\", but we should be freeing another member of the same\n         type, which we'll do in the subsequent commit.\n     \n    @@ Commit message\n     \n                 if (!x)\n                         return;\n    -            free(y);\n    +            free_pattern_expr(y);\n     \n    -    But after the cleanup in db84376f981 (which was a narrow segfault fix,\n    -    and thus avoided refactoring this) we ended up with:\n    +    While at it, instead of:\n     \n                 if (!x)\n                         return;\n    -            free(x);\n    +            free_pattern_expr(x);\n     \n         Let's instead do:\n     \n                 if (x)\n    -                    free(x);\n    +                    free_pattern_expr(x);\n     \n    -    This doesn't matter for the subsequent change, but as we're\n    -    refactoring this function let's make it easier to reason about, and to\n    -    extend in the future, i.e. if we start to free free() members that\n    -    come after \"pattern_expression\" in the \"struct grep_opt\".\n    +    This will make it easier to free additional members from\n    +    free_grep_patterns() in the future.\n     \n    +    Helped-by: Elijah Newren <newren@gmail.com>\n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## grep.c ##\n17:  6a8f4a567aa ! 16:  0c51ea7fd2d grep API: plug memory leaks by freeing \"header_list\"\n    @@ Metadata\n      ## Commit message ##\n         grep API: plug memory leaks by freeing \"header_list\"\n     \n    -    When the \"header_list\" struct member was added in [1] it wasn't made\n    -    to free the list using loop added for the adjacent \"pattern_list\"\n    -    member, see [2] for when we started freeing it.\n    -\n    -    This makes e.g. this command leak-free when run on git.git:\n    +    When the \"header_list\" struct member was added in [1], freeing this\n    +    field was neglected. Fix that now, so that commands like\n     \n                 ./git -P log -1 --color=always --author=A origin/master\n     \n    +    will run leak-free.\n    +\n         1. 80235ba79ef (\"log --author=me --grep=it\" should find intersection,\n            not union, 2010-01-17)\n    -    2. b48fb5b6a95 (grep: free expressions and patterns when done.,\n    -       2006-09-27)\n     \n    +    Helped-by: Elijah Newren <newren@gmail.com>\n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## grep.c ##\n18:  3c3d48df04b ! 17:  4b2db91f5cb receive-pack: free() the \"ref_name\" in \"struct command\"\n    @@ Commit message\n         receive-pack: free() the \"ref_name\" in \"struct command\"\n     \n         Fix a memory leak that's been with us since this code was introduced\n    -    in 575f497456e (Add first cut at \"git-receive-pack\", 2005-06-29), see\n    +    in 575f497456e (Add first cut at \"git-receive-pack\", 2005-06-29). See\n         eb1af2df0b1 (git-receive-pack: start parsing ref update commands,\n         2005-06-29) for the later change that refactored the code to add the\n         \"ref_name\" member.\n -:  ----------- > 18:  aa33f7e05c8 push: refactor refspec_append_mapped() for subsequent leak-fix\n19:  f29500a4abc ! 19:  67076dfba6d push: free_refs() the \"local_refs\" in set_refspecs()\n    @@ Commit message\n         Fix a memory leak that's been with us since this code was added in\n         ca02465b413 (push: use remote.$name.push as a refmap, 2013-12-03).\n     \n    +    The \"remote = remote_get(...)\" added in the same commit would seem to\n    +    leak based only on the context here, but that function is a wrapper\n    +    for sticking the remotes we fetch into \"the_repository->remote_state\".\n    +\n    +    See fd3cb0501e1 (remote: move static variables into per-repository\n    +    struct, 2021-11-17) for the addition of code in repository.c that\n    +    free's the \"remote\" allocated here.\n    +\n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## builtin/push.c ##\n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471326","messageId":"patch-v6-01.19-36da48d4db9-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v6 01/19] tests: mark tests as passing with SANITIZE=leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:32Z","receivedAt":"2023-02-02T09:53:11Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the \"ab/various-leak-fixes\" topic was merged in [1] only t6021\nwould fail if the tests were run in the\n\"GIT_TEST_PASSING_SANITIZE_LEAK=check\" mode, i.e. to check whether we\nmarked all leak-free tests with \"TEST_PASSES_SANITIZE_LEAK=true\".\n\nSince then we've had various tests starting to pass under\nSANITIZE=leak. Let's mark those as passing, this is when they started\nto pass, narrowed down with \"git bisect\":\n\n- t5317-pack-objects-filter-objects.sh: In\n  faebba436e6 (list-objects-filter: plug pattern_list leak, 2022-12-01).\n\n- t3210-pack-refs.sh, t5613-info-alternate.sh,\n  t7403-submodule-sync.sh: In 189e97bc4ba (diff: remove parseopts member\n  from struct diff_options, 2022-12-01).\n\n- t1408-packed-refs.sh: In ab91f6b7c42 (Merge branch\n  'rs/diff-parseopts', 2022-12-19).\n\n- t0023-crlf-am.sh, t4152-am-subjects.sh, t4254-am-corrupt.sh,\n  t4256-am-format-flowed.sh, t4257-am-interactive.sh,\n  t5403-post-checkout-hook.sh: In a658e881c13 (am: don't pass strvec to\n  apply_parse_options(), 2022-12-13)\n\n- t1301-shared-repo.sh, t1302-repo-version.sh: In b07a819c05f (reflog:\n  clear leftovers in reflog_expiry_cleanup(), 2022-12-13).\n\n- t1304-default-acl.sh, t1410-reflog.sh,\n  t5330-no-lazy-fetch-with-commit-graph.sh, t5502-quickfetch.sh,\n  t5604-clone-reference.sh, t6014-rev-list-all.sh,\n  t7701-repack-unpack-unreachable.sh: In b0c61be3209 (Merge branch\n  'rs/reflog-expiry-cleanup', 2022-12-26)\n\n- t3800-mktag.sh, t5302-pack-index.sh, t5306-pack-nobase.sh,\n  t5573-pull-verify-signatures.sh, t7612-merge-verify-signatures.sh: In\n  69bbbe484ba (hash-object: use fsck for object checks, 2023-01-18).\n\n- t1451-fsck-buffer.sh: In 8e4309038f0 (fsck: do not assume\n  NUL-termination of buffers, 2023-01-19).\n\n- t6501-freshen-objects.sh: In abf2bb895b4 (Merge branch\n  'jk/hash-object-fsck', 2023-01-30)\n\n1. 9ea1378d046 (Merge branch 'ab/various-leak-fixes', 2022-12-14)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n t/t0023-crlf-am.sh                         | 1 +\n t/t1301-shared-repo.sh                     | 1 +\n t/t1302-repo-version.sh                    | 1 +\n t/t1304-default-acl.sh                     | 1 +\n t/t1408-packed-refs.sh                     | 1 +\n t/t1410-reflog.sh                          | 1 +\n t/t1451-fsck-buffer.sh                     | 2 ++\n t/t3210-pack-refs.sh                       | 1 +\n t/t3800-mktag.sh                           | 1 +\n t/t4152-am-subjects.sh                     | 2 ++\n t/t4254-am-corrupt.sh                      | 2 ++\n t/t4256-am-format-flowed.sh                | 1 +\n t/t4257-am-interactive.sh                  | 2 ++\n t/t5302-pack-index.sh                      | 2 ++\n t/t5306-pack-nobase.sh                     | 2 ++\n t/t5317-pack-objects-filter-objects.sh     | 1 +\n t/t5330-no-lazy-fetch-with-commit-graph.sh | 1 +\n t/t5403-post-checkout-hook.sh              | 1 +\n t/t5502-quickfetch.sh                      | 1 +\n t/t5573-pull-verify-signatures.sh          | 2 ++\n t/t5604-clone-reference.sh                 | 1 +\n t/t5613-info-alternate.sh                  | 2 ++\n t/t6014-rev-list-all.sh                    | 1 +\n t/t6021-rev-list-exclude-hidden.sh         | 1 +\n t/t6501-freshen-objects.sh                 | 1 +\n t/t7403-submodule-sync.sh                  | 1 +\n t/t7612-merge-verify-signatures.sh         | 1 +\n t/t7701-repack-unpack-unreachable.sh       | 1 +\n 28 files changed, 36 insertions(+)\n\ndiff --git a/t/t0023-crlf-am.sh b/t/t0023-crlf-am.sh\nindex f9bbb91f64e..575805513a3 100755\n--- a/t/t0023-crlf-am.sh\n+++ b/t/t0023-crlf-am.sh\n@@ -2,6 +2,7 @@\n \n test_description='Test am with auto.crlf'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n cat >patchfile <<\\EOF\ndiff --git a/t/t1301-shared-repo.sh b/t/t1301-shared-repo.sh\nindex 58d6da7feb1..1b6437ec079 100755\n--- a/t/t1301-shared-repo.sh\n+++ b/t/t1301-shared-repo.sh\n@@ -9,6 +9,7 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n TEST_CREATE_REPO_NO_TEMPLATE=1\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Remove a default ACL from the test dir if possible.\ndiff --git a/t/t1302-repo-version.sh b/t/t1302-repo-version.sh\nindex 7cf80bf66a6..70389fa2ebb 100755\n--- a/t/t1302-repo-version.sh\n+++ b/t/t1302-repo-version.sh\n@@ -5,6 +5,7 @@\n \n test_description='Test repository version check'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh\nindex c69ae41306c..31b89dd9693 100755\n--- a/t/t1304-default-acl.sh\n+++ b/t/t1304-default-acl.sh\n@@ -9,6 +9,7 @@ test_description='Test repository with default ACL'\n # => this must come before . ./test-lib.sh\n umask 077\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # We need an arbitrary other user give permission to using ACLs. root\ndiff --git a/t/t1408-packed-refs.sh b/t/t1408-packed-refs.sh\nindex 41ba1f1d7fc..9469c79a585 100755\n--- a/t/t1408-packed-refs.sh\n+++ b/t/t1408-packed-refs.sh\n@@ -5,6 +5,7 @@ test_description='packed-refs entries are covered by loose refs'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh\nindex aa59954f6c5..6c45965b1e4 100755\n--- a/t/t1410-reflog.sh\n+++ b/t/t1410-reflog.sh\n@@ -7,6 +7,7 @@ test_description='Test prune and reflog expiration'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n check_have () {\ndiff --git a/t/t1451-fsck-buffer.sh b/t/t1451-fsck-buffer.sh\nindex 9ac270abab6..3413da40e4a 100755\n--- a/t/t1451-fsck-buffer.sh\n+++ b/t/t1451-fsck-buffer.sh\n@@ -14,6 +14,8 @@ so.\n These tests _might_ catch such overruns in normal use, but should be run with\n ASan or valgrind for more confidence.\n '\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # the general idea for tags and commits is to build up the \"base\" file\ndiff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh\nindex 577f32dc71f..07a0ff93def 100755\n--- a/t/t3210-pack-refs.sh\n+++ b/t/t3210-pack-refs.sh\n@@ -12,6 +12,7 @@ semantic is still the same.\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'enable reflogs' '\ndiff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh\nindex e3cf0ffbe59..d3e428ff46e 100755\n--- a/t/t3800-mktag.sh\n+++ b/t/t3800-mktag.sh\n@@ -4,6 +4,7 @@\n \n test_description='git mktag: tag object verify test'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n ###########################################################\ndiff --git a/t/t4152-am-subjects.sh b/t/t4152-am-subjects.sh\nindex 4c68245acad..9f2edba1f83 100755\n--- a/t/t4152-am-subjects.sh\n+++ b/t/t4152-am-subjects.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test subject preservation with format-patch | am'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n make_patches() {\ndiff --git a/t/t4254-am-corrupt.sh b/t/t4254-am-corrupt.sh\nindex 54be7da1611..45f1d4f95e5 100755\n--- a/t/t4254-am-corrupt.sh\n+++ b/t/t4254-am-corrupt.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git am with corrupt input'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n make_mbox_with_nul () {\ndiff --git a/t/t4256-am-format-flowed.sh b/t/t4256-am-format-flowed.sh\nindex 2369c4e17ad..1015273bc82 100755\n--- a/t/t4256-am-format-flowed.sh\n+++ b/t/t4256-am-format-flowed.sh\n@@ -2,6 +2,7 @@\n \n test_description='test format=flowed support of git am'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t4257-am-interactive.sh b/t/t4257-am-interactive.sh\nindex aed8f4de3d6..f26d7fd2dbd 100755\n--- a/t/t4257-am-interactive.sh\n+++ b/t/t4257-am-interactive.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='am --interactive tests'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'set up patches to apply' '\ndiff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh\nindex 59e9e77223b..f89809be53c 100755\n--- a/t/t5302-pack-index.sh\n+++ b/t/t5302-pack-index.sh\n@@ -4,6 +4,8 @@\n #\n \n test_description='pack index with 64-bit offsets and object CRC'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t5306-pack-nobase.sh b/t/t5306-pack-nobase.sh\nindex 51973f4a512..846c5ca7d34 100755\n--- a/t/t5306-pack-nobase.sh\n+++ b/t/t5306-pack-nobase.sh\n@@ -6,6 +6,8 @@\n test_description='git-pack-object with missing base\n \n '\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Create A-B chain\ndiff --git a/t/t5317-pack-objects-filter-objects.sh b/t/t5317-pack-objects-filter-objects.sh\nindex 5b707d911b5..b26d476c646 100755\n--- a/t/t5317-pack-objects-filter-objects.sh\n+++ b/t/t5317-pack-objects-filter-objects.sh\n@@ -5,6 +5,7 @@ test_description='git pack-objects using object filtering'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Test blob:none filter.\ndiff --git a/t/t5330-no-lazy-fetch-with-commit-graph.sh b/t/t5330-no-lazy-fetch-with-commit-graph.sh\nindex 2cc7fd7a476..5eb28f0512d 100755\n--- a/t/t5330-no-lazy-fetch-with-commit-graph.sh\n+++ b/t/t5330-no-lazy-fetch-with-commit-graph.sh\n@@ -2,6 +2,7 @@\n \n test_description='test for no lazy fetch with the commit-graph'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup: prepare a repository with a commit' '\ndiff --git a/t/t5403-post-checkout-hook.sh b/t/t5403-post-checkout-hook.sh\nindex 978f240cdac..cfaae547398 100755\n--- a/t/t5403-post-checkout-hook.sh\n+++ b/t/t5403-post-checkout-hook.sh\n@@ -7,6 +7,7 @@ test_description='Test the post-checkout hook.'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5502-quickfetch.sh b/t/t5502-quickfetch.sh\nindex b160f8b7fb7..7b3ff21b984 100755\n--- a/t/t5502-quickfetch.sh\n+++ b/t/t5502-quickfetch.sh\n@@ -5,6 +5,7 @@ test_description='test quickfetch from local'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5573-pull-verify-signatures.sh b/t/t5573-pull-verify-signatures.sh\nindex a53dd8550d0..1221ac05978 100755\n--- a/t/t5573-pull-verify-signatures.sh\n+++ b/t/t5573-pull-verify-signatures.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='pull signature verification tests'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY/lib-gpg.sh\"\n \ndiff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh\nindex 2734e37e880..dc86dea1333 100755\n--- a/t/t5604-clone-reference.sh\n+++ b/t/t5604-clone-reference.sh\n@@ -7,6 +7,7 @@ test_description='test clone --reference'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n base_dir=$(pwd)\ndiff --git a/t/t5613-info-alternate.sh b/t/t5613-info-alternate.sh\nindex 895f46bb911..7708cbafa98 100755\n--- a/t/t5613-info-alternate.sh\n+++ b/t/t5613-info-alternate.sh\n@@ -4,6 +4,8 @@\n #\n \n test_description='test transitive info/alternate entries'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'preparing first repository' '\ndiff --git a/t/t6014-rev-list-all.sh b/t/t6014-rev-list-all.sh\nindex c9bedd29cba..16b8bd1d090 100755\n--- a/t/t6014-rev-list-all.sh\n+++ b/t/t6014-rev-list-all.sh\n@@ -2,6 +2,7 @@\n \n test_description='--all includes detached HEADs'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n \ndiff --git a/t/t6021-rev-list-exclude-hidden.sh b/t/t6021-rev-list-exclude-hidden.sh\nindex 32b2b094138..11c50b7c0dd 100755\n--- a/t/t6021-rev-list-exclude-hidden.sh\n+++ b/t/t6021-rev-list-exclude-hidden.sh\n@@ -2,6 +2,7 @@\n \n test_description='git rev-list --exclude-hidden test'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t6501-freshen-objects.sh b/t/t6501-freshen-objects.sh\nindex 10662456aee..3968b47ed53 100755\n--- a/t/t6501-freshen-objects.sh\n+++ b/t/t6501-freshen-objects.sh\n@@ -28,6 +28,7 @@ test_description='check pruning of dependent objects'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # We care about reachability, so we do not want to use\ndiff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh\nindex ea92ef52a5e..ff09443a0a4 100755\n--- a/t/t7403-submodule-sync.sh\n+++ b/t/t7403-submodule-sync.sh\n@@ -11,6 +11,7 @@ These tests exercise the \"git submodule sync\" subcommand.\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t7612-merge-verify-signatures.sh b/t/t7612-merge-verify-signatures.sh\nindex 61330f71b17..f5c90cc22a1 100755\n--- a/t/t7612-merge-verify-signatures.sh\n+++ b/t/t7612-merge-verify-signatures.sh\n@@ -4,6 +4,7 @@ test_description='merge signature verification tests'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY/lib-gpg.sh\"\n \ndiff --git a/t/t7701-repack-unpack-unreachable.sh b/t/t7701-repack-unpack-unreachable.sh\nindex b7ac4f598a8..ebb267855fe 100755\n--- a/t/t7701-repack-unpack-unreachable.sh\n+++ b/t/t7701-repack-unpack-unreachable.sh\n@@ -5,6 +5,7 @@ test_description='git repack works correctly'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n fsha1=\n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471327","messageId":"patch-v6-03.19-cf0dddf4e8c-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v6 03/19] commit-graph: use free_commit_graph() instead of UNLEAK()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:34Z","receivedAt":"2023-02-02T09:53:15Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"In 0bfb48e6723 (builtin/commit-graph.c: UNLEAK variables, 2018-10-03)\nthis was made to UNLEAK(), but we can just as easily invoke the\nfree_commit_graph() function added in c3756d5b7fc (commit-graph: add\nfree_commit_graph, 2018-07-11) instead.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/commit-graph.c | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/commit-graph.c b/builtin/commit-graph.c\nindex e8f77f535f3..0102ac8540e 100644\n--- a/builtin/commit-graph.c\n+++ b/builtin/commit-graph.c\n@@ -67,6 +67,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix)\n \tint fd;\n \tstruct stat st;\n \tint flags = 0;\n+\tint ret;\n \n \tstatic struct option builtin_commit_graph_verify_options[] = {\n \t\tOPT_BOOL(0, \"shallow\", &opts.shallow,\n@@ -111,8 +112,9 @@ static int graph_verify(int argc, const char **argv, const char *prefix)\n \tif (!graph)\n \t\treturn !!open_ok;\n \n-\tUNLEAK(graph);\n-\treturn verify_commit_graph(the_repository, graph, flags);\n+\tret = verify_commit_graph(the_repository, graph, flags);\n+\tfree_commit_graph(graph);\n+\treturn ret;\n }\n \n extern int read_replace_refs;\n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471328","messageId":"patch-v6-02.19-f0f1a388350-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v6 02/19] bundle.c: don't leak the \"args\" in the \"struct child_process\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:33Z","receivedAt":"2023-02-02T09:53:16Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a leak that's been here since 7366096de9d (bundle API: change\n\"flags\" to be \"extra_index_pack_args\", 2021-09-05). If we can't verify\nthe bundle, we didn't call child_process_clear() to clear the \"args\".\n\nBut rather than adding an additional child_process_clear() call, let's\nverify the bundle before we start preparing the process we're going to\nspawn. If we fail to verify, we don't need to push anything to the\nchild_process \"args\".\n\nHelped-by: Elijah Newren <newren@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n bundle.c | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/bundle.c b/bundle.c\nindex 4ef7256aa11..9ebb10a8f72 100644\n--- a/bundle.c\n+++ b/bundle.c\n@@ -627,6 +627,10 @@ int unbundle(struct repository *r, struct bundle_header *header,\n \t     enum verify_bundle_flags flags)\n {\n \tstruct child_process ip = CHILD_PROCESS_INIT;\n+\n+\tif (verify_bundle(r, header, flags))\n+\t\treturn -1;\n+\n \tstrvec_pushl(&ip.args, \"index-pack\", \"--fix-thin\", \"--stdin\", NULL);\n \n \t/* If there is a filter, then we need to create the promisor pack. */\n@@ -638,8 +642,6 @@ int unbundle(struct repository *r, struct bundle_header *header,\n \t\tstrvec_clear(extra_index_pack_args);\n \t}\n \n-\tif (verify_bundle(r, header, flags))\n-\t\treturn -1;\n \tip.in = bundle_fd;\n \tip.no_stdout = 1;\n \tip.git_cmd = 1;\n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471329","messageId":"patch-v6-04.19-0430c1fec1b-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v6 04/19] clone: use free() instead of UNLEAK()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:35Z","receivedAt":"2023-02-02T09:53:18Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change an UNLEAK() added in 0c4542738e6 (clone: free or UNLEAK further\npointers when finished, 2021-03-14) to use a \"to_free\" pattern\ninstead. In this case the \"repo\" can be either this absolute_pathdup()\nvalue, or in the \"else if\" branch seen in the context the the\n\"argv[0]\" argument to \"main()\".\n\nWe can only free() the value in the former case, hence the \"to_free\"\npattern.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/clone.c | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 5453ba5277f..ba82f5e4108 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -892,6 +892,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tint is_bundle = 0, is_local;\n \tint reject_shallow = 0;\n \tconst char *repo_name, *repo, *work_tree, *git_dir;\n+\tchar *repo_to_free = NULL;\n \tchar *path = NULL, *dir, *display_repo = NULL;\n \tint dest_exists, real_dest_exists = 0;\n \tconst struct ref *refs, *remote_head;\n@@ -949,7 +950,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tpath = get_repo_path(repo_name, &is_bundle);\n \tif (path) {\n \t\tFREE_AND_NULL(path);\n-\t\trepo = absolute_pathdup(repo_name);\n+\t\trepo = repo_to_free = absolute_pathdup(repo_name);\n \t} else if (strchr(repo_name, ':')) {\n \t\trepo = repo_name;\n \t\tdisplay_repo = transport_anonymize_url(repo);\n@@ -1413,7 +1414,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tfree(unborn_head);\n \tfree(dir);\n \tfree(path);\n-\tUNLEAK(repo);\n+\tfree(repo_to_free);\n \tjunk_mode = JUNK_LEAVE_ALL;\n \n \ttransport_ls_refs_options_release(&transport_ls_refs_options);\n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471330","messageId":"patch-v6-08.19-cd3eb9e68ff-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v6 08/19] worktree: fix a trivial leak in prune_worktrees()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:39Z","receivedAt":"2023-02-02T09:53:32Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"We were leaking both the \"struct strbuf\" in prune_worktrees(), as well\nas the \"path\" we got from should_prune_worktree(). Since these were\nthe only two uses of the \"struct string_list\" let's change it to a\n\"DUP\" and push these to it with \"string_list_append_nodup()\".\n\nFor the string_list_append_nodup() we could also string_list_append()\nthe main_path.buf, and then strbuf_release(&main_path) right away. But\ndoing it this way avoids an allocation, as we already have the \"struct\nstrbuf\" prepared for appending to \"kept\".\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/worktree.c         | 6 +++---\n t/t2401-worktree-prune.sh  | 1 +\n t/t2406-worktree-repair.sh | 1 +\n 3 files changed, 5 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex f51c40f1e1e..254283aa6f5 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -173,7 +173,7 @@ static void prune_worktrees(void)\n {\n \tstruct strbuf reason = STRBUF_INIT;\n \tstruct strbuf main_path = STRBUF_INIT;\n-\tstruct string_list kept = STRING_LIST_INIT_NODUP;\n+\tstruct string_list kept = STRING_LIST_INIT_DUP;\n \tDIR *dir = opendir(git_path(\"worktrees\"));\n \tstruct dirent *d;\n \tif (!dir)\n@@ -184,14 +184,14 @@ static void prune_worktrees(void)\n \t\tif (should_prune_worktree(d->d_name, &reason, &path, expire))\n \t\t\tprune_worktree(d->d_name, reason.buf);\n \t\telse if (path)\n-\t\t\tstring_list_append(&kept, path)->util = xstrdup(d->d_name);\n+\t\t\tstring_list_append_nodup(&kept, path)->util = xstrdup(d->d_name);\n \t}\n \tclosedir(dir);\n \n \tstrbuf_add_absolute_path(&main_path, get_git_common_dir());\n \t/* massage main worktree absolute path to match 'gitdir' content */\n \tstrbuf_strip_suffix(&main_path, \"/.\");\n-\tstring_list_append(&kept, strbuf_detach(&main_path, NULL));\n+\tstring_list_append_nodup(&kept, strbuf_detach(&main_path, NULL));\n \tprune_dups(&kept);\n \tstring_list_clear(&kept, 1);\n \ndiff --git a/t/t2401-worktree-prune.sh b/t/t2401-worktree-prune.sh\nindex 3d28c7f06b2..568a47ec426 100755\n--- a/t/t2401-worktree-prune.sh\n+++ b/t/t2401-worktree-prune.sh\n@@ -5,6 +5,7 @@ test_description='prune $GIT_DIR/worktrees'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success initialize '\ndiff --git a/t/t2406-worktree-repair.sh b/t/t2406-worktree-repair.sh\nindex 5c44453e1c1..8970780efcc 100755\n--- a/t/t2406-worktree-repair.sh\n+++ b/t/t2406-worktree-repair.sh\n@@ -2,6 +2,7 @@\n \n test_description='test git worktree repair'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471331","messageId":"patch-v6-05.19-fb2d9875c73-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v6 05/19] various: add missing clear_pathspec(), fix leaks","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:36Z","receivedAt":"2023-02-02T09:53:33Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix memory leaks resulting from a missing clear_pathspec().\n\n- archive.c: Plug a leak in the \"struct archiver_args\", and\n  clear_pathspec() the \"pathspec\" member that the \"parse_pathspec_arg()\"\n  call in this function populates.\n\n- builtin/clean.c: Fix a memory leak that's been with us since\n  893d839970c (clean: convert to use parse_pathspec, 2013-07-14).\n\n- builtin/reset.c: Add clear_pathspec() calls to cmd_reset(),\n  including to the codepaths where we'd return early.\n\n- builtin/stash.c: Call clear_pathspec() on the pathspec initialized\n  in push_stash().\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n archive.c                       |  1 +\n builtin/clean.c                 |  1 +\n builtin/reset.c                 | 11 ++++++++---\n builtin/stash.c                 |  7 +++++--\n t/t5001-archive-attr.sh         |  1 +\n t/t5004-archive-corner-cases.sh |  2 ++\n t/t7105-reset-patch.sh          |  2 ++\n t/t7106-reset-unborn-branch.sh  |  2 ++\n t/t7107-reset-pathspec-file.sh  |  1 +\n t/t7301-clean-interactive.sh    |  1 +\n 10 files changed, 24 insertions(+), 5 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex 81ff76fce99..f2a8756d84f 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -710,6 +710,7 @@ int write_archive(int argc, const char **argv, const char *prefix,\n \n \tstring_list_clear_func(&args.extra_files, extra_file_info_clear);\n \tfree(args.refname);\n+\tclear_pathspec(&args.pathspec);\n \n \treturn rc;\n }\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex b2701a28158..b15eab328b7 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -1092,5 +1092,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tstrbuf_release(&buf);\n \tstring_list_clear(&del_list, 0);\n \tstring_list_clear(&exclude_list, 0);\n+\tclear_pathspec(&pathspec);\n \treturn (errors != 0);\n }\ndiff --git a/builtin/reset.c b/builtin/reset.c\nindex fea20a9ba0b..e9c10618cd3 100644\n--- a/builtin/reset.c\n+++ b/builtin/reset.c\n@@ -390,7 +390,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \t\tif (reset_type != NONE)\n \t\t\tdie(_(\"options '%s' and '%s' cannot be used together\"), \"--patch\", \"--{hard,mixed,soft}\");\n \t\ttrace2_cmd_mode(\"patch-interactive\");\n-\t\treturn run_add_interactive(rev, \"--patch=reset\", &pathspec);\n+\t\tupdate_ref_status = run_add_interactive(rev, \"--patch=reset\", &pathspec);\n+\t\tgoto cleanup;\n \t}\n \n \t/* git reset tree [--] paths... can be used to\n@@ -439,8 +440,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \t\t\t\t       LOCK_DIE_ON_ERROR);\n \t\tif (reset_type == MIXED) {\n \t\t\tint flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;\n-\t\t\tif (read_from_tree(&pathspec, &oid, intent_to_add))\n-\t\t\t\treturn 1;\n+\t\t\tif (read_from_tree(&pathspec, &oid, intent_to_add)) {\n+\t\t\t\tupdate_ref_status = 1;\n+\t\t\t\tgoto cleanup;\n+\t\t\t}\n \t\t\tthe_index.updated_skipworktree = 1;\n \t\t\tif (!no_refresh && get_git_work_tree()) {\n \t\t\t\tuint64_t t_begin, t_delta_in_ms;\n@@ -488,5 +491,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \n \tdiscard_index(&the_index);\n \n+cleanup:\n+\tclear_pathspec(&pathspec);\n \treturn update_ref_status;\n }\ndiff --git a/builtin/stash.c b/builtin/stash.c\nindex 839569a9803..71a4ee6b1a5 100644\n--- a/builtin/stash.c\n+++ b/builtin/stash.c\n@@ -1727,6 +1727,7 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n \t\tOPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),\n \t\tOPT_END()\n \t};\n+\tint ret;\n \n \tif (argc) {\n \t\tforce_assume = !strcmp(argv[0], \"-p\");\n@@ -1766,8 +1767,10 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n \t\tdie(_(\"the option '%s' requires '%s'\"), \"--pathspec-file-nul\", \"--pathspec-from-file\");\n \t}\n \n-\treturn do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n-\t\t\t     include_untracked, only_staged);\n+\tret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n+\t\t\t    include_untracked, only_staged);\n+\tclear_pathspec(&ps);\n+\treturn ret;\n }\n \n static int push_stash_unassumed(int argc, const char **argv, const char *prefix)\ndiff --git a/t/t5001-archive-attr.sh b/t/t5001-archive-attr.sh\nindex 2f6eef5e372..04d300eeda7 100755\n--- a/t/t5001-archive-attr.sh\n+++ b/t/t5001-archive-attr.sh\n@@ -3,6 +3,7 @@\n test_description='git archive attribute tests'\n \n TEST_CREATE_REPO_NO_TEMPLATE=1\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n SUBSTFORMAT='%H (%h)%n'\ndiff --git a/t/t5004-archive-corner-cases.sh b/t/t5004-archive-corner-cases.sh\nindex ae508e21623..9f2c6da80e8 100755\n--- a/t/t5004-archive-corner-cases.sh\n+++ b/t/t5004-archive-corner-cases.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test corner cases of git-archive'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # the 10knuls.tar file is used to test for an empty git generated tar\ndiff --git a/t/t7105-reset-patch.sh b/t/t7105-reset-patch.sh\nindex fc2a6cf5c7a..9b46da7aaa7 100755\n--- a/t/t7105-reset-patch.sh\n+++ b/t/t7105-reset-patch.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git reset --patch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./lib-patch-mode.sh\n \n test_expect_success PERL 'setup' '\ndiff --git a/t/t7106-reset-unborn-branch.sh b/t/t7106-reset-unborn-branch.sh\nindex ecb85c3b823..a0b67a0b843 100755\n--- a/t/t7106-reset-unborn-branch.sh\n+++ b/t/t7106-reset-unborn-branch.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git reset should work on unborn branch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7107-reset-pathspec-file.sh b/t/t7107-reset-pathspec-file.sh\nindex 523efbecde1..af5ea406db3 100755\n--- a/t/t7107-reset-pathspec-file.sh\n+++ b/t/t7107-reset-pathspec-file.sh\n@@ -2,6 +2,7 @@\n \n test_description='reset --pathspec-from-file'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_tick\ndiff --git a/t/t7301-clean-interactive.sh b/t/t7301-clean-interactive.sh\nindex a07e8b86de2..d82a3210a1d 100755\n--- a/t/t7301-clean-interactive.sh\n+++ b/t/t7301-clean-interactive.sh\n@@ -2,6 +2,7 @@\n \n test_description='git clean -i basic tests'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-terminal.sh\n \n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471332","messageId":"patch-v6-07.19-09950d92940-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v6 07/19] repack: fix leaks on error with \"goto cleanup\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:38Z","receivedAt":"2023-02-02T09:53:35Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"In cmd_repack() when we hit an error, replace \"return ret\" with \"goto\ncleanup\" to ensure we free the necessary data structures.\n\nHelped-by: Elijah Newren <newren@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/repack.c                    | 13 +++++++------\n t/t5312-prune-corruption.sh         |  1 +\n t/t6011-rev-list-with-bad-commit.sh |  1 +\n 3 files changed, 9 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/repack.c b/builtin/repack.c\nindex c1402ad038f..f6493795318 100644\n--- a/builtin/repack.c\n+++ b/builtin/repack.c\n@@ -948,7 +948,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \n \tret = start_command(&cmd);\n \tif (ret)\n-\t\treturn ret;\n+\t\tgoto cleanup;\n \n \tif (geometry) {\n \t\tFILE *in = xfdopen(cmd.in, \"w\");\n@@ -977,7 +977,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \tfclose(out);\n \tret = finish_command(&cmd);\n \tif (ret)\n-\t\treturn ret;\n+\t\tgoto cleanup;\n \n \tif (!names.nr && !po_args.quiet)\n \t\tprintf_ln(_(\"Nothing new to pack.\"));\n@@ -1007,7 +1007,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\t\t\t       &existing_nonkept_packs,\n \t\t\t\t       &existing_kept_packs);\n \t\tif (ret)\n-\t\t\treturn ret;\n+\t\t\tgoto cleanup;\n \n \t\tif (delete_redundant && expire_to) {\n \t\t\t/*\n@@ -1039,7 +1039,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\t\t\t\t       &existing_nonkept_packs,\n \t\t\t\t\t       &existing_kept_packs);\n \t\t\tif (ret)\n-\t\t\t\treturn ret;\n+\t\t\t\tgoto cleanup;\n \t\t}\n \t}\n \n@@ -1115,7 +1115,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\tstring_list_clear(&include, 0);\n \n \t\tif (ret)\n-\t\t\treturn ret;\n+\t\t\tgoto cleanup;\n \t}\n \n \treprepare_packed_git(the_repository);\n@@ -1172,10 +1172,11 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\twrite_midx_file(get_object_directory(), NULL, NULL, flags);\n \t}\n \n+cleanup:\n \tstring_list_clear(&names, 1);\n \tstring_list_clear(&existing_nonkept_packs, 0);\n \tstring_list_clear(&existing_kept_packs, 0);\n \tclear_pack_geometry(geometry);\n \n-\treturn 0;\n+\treturn ret;\n }\ndiff --git a/t/t5312-prune-corruption.sh b/t/t5312-prune-corruption.sh\nindex 9d8e249ae8b..230cb387122 100755\n--- a/t/t5312-prune-corruption.sh\n+++ b/t/t5312-prune-corruption.sh\n@@ -14,6 +14,7 @@ what currently happens. If that changes, these tests should be revisited.\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'disable reflogs' '\ndiff --git a/t/t6011-rev-list-with-bad-commit.sh b/t/t6011-rev-list-with-bad-commit.sh\nindex bad02cf5b83..b2e422cf0f7 100755\n--- a/t/t6011-rev-list-with-bad-commit.sh\n+++ b/t/t6011-rev-list-with-bad-commit.sh\n@@ -2,6 +2,7 @@\n \n test_description='git rev-list should notice bad commits'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Note:\n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471333","messageId":"patch-v6-09.19-e80a719913b-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v6 09/19] http-backend.c: fix \"dir\" and \"cmd_arg\" leaks in cmd_main()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:40Z","receivedAt":"2023-02-02T09:53:49Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Free the \"dir\" variable after we're done with it. Before\n917adc03608 (http-backend: add GIT_PROJECT_ROOT environment var,\n2009-10-30) there was no leak here, as we'd get it via getenv(), but\nsince 917adc03608 we've xstrdup()'d it (or the equivalent), so we need\nto free() it.\n\nWe also need to free the \"cmd_arg\" variable, which has been leaked\never since it was added in 2f4038ab337 (Git-aware CGI to provide dumb\nHTTP transport, 2009-10-30).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n http-backend.c | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git a/http-backend.c b/http-backend.c\nindex 6eb3b2fe51c..67819d931ce 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -786,6 +786,7 @@ int cmd_main(int argc, const char **argv)\n \tif (!getenv(\"GIT_HTTP_EXPORT_ALL\") &&\n \t    access(\"git-daemon-export-ok\", F_OK) )\n \t\tnot_found(&hdr, \"Repository not exported: '%s'\", dir);\n+\tfree(dir);\n \n \thttp_config();\n \tmax_request_buffer = git_env_ulong(\"GIT_HTTP_MAX_REQUEST_BUFFER\",\n@@ -795,5 +796,6 @@ int cmd_main(int argc, const char **argv)\n \t\tsetenv(GIT_PROTOCOL_ENVIRONMENT, proto_header, 0);\n \n \tcmd->imp(&hdr, cmd_arg);\n+\tfree(cmd_arg);\n \treturn 0;\n }\n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471334","messageId":"patch-v6-11.19-65e25377791-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v6 11/19] commit-graph: fix a parse_options_concat() leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:42Z","receivedAt":"2023-02-02T09:53:51Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the parse_options_concat() was added to this file in\n84e4484f128 (commit-graph: use parse_options_concat(), 2021-08-23) we\nwouldn't free() it if we returned early in these cases.\n\nSince \"result\" is 0 by default we can \"goto cleanup\" in both cases,\nand only need to set \"result\" if write_commit_graph_reachable() fails.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/commit-graph.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/commit-graph.c b/builtin/commit-graph.c\nindex 0102ac8540e..93704f95a9d 100644\n--- a/builtin/commit-graph.c\n+++ b/builtin/commit-graph.c\n@@ -269,8 +269,8 @@ static int graph_write(int argc, const char **argv, const char *prefix)\n \n \tif (opts.reachable) {\n \t\tif (write_commit_graph_reachable(odb, flags, &write_opts))\n-\t\t\treturn 1;\n-\t\treturn 0;\n+\t\t\tresult = 1;\n+\t\tgoto cleanup;\n \t}\n \n \tif (opts.stdin_packs) {\n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471335","messageId":"patch-v6-10.19-9d9df0caf17-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v6 10/19] http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:41Z","receivedAt":"2023-02-02T09:53:52Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us ever since\n2f4038ab337 (Git-aware CGI to provide dumb HTTP transport,\n2009-10-30). In this case we're not calling regerror() after a failed\nregexec(), and don't otherwise use \"re\" afterwards.\n\nWe can therefore simplify this code by calling regfree() right after\nthe regexec(). An alternative fix would be to add a regfree() to both\nthe \"return\" and \"break\" path in this for-loop.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n http-backend.c | 7 +++++--\n 1 file changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/http-backend.c b/http-backend.c\nindex 67819d931ce..8ab58e55f85 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -759,10 +759,14 @@ int cmd_main(int argc, const char **argv)\n \t\tstruct service_cmd *c = &services[i];\n \t\tregex_t re;\n \t\tregmatch_t out[1];\n+\t\tint ret;\n \n \t\tif (regcomp(&re, c->pattern, REG_EXTENDED))\n \t\t\tdie(\"Bogus regex in service table: %s\", c->pattern);\n-\t\tif (!regexec(&re, dir, 1, out, 0)) {\n+\t\tret = regexec(&re, dir, 1, out, 0);\n+\t\tregfree(&re);\n+\n+\t\tif (!ret) {\n \t\t\tsize_t n;\n \n \t\t\tif (strcmp(method, c->method))\n@@ -774,7 +778,6 @@ int cmd_main(int argc, const char **argv)\n \t\t\tdir[out[0].rm_so] = 0;\n \t\t\tbreak;\n \t\t}\n-\t\tregfree(&re);\n \t}\n \n \tif (!cmd)\n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471336","messageId":"patch-v6-06.19-bca659788de-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v6 06/19] name-rev: don't xstrdup() an already dup'd string","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:37Z","receivedAt":"2023-02-02T09:53:55Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When \"add_to_tip_table()\" is called with a non-zero\n\"shorten_unambiguous\" we always return an xstrdup()'d string, which\nwe'd then xstrdup() again, leaking memory. See [1] and [2] for how\nthis leak came about.\n\nWe could xstrdup() only if \"shorten_unambiguous\" wasn't true, but\nlet's instead inline this code, so that information on whether we need\nto xstrdup() is contained within add_to_tip_table().\n\n1. 98c5c4ad015 (name-rev: allow to specify a subpath for --refs\n   option, 2013-06-18)\n2. b23e0b9353e (name-rev: allow converting the exact object name at\n   the tip of a ref, 2013-07-07)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/name-rev.c | 23 ++++++++++-------------\n 1 file changed, 10 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin/name-rev.c b/builtin/name-rev.c\nindex 15535e914a6..49fae523694 100644\n--- a/builtin/name-rev.c\n+++ b/builtin/name-rev.c\n@@ -273,17 +273,6 @@ static int subpath_matches(const char *path, const char *filter)\n \treturn -1;\n }\n \n-static const char *name_ref_abbrev(const char *refname, int shorten_unambiguous)\n-{\n-\tif (shorten_unambiguous)\n-\t\trefname = shorten_unambiguous_ref(refname, 0);\n-\telse if (skip_prefix(refname, \"refs/heads/\", &refname))\n-\t\t; /* refname already advanced */\n-\telse\n-\t\tskip_prefix(refname, \"refs/\", &refname);\n-\treturn refname;\n-}\n-\n struct name_ref_data {\n \tint tags_only;\n \tint name_only;\n@@ -309,11 +298,19 @@ static void add_to_tip_table(const struct object_id *oid, const char *refname,\n \t\t\t     int shorten_unambiguous, struct commit *commit,\n \t\t\t     timestamp_t taggerdate, int from_tag, int deref)\n {\n-\trefname = name_ref_abbrev(refname, shorten_unambiguous);\n+\tchar *short_refname = NULL;\n+\n+\tif (shorten_unambiguous)\n+\t\tshort_refname = shorten_unambiguous_ref(refname, 0);\n+\telse if (skip_prefix(refname, \"refs/heads/\", &refname))\n+\t\t; /* refname already advanced */\n+\telse\n+\t\tskip_prefix(refname, \"refs/\", &refname);\n \n \tALLOC_GROW(tip_table.table, tip_table.nr + 1, tip_table.alloc);\n \toidcpy(&tip_table.table[tip_table.nr].oid, oid);\n-\ttip_table.table[tip_table.nr].refname = xstrdup(refname);\n+\ttip_table.table[tip_table.nr].refname = short_refname ?\n+\t\tshort_refname : xstrdup(refname);\n \ttip_table.table[tip_table.nr].commit = commit;\n \ttip_table.table[tip_table.nr].taggerdate = taggerdate;\n \ttip_table.table[tip_table.nr].from_tag = from_tag;\n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471337","messageId":"patch-v6-12.19-3b1d47b9d62-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v6 12/19] show-branch: free() allocated \"head\" before return","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:43Z","receivedAt":"2023-02-02T09:53:57Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Stop leaking the \"head\" variable, which we've been leaking since it\nwas originally added in [1], and in its current form since [2]\n\n1. ed378ec7e85 (Make ref resolution saner, 2006-09-11)\n2. d9e557a320b (show-branch: store resolved head in heap buffer,\n   2017-02-14).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/show-branch.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/show-branch.c b/builtin/show-branch.c\nindex c013abaf942..358ac3e519a 100644\n--- a/builtin/show-branch.c\n+++ b/builtin/show-branch.c\n@@ -956,5 +956,6 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)\n \t\tif (shown_merge_point && --extra < 0)\n \t\t\tbreak;\n \t}\n+\tfree(head);\n \treturn 0;\n }\n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471338","messageId":"patch-v6-13.19-a85e5f3b14e-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v6 13/19] builtin/merge.c: use fixed strings, not \"strbuf\", fix leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:44Z","receivedAt":"2023-02-02T09:53:59Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Follow-up 465028e0e25 (merge: add missing strbuf_release(),\n2021-10-07) and address the \"msg\" memory leak in this block. We could\nfree \"&msg\" before the \"goto done\" here, but even better is to avoid\nallocating it in the first place.\n\nBy repeating the \"Fast-forward\" string here we can avoid using a\n\"struct strbuf\" altogether.\n\nSuggested-by: René Scharfe <l.s.r@web.de>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/merge.c                | 11 ++++-------\n t/t6439-merge-co-error-msgs.sh |  1 +\n 2 files changed, 5 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 74de2ebd2b3..32733e551d4 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -1560,7 +1560,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t!common->next &&\n \t\t\toideq(&common->item->object.oid, &head_commit->object.oid)) {\n \t\t/* Again the most common case of merging one remote. */\n-\t\tstruct strbuf msg = STRBUF_INIT;\n+\t\tconst char *msg = have_message ?\n+\t\t\t\"Fast-forward (no commit created; -m option ignored)\" :\n+\t\t\t\"Fast-forward\";\n \t\tstruct commit *commit;\n \n \t\tif (verbosity >= 0) {\n@@ -1570,10 +1572,6 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t       find_unique_abbrev(&remoteheads->item->object.oid,\n \t\t\t\t\t\t  DEFAULT_ABBREV));\n \t\t}\n-\t\tstrbuf_addstr(&msg, \"Fast-forward\");\n-\t\tif (have_message)\n-\t\t\tstrbuf_addstr(&msg,\n-\t\t\t\t\" (no commit created; -m option ignored)\");\n \t\tcommit = remoteheads->item;\n \t\tif (!commit) {\n \t\t\tret = 1;\n@@ -1592,9 +1590,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\tgoto done;\n \t\t}\n \n-\t\tfinish(head_commit, remoteheads, &commit->object.oid, msg.buf);\n+\t\tfinish(head_commit, remoteheads, &commit->object.oid, msg);\n \t\tremove_merge_branch_state(the_repository);\n-\t\tstrbuf_release(&msg);\n \t\tgoto done;\n \t} else if (!remoteheads->next && common->next)\n \t\t;\ndiff --git a/t/t6439-merge-co-error-msgs.sh b/t/t6439-merge-co-error-msgs.sh\nindex 52cf0c87690..0cbec57cdab 100755\n--- a/t/t6439-merge-co-error-msgs.sh\n+++ b/t/t6439-merge-co-error-msgs.sh\n@@ -5,6 +5,7 @@ test_description='unpack-trees error messages'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n \n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471339","messageId":"patch-v6-14.19-7dbc422d5b4-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v6 14/19] builtin/merge.c: free \"&buf\" on \"Your local changes...\" error","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:45Z","receivedAt":"2023-02-02T09:54:08Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Plug a memory leak introduced in [1], since that change didn't follow\nthe \"goto done\" pattern introduced in [2] we'd leak the \"&buf\" memory.\n\n1. e4cdfe84a0d (merge: abort if index does not match HEAD for trivial\n   merges, 2022-07-23)\n2. d5a35c114ab (Copy resolve_ref() return value for longer use,\n   2011-11-13)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/merge.c | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 32733e551d4..5a834b1f291 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -1618,7 +1618,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t\terror(_(\"Your local changes to the following files would be overwritten by merge:\\n  %s\"),\n \t\t\t\t      sb.buf);\n \t\t\t\tstrbuf_release(&sb);\n-\t\t\t\treturn 2;\n+\t\t\t\tret = 2;\n+\t\t\t\tgoto done;\n \t\t\t}\n \n \t\t\t/* See if it is really trivial. */\n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471340","messageId":"patch-v6-15.19-aa51668b70d-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v6 15/19] grep.c: refactor free_grep_patterns()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:46Z","receivedAt":"2023-02-02T09:54:10Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Refactor the free_grep_patterns() function to split out the freeing of\nthe \"struct grep_pat\" it contains. Right now we're only freeing the\n\"pattern_list\", but we should be freeing another member of the same\ntype, which we'll do in the subsequent commit.\n\nLet's also replace the \"return\" if we don't have an\n\"opt->pattern_expression\" with a conditional call of\nfree_pattern_expr().\n\nBefore db84376f981 (grep.c: remove \"extended\" in favor of\n\"pattern_expression\", fix segfault, 2022-10-11) the pattern here was:\n\n\tif (!x)\n\t\treturn;\n\tfree_pattern_expr(y);\n\nWhile at it, instead of:\n\n\tif (!x)\n\t\treturn;\n\tfree_pattern_expr(x);\n\nLet's instead do:\n\n\tif (x)\n\t\tfree_pattern_expr(x);\n\nThis will make it easier to free additional members from\nfree_grep_patterns() in the future.\n\nHelped-by: Elijah Newren <newren@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n grep.c | 14 +++++++++-----\n 1 file changed, 9 insertions(+), 5 deletions(-)\n\ndiff --git a/grep.c b/grep.c\nindex 1687f65b64f..f8708e1fd20 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -769,11 +769,11 @@ static void free_pattern_expr(struct grep_expr *x)\n \tfree(x);\n }\n \n-void free_grep_patterns(struct grep_opt *opt)\n+static void free_grep_pat(struct grep_pat *pattern)\n {\n \tstruct grep_pat *p, *n;\n \n-\tfor (p = opt->pattern_list; p; p = n) {\n+\tfor (p = pattern; p; p = n) {\n \t\tn = p->next;\n \t\tswitch (p->token) {\n \t\tcase GREP_PATTERN: /* atom */\n@@ -790,10 +790,14 @@ void free_grep_patterns(struct grep_opt *opt)\n \t\t}\n \t\tfree(p);\n \t}\n+}\n \n-\tif (!opt->pattern_expression)\n-\t\treturn;\n-\tfree_pattern_expr(opt->pattern_expression);\n+void free_grep_patterns(struct grep_opt *opt)\n+{\n+\tfree_grep_pat(opt->pattern_list);\n+\n+\tif (opt->pattern_expression)\n+\t\tfree_pattern_expr(opt->pattern_expression);\n }\n \n static const char *end_of_line(const char *cp, unsigned long *left)\n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471341","messageId":"patch-v6-16.19-0c51ea7fd2d-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v6 16/19] grep API: plug memory leaks by freeing \"header_list\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:47Z","receivedAt":"2023-02-02T09:54:11Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the \"header_list\" struct member was added in [1], freeing this\nfield was neglected. Fix that now, so that commands like\n\n\t./git -P log -1 --color=always --author=A origin/master\n\nwill run leak-free.\n\n1. 80235ba79ef (\"log --author=me --grep=it\" should find intersection,\n   not union, 2010-01-17)\n\nHelped-by: Elijah Newren <newren@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n grep.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/grep.c b/grep.c\nindex f8708e1fd20..92ece4b7fa3 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -795,6 +795,7 @@ static void free_grep_pat(struct grep_pat *pattern)\n void free_grep_patterns(struct grep_opt *opt)\n {\n \tfree_grep_pat(opt->pattern_list);\n+\tfree_grep_pat(opt->header_list);\n \n \tif (opt->pattern_expression)\n \t\tfree_pattern_expr(opt->pattern_expression);\n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471342","messageId":"patch-v6-18.19-aa33f7e05c8-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v6 18/19] push: refactor refspec_append_mapped() for subsequent leak-fix","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:49Z","receivedAt":"2023-02-02T09:54:14Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"The set_refspecs() caller of refspec_append_mapped() (added in [1])\nleft open the question[2] of whether the \"remote\" we lazily fetch\nmight be NULL in the \"[...]uniquely name our ref?\" case, as\nremote_get() can return NULL.\n\nIf we got past the \"[...]uniquely name our ref?\" case we'd have\nalready segfaulted if we tried to dereference it as\n\"remote->push.nr\". In these cases the config mechanism & previous\nremote validation will have bailed out earlier.\n\nLet's refactor this code to clarify that, we'll now BUG() out if we\ncan't get a \"remote\", and will no longer retrieve it for these common\ncases where we don't need it.\n\n1. ca02465b413 (push: use remote.$name.push as a refmap, 2013-12-03)\n2. https://lore.kernel.org/git/c0c07b89-7eaf-21cd-748e-e14ea57f09fd@web.de/\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/push.c | 29 +++++++++++++++++------------\n 1 file changed, 17 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/push.c b/builtin/push.c\nindex 60ac8017e52..97b35eca3ab 100644\n--- a/builtin/push.c\n+++ b/builtin/push.c\n@@ -63,16 +63,9 @@ static struct refspec rs = REFSPEC_INIT_PUSH;\n static struct string_list push_options_config = STRING_LIST_INIT_DUP;\n \n static void refspec_append_mapped(struct refspec *refspec, const char *ref,\n-\t\t\t\t  struct remote *remote, struct ref *local_refs)\n+\t\t\t\t  struct remote *remote, struct ref *matched)\n {\n \tconst char *branch_name;\n-\tstruct ref *matched = NULL;\n-\n-\t/* Does \"ref\" uniquely name our ref? */\n-\tif (count_refspec_match(ref, local_refs, &matched) != 1) {\n-\t\trefspec_append(refspec, ref);\n-\t\treturn;\n-\t}\n \n \tif (remote->push.nr) {\n \t\tstruct refspec_item query;\n@@ -120,12 +113,24 @@ static void set_refspecs(const char **refs, int nr, const char *repo)\n \t\t\t\tdie(_(\"--delete only accepts plain target ref names\"));\n \t\t\trefspec_appendf(&rs, \":%s\", ref);\n \t\t} else if (!strchr(ref, ':')) {\n-\t\t\tif (!remote) {\n-\t\t\t\t/* lazily grab remote and local_refs */\n-\t\t\t\tremote = remote_get(repo);\n+\t\t\tstruct ref *matched = NULL;\n+\n+\t\t\t/* lazily grab local_refs */\n+\t\t\tif (!local_refs)\n \t\t\t\tlocal_refs = get_local_heads();\n+\n+\t\t\t/* Does \"ref\" uniquely name our ref? */\n+\t\t\tif (count_refspec_match(ref, local_refs, &matched) != 1) {\n+\t\t\t\trefspec_append(&rs, ref);\n+\t\t\t} else {\n+\t\t\t\t/* lazily grab remote */\n+\t\t\t\tif (!remote)\n+\t\t\t\t\tremote = remote_get(repo);\n+\t\t\t\tif (!remote)\n+\t\t\t\t\tBUG(\"must get a remote for repo '%s'\", repo);\n+\n+\t\t\t\trefspec_append_mapped(&rs, ref, remote, matched);\n \t\t\t}\n-\t\t\trefspec_append_mapped(&rs, ref, remote, local_refs);\n \t\t} else\n \t\t\trefspec_append(&rs, ref);\n \t}\n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471343","messageId":"patch-v6-17.19-4b2db91f5cb-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v6 17/19] receive-pack: free() the \"ref_name\" in \"struct command\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:48Z","receivedAt":"2023-02-02T09:54:16Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us since this code was introduced\nin 575f497456e (Add first cut at \"git-receive-pack\", 2005-06-29). See\neb1af2df0b1 (git-receive-pack: start parsing ref update commands,\n2005-06-29) for the later change that refactored the code to add the\n\"ref_name\" member.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/receive-pack.c                 | 10 ++++++++++\n t/t5405-send-pack-rewind.sh            |  1 +\n t/t5406-remote-rejects.sh              |  1 +\n t/t5507-remote-environment.sh          |  2 ++\n t/t5522-pull-symlink.sh                |  1 +\n t/t5527-fetch-odd-refs.sh              |  1 +\n t/t5560-http-backend-noserver.sh       |  1 +\n t/t5561-http-backend.sh                |  1 +\n t/t5562-http-backend-content-length.sh |  2 ++\n t/t5705-session-id-in-capabilities.sh  |  1 +\n 10 files changed, 21 insertions(+)\n\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex a90af303630..451bad776c6 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -2032,6 +2032,15 @@ static struct command **queue_command(struct command **tail,\n \treturn &cmd->next;\n }\n \n+static void free_commands(struct command *commands)\n+{\n+\twhile (commands) {\n+\t\tstruct command *next = commands->next;\n+\t\tfree(commands);\n+\t\tcommands = next;\n+\t}\n+}\n+\n static void queue_commands_from_cert(struct command **tail,\n \t\t\t\t     struct strbuf *push_cert)\n {\n@@ -2569,6 +2578,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n \t\trun_receive_hook(commands, \"post-receive\", 1,\n \t\t\t\t &push_options);\n \t\trun_update_post_hook(commands);\n+\t\tfree_commands(commands);\n \t\tstring_list_clear(&push_options, 0);\n \t\tif (auto_gc) {\n \t\t\tstruct child_process proc = CHILD_PROCESS_INIT;\ndiff --git a/t/t5405-send-pack-rewind.sh b/t/t5405-send-pack-rewind.sh\nindex 11f03239a06..1686ac13aa6 100755\n--- a/t/t5405-send-pack-rewind.sh\n+++ b/t/t5405-send-pack-rewind.sh\n@@ -5,6 +5,7 @@ test_description='forced push to replace commit we do not have'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5406-remote-rejects.sh b/t/t5406-remote-rejects.sh\nindex dcbeb420827..d6a99466338 100755\n--- a/t/t5406-remote-rejects.sh\n+++ b/t/t5406-remote-rejects.sh\n@@ -2,6 +2,7 @@\n \n test_description='remote push rejects are reported by client'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t5507-remote-environment.sh b/t/t5507-remote-environment.sh\nindex e6149295b18..c6a6957c500 100755\n--- a/t/t5507-remote-environment.sh\n+++ b/t/t5507-remote-environment.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check environment showed to remote side of transports'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'set up \"remote\" push situation' '\ndiff --git a/t/t5522-pull-symlink.sh b/t/t5522-pull-symlink.sh\nindex bcff460d0a2..394bc60cb8e 100755\n--- a/t/t5522-pull-symlink.sh\n+++ b/t/t5522-pull-symlink.sh\n@@ -2,6 +2,7 @@\n \n test_description='pulling from symlinked subdir'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # The scenario we are building:\ndiff --git a/t/t5527-fetch-odd-refs.sh b/t/t5527-fetch-odd-refs.sh\nindex e2770e4541f..98ece27c6a0 100755\n--- a/t/t5527-fetch-odd-refs.sh\n+++ b/t/t5527-fetch-odd-refs.sh\n@@ -4,6 +4,7 @@ test_description='test fetching of oddly-named refs'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # afterwards we will have:\ndiff --git a/t/t5560-http-backend-noserver.sh b/t/t5560-http-backend-noserver.sh\nindex d30cf4f5b83..f75068de648 100755\n--- a/t/t5560-http-backend-noserver.sh\n+++ b/t/t5560-http-backend-noserver.sh\n@@ -4,6 +4,7 @@ test_description='test git-http-backend-noserver'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n HTTPD_DOCUMENT_ROOT_PATH=\"$TRASH_DIRECTORY\"\ndiff --git a/t/t5561-http-backend.sh b/t/t5561-http-backend.sh\nindex 9c57d843152..e1d3b8caed0 100755\n--- a/t/t5561-http-backend.sh\n+++ b/t/t5561-http-backend.sh\n@@ -4,6 +4,7 @@ test_description='test git-http-backend'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-httpd.sh\n \ndiff --git a/t/t5562-http-backend-content-length.sh b/t/t5562-http-backend-content-length.sh\nindex b68ec22d3fd..7ee9858a78b 100755\n--- a/t/t5562-http-backend-content-length.sh\n+++ b/t/t5562-http-backend-content-length.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test git-http-backend respects CONTENT_LENGTH'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_lazy_prereq GZIP 'gzip --version'\ndiff --git a/t/t5705-session-id-in-capabilities.sh b/t/t5705-session-id-in-capabilities.sh\nindex ed38c76c290..b8a722ec27e 100755\n--- a/t/t5705-session-id-in-capabilities.sh\n+++ b/t/t5705-session-id-in-capabilities.sh\n@@ -2,6 +2,7 @@\n \n test_description='session ID in capabilities'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n REPO=\"$(pwd)/repo\"\n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471344","messageId":"patch-v6-19.19-67076dfba6d-20230202T094704Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v6 19/19] push: free_refs() the \"local_refs\" in set_refspecs()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-02T09:52:50Z","receivedAt":"2023-02-02T09:54:18Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us since this code was added in\nca02465b413 (push: use remote.$name.push as a refmap, 2013-12-03).\n\nThe \"remote = remote_get(...)\" added in the same commit would seem to\nleak based only on the context here, but that function is a wrapper\nfor sticking the remotes we fetch into \"the_repository->remote_state\".\n\nSee fd3cb0501e1 (remote: move static variables into per-repository\nstruct, 2021-11-17) for the addition of code in repository.c that\nfree's the \"remote\" allocated here.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/push.c                          | 1 +\n t/t1416-ref-transaction-hooks.sh        | 1 +\n t/t2402-worktree-list.sh                | 1 +\n t/t5504-fetch-receive-strict.sh         | 1 +\n t/t5523-push-upstream.sh                | 1 +\n t/t5529-push-errors.sh                  | 2 ++\n t/t5546-receive-limits.sh               | 2 ++\n t/t5547-push-quarantine.sh              | 2 ++\n t/t5606-clone-options.sh                | 1 +\n t/t5810-proto-disable-local.sh          | 2 ++\n t/t5813-proto-disable-ssh.sh            | 2 ++\n t/t7409-submodule-detached-work-tree.sh | 1 +\n t/t7416-submodule-dash-url.sh           | 2 ++\n t/t7450-bad-git-dotfiles.sh             | 2 ++\n 14 files changed, 21 insertions(+)\n\ndiff --git a/builtin/push.c b/builtin/push.c\nindex 97b35eca3ab..8f7d326ab3f 100644\n--- a/builtin/push.c\n+++ b/builtin/push.c\n@@ -134,6 +134,7 @@ static void set_refspecs(const char **refs, int nr, const char *repo)\n \t\t} else\n \t\t\trefspec_append(&rs, ref);\n \t}\n+\tfree_refs(local_refs);\n }\n \n static int push_url_of_remote(struct remote *remote, const char ***url_p)\ndiff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh\nindex 27731722a5b..b32ca798f9f 100755\n--- a/t/t1416-ref-transaction-hooks.sh\n+++ b/t/t1416-ref-transaction-hooks.sh\n@@ -5,6 +5,7 @@ test_description='reference transaction hooks'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t2402-worktree-list.sh b/t/t2402-worktree-list.sh\nindex 79e0fce2d90..9ad9be0c208 100755\n--- a/t/t2402-worktree-list.sh\n+++ b/t/t2402-worktree-list.sh\n@@ -5,6 +5,7 @@ test_description='test git worktree list'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh\nindex 88d3c56750a..0b8ab4afdbe 100755\n--- a/t/t5504-fetch-receive-strict.sh\n+++ b/t/t5504-fetch-receive-strict.sh\n@@ -4,6 +4,7 @@ test_description='fetch/receive strict mode'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup and inject \"corrupt or missing\" object' '\ndiff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh\nindex fdb42920564..c9acc076353 100755\n--- a/t/t5523-push-upstream.sh\n+++ b/t/t5523-push-upstream.sh\n@@ -4,6 +4,7 @@ test_description='push with --set-upstream'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-terminal.sh\n \ndiff --git a/t/t5529-push-errors.sh b/t/t5529-push-errors.sh\nindex ce85fd30ad1..0247137cb36 100755\n--- a/t/t5529-push-errors.sh\n+++ b/t/t5529-push-errors.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='detect some push errors early (before contacting remote)'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup commits' '\ndiff --git a/t/t5546-receive-limits.sh b/t/t5546-receive-limits.sh\nindex 0b0e987fdb7..eed3c9d81ab 100755\n--- a/t/t5546-receive-limits.sh\n+++ b/t/t5546-receive-limits.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check receive input limits'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Let's run tests with different unpack limits: 1 and 10000\ndiff --git a/t/t5547-push-quarantine.sh b/t/t5547-push-quarantine.sh\nindex 1876fb34e51..9f899b8c7d7 100755\n--- a/t/t5547-push-quarantine.sh\n+++ b/t/t5547-push-quarantine.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check quarantine of objects during push'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'create picky dest repo' '\ndiff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh\nindex cf221e92c4d..27f9f776389 100755\n--- a/t/t5606-clone-options.sh\n+++ b/t/t5606-clone-options.sh\n@@ -4,6 +4,7 @@ test_description='basic clone options'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t5810-proto-disable-local.sh b/t/t5810-proto-disable-local.sh\nindex c1ef99b85c2..862610256fb 100755\n--- a/t/t5810-proto-disable-local.sh\n+++ b/t/t5810-proto-disable-local.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test disabling of local paths in clone/fetch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY/lib-proto-disable.sh\"\n \ndiff --git a/t/t5813-proto-disable-ssh.sh b/t/t5813-proto-disable-ssh.sh\nindex 3f084ee3065..2e975dc70ec 100755\n--- a/t/t5813-proto-disable-ssh.sh\n+++ b/t/t5813-proto-disable-ssh.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test disabling of git-over-ssh in clone/fetch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY/lib-proto-disable.sh\"\n \ndiff --git a/t/t7409-submodule-detached-work-tree.sh b/t/t7409-submodule-detached-work-tree.sh\nindex 374ed481e9c..574a6fc526e 100755\n--- a/t/t7409-submodule-detached-work-tree.sh\n+++ b/t/t7409-submodule-detached-work-tree.sh\n@@ -13,6 +13,7 @@ TEST_NO_CREATE_REPO=1\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7416-submodule-dash-url.sh b/t/t7416-submodule-dash-url.sh\nindex 3ebd9859814..7cf72b9a076 100755\n--- a/t/t7416-submodule-dash-url.sh\n+++ b/t/t7416-submodule-dash-url.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check handling of disallowed .gitmodule urls'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7450-bad-git-dotfiles.sh b/t/t7450-bad-git-dotfiles.sh\nindex ba1f569bcbb..0d0c3f2c683 100755\n--- a/t/t7450-bad-git-dotfiles.sh\n+++ b/t/t7450-bad-git-dotfiles.sh\n@@ -12,6 +12,8 @@ Such as:\n \n   - symlinked .gitmodules, etc\n '\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-pack.sh\n \n-- \n2.39.1.1392.g63e6d408230\n\n"},{"id":"471398","messageId":"xmqqo7qbspf0.fsf@gitster.g","threadId":"59011","inReplyTo":"patch-v6-17.19-4b2db91f5cb-20230202T094704Z-avarab@gmail.com","subject":"Re: [PATCH v6 17/19] receive-pack: free() the \"ref_name\" in \"struct command\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-02-02T21:55:31Z","receivedAt":"2023-02-02T21:55:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> Fix a memory leak that's been with us since this code was introduced\n> in 575f497456e (Add first cut at \"git-receive-pack\", 2005-06-29). See\n> eb1af2df0b1 (git-receive-pack: start parsing ref update commands,\n> 2005-06-29) for the later change that refactored the code to add the\n> \"ref_name\" member.\n\nThe above description does not really match what the patch does,\nthough.  Yes, command.ref_name[] member held varying number of bytes\nin it, but the code was leaking a singly linked list of the entire\ncommand structure, not just ref_name[] member.  And the patch makes\nsure we will release the resource held by the entire chain, not just\nthe ref_name flex-array member.\n"},{"id":"471399","messageId":"xmqqk00zsoqh.fsf@gitster.g","threadId":"59011","inReplyTo":"patch-v6-18.19-aa33f7e05c8-20230202T094704Z-avarab@gmail.com","subject":"Re: [PATCH v6 18/19] push: refactor refspec_append_mapped() for subsequent leak-fix","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-02-02T22:10:14Z","receivedAt":"2023-02-02T22:10:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> The set_refspecs() caller of refspec_append_mapped() (added in [1])\n> left open the question[2] of whether the \"remote\" we lazily fetch\n> might be NULL in the \"[...]uniquely name our ref?\" case, as\n> remote_get() can return NULL.\n>\n> If we got past the \"[...]uniquely name our ref?\" case we'd have\n> already segfaulted if we tried to dereference it as\n> \"remote->push.nr\". In these cases the config mechanism & previous\n> remote validation will have bailed out earlier.\n>\n> Let's refactor this code to clarify that, we'll now BUG() out if we\n> can't get a \"remote\", and will no longer retrieve it for these common\n> cases where we don't need it.\n\nAnother thing this does, if I am not mistaken, and the above does\nnot mention, is, that the old code called get_local_heads() for each\nand every ref from the command line, and the second and subsequent\ncalls to the function and assignment to local_refs would leak the\nentire local_refs linked list.  This step does not release the\nlinked list at the end, but at least it stops leaking it in each\niteration of the loop.\n"},{"id":"471400","messageId":"xmqqfsbnson8.fsf@gitster.g","threadId":"59011","inReplyTo":"patch-v6-19.19-67076dfba6d-20230202T094704Z-avarab@gmail.com","subject":"Re: [PATCH v6 19/19] push: free_refs() the \"local_refs\" in set_refspecs()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-02-02T22:12:11Z","receivedAt":"2023-02-02T22:12:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> Fix a memory leak that's been with us since this code was added in\n> ca02465b413 (push: use remote.$name.push as a refmap, 2013-12-03).\n>\n> The \"remote = remote_get(...)\" added in the same commit would seem to\n> leak based only on the context here, but that function is a wrapper\n> for sticking the remotes we fetch into \"the_repository->remote_state\".\n>\n> See fd3cb0501e1 (remote: move static variables into per-repository\n> struct, 2021-11-17) for the addition of code in repository.c that\n> free's the \"remote\" allocated here.\n\nAs I noted in my review of the previous step, the \"if !local_heads\"\nchange we saw in the previous step goes better in this step, whose\nfocus is on fixing the local_refs leak.\n\n"},{"id":"471568","messageId":"230206.86sffi67ce.gmgdl@evledraar.gmail.com","threadId":"59011","inReplyTo":"xmqqk00zsoqh.fsf@gitster.g","subject":"Re: [PATCH v6 18/19] push: refactor refspec_append_mapped() for subsequent leak-fix","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T17:16:21Z","receivedAt":"2023-02-06T17:18:16Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Thu, Feb 02 2023, Junio C Hamano wrote:\n\n> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n>\n>> The set_refspecs() caller of refspec_append_mapped() (added in [1])\n>> left open the question[2] of whether the \"remote\" we lazily fetch\n>> might be NULL in the \"[...]uniquely name our ref?\" case, as\n>> remote_get() can return NULL.\n>>\n>> If we got past the \"[...]uniquely name our ref?\" case we'd have\n>> already segfaulted if we tried to dereference it as\n>> \"remote->push.nr\". In these cases the config mechanism & previous\n>> remote validation will have bailed out earlier.\n>>\n>> Let's refactor this code to clarify that, we'll now BUG() out if we\n>> can't get a \"remote\", and will no longer retrieve it for these common\n>> cases where we don't need it.\n>\n> Another thing this does, if I am not mistaken, and the above does\n> not mention, is, that the old code called get_local_heads() for each\n> and every ref from the command line, and the second and subsequent\n> calls to the function and assignment to local_refs would leak the\n> entire local_refs linked list.  This step does not release the\n> linked list at the end, but at least it stops leaking it in each\n> iteration of the loop.\n\nI think you're mistaken, or I'm misunderstanding you. For e.g. the 29th\ntest in t4301-merge-tree-write-tree.sh where we do:\n\n\tgit push read-only side1 side2 side3\n\nWe'll only invoke \"get_local_heads()\" once, not once for each of the\nrefs. That's part of the reason for this refactoring: It *looks* as\nthough we might do it N times, but in practice we always get hte\n\"remote\", so we only leak it once.\n\n"},{"id":"471569","messageId":"230206.86o7q6675y.gmgdl@evledraar.gmail.com","threadId":"59011","inReplyTo":"xmqqfsbnson8.fsf@gitster.g","subject":"Re: [PATCH v6 19/19] push: free_refs() the \"local_refs\" in set_refspecs()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T17:19:14Z","receivedAt":"2023-02-06T17:22:10Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Thu, Feb 02 2023, Junio C Hamano wrote:\n\n> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n>\n>> Fix a memory leak that's been with us since this code was added in\n>> ca02465b413 (push: use remote.$name.push as a refmap, 2013-12-03).\n>>\n>> The \"remote = remote_get(...)\" added in the same commit would seem to\n>> leak based only on the context here, but that function is a wrapper\n>> for sticking the remotes we fetch into \"the_repository->remote_state\".\n>>\n>> See fd3cb0501e1 (remote: move static variables into per-repository\n>> struct, 2021-11-17) for the addition of code in repository.c that\n>> free's the \"remote\" allocated here.\n>\n> As I noted in my review of the previous step, the \"if !local_heads\"\n> change we saw in the previous step goes better in this step, whose\n> focus is on fixing the local_refs leak.\n\nAs I noted in the reply there it belongs in the preceding commit because\nwe currently *don't* allocate in a loop, it just looks at first glance\nas though we might.\n\nIn practice we have earlier checks that would have died if the\nremote_get() died, so the current \"remote\" sentinel value always\nincludes \"local_heads\".\n\nI'll send a re-roll of this sooner than later with something to address\nyour 17/19 comment, but am keeping 18-19/19 the same, unless you reply\nhere/disagree/I've missed something.\n\nThanks.\n"},{"id":"471640","messageId":"patch-v7-01.19-ab180d78c7b-20230206T230142Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"[PATCH v7 01/19] tests: mark tests as passing with SANITIZE=leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:36Z","receivedAt":"2023-02-06T23:08:17Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the \"ab/various-leak-fixes\" topic was merged in [1] only t6021\nwould fail if the tests were run in the\n\"GIT_TEST_PASSING_SANITIZE_LEAK=check\" mode, i.e. to check whether we\nmarked all leak-free tests with \"TEST_PASSES_SANITIZE_LEAK=true\".\n\nSince then we've had various tests starting to pass under\nSANITIZE=leak. Let's mark those as passing, this is when they started\nto pass, narrowed down with \"git bisect\":\n\n- t5317-pack-objects-filter-objects.sh: In\n  faebba436e6 (list-objects-filter: plug pattern_list leak, 2022-12-01).\n\n- t3210-pack-refs.sh, t5613-info-alternate.sh,\n  t7403-submodule-sync.sh: In 189e97bc4ba (diff: remove parseopts member\n  from struct diff_options, 2022-12-01).\n\n- t1408-packed-refs.sh: In ab91f6b7c42 (Merge branch\n  'rs/diff-parseopts', 2022-12-19).\n\n- t0023-crlf-am.sh, t4152-am-subjects.sh, t4254-am-corrupt.sh,\n  t4256-am-format-flowed.sh, t4257-am-interactive.sh,\n  t5403-post-checkout-hook.sh: In a658e881c13 (am: don't pass strvec to\n  apply_parse_options(), 2022-12-13)\n\n- t1301-shared-repo.sh, t1302-repo-version.sh: In b07a819c05f (reflog:\n  clear leftovers in reflog_expiry_cleanup(), 2022-12-13).\n\n- t1304-default-acl.sh, t1410-reflog.sh,\n  t5330-no-lazy-fetch-with-commit-graph.sh, t5502-quickfetch.sh,\n  t5604-clone-reference.sh, t6014-rev-list-all.sh,\n  t7701-repack-unpack-unreachable.sh: In b0c61be3209 (Merge branch\n  'rs/reflog-expiry-cleanup', 2022-12-26)\n\n- t3800-mktag.sh, t5302-pack-index.sh, t5306-pack-nobase.sh,\n  t5573-pull-verify-signatures.sh, t7612-merge-verify-signatures.sh: In\n  69bbbe484ba (hash-object: use fsck for object checks, 2023-01-18).\n\n- t1451-fsck-buffer.sh: In 8e4309038f0 (fsck: do not assume\n  NUL-termination of buffers, 2023-01-19).\n\n- t6501-freshen-objects.sh: In abf2bb895b4 (Merge branch\n  'jk/hash-object-fsck', 2023-01-30)\n\n1. 9ea1378d046 (Merge branch 'ab/various-leak-fixes', 2022-12-14)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n t/t0023-crlf-am.sh                         | 1 +\n t/t1301-shared-repo.sh                     | 1 +\n t/t1302-repo-version.sh                    | 1 +\n t/t1304-default-acl.sh                     | 1 +\n t/t1408-packed-refs.sh                     | 1 +\n t/t1410-reflog.sh                          | 1 +\n t/t1451-fsck-buffer.sh                     | 2 ++\n t/t3210-pack-refs.sh                       | 1 +\n t/t3800-mktag.sh                           | 1 +\n t/t4152-am-subjects.sh                     | 2 ++\n t/t4254-am-corrupt.sh                      | 2 ++\n t/t4256-am-format-flowed.sh                | 1 +\n t/t4257-am-interactive.sh                  | 2 ++\n t/t5302-pack-index.sh                      | 2 ++\n t/t5306-pack-nobase.sh                     | 2 ++\n t/t5317-pack-objects-filter-objects.sh     | 1 +\n t/t5330-no-lazy-fetch-with-commit-graph.sh | 1 +\n t/t5403-post-checkout-hook.sh              | 1 +\n t/t5502-quickfetch.sh                      | 1 +\n t/t5573-pull-verify-signatures.sh          | 2 ++\n t/t5604-clone-reference.sh                 | 1 +\n t/t5613-info-alternate.sh                  | 2 ++\n t/t6014-rev-list-all.sh                    | 1 +\n t/t6021-rev-list-exclude-hidden.sh         | 1 +\n t/t6501-freshen-objects.sh                 | 1 +\n t/t7403-submodule-sync.sh                  | 1 +\n t/t7612-merge-verify-signatures.sh         | 1 +\n t/t7701-repack-unpack-unreachable.sh       | 1 +\n 28 files changed, 36 insertions(+)\n\ndiff --git a/t/t0023-crlf-am.sh b/t/t0023-crlf-am.sh\nindex f9bbb91f64e..575805513a3 100755\n--- a/t/t0023-crlf-am.sh\n+++ b/t/t0023-crlf-am.sh\n@@ -2,6 +2,7 @@\n \n test_description='Test am with auto.crlf'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n cat >patchfile <<\\EOF\ndiff --git a/t/t1301-shared-repo.sh b/t/t1301-shared-repo.sh\nindex 58d6da7feb1..1b6437ec079 100755\n--- a/t/t1301-shared-repo.sh\n+++ b/t/t1301-shared-repo.sh\n@@ -9,6 +9,7 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n TEST_CREATE_REPO_NO_TEMPLATE=1\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Remove a default ACL from the test dir if possible.\ndiff --git a/t/t1302-repo-version.sh b/t/t1302-repo-version.sh\nindex 7cf80bf66a6..70389fa2ebb 100755\n--- a/t/t1302-repo-version.sh\n+++ b/t/t1302-repo-version.sh\n@@ -5,6 +5,7 @@\n \n test_description='Test repository version check'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh\nindex c69ae41306c..31b89dd9693 100755\n--- a/t/t1304-default-acl.sh\n+++ b/t/t1304-default-acl.sh\n@@ -9,6 +9,7 @@ test_description='Test repository with default ACL'\n # => this must come before . ./test-lib.sh\n umask 077\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # We need an arbitrary other user give permission to using ACLs. root\ndiff --git a/t/t1408-packed-refs.sh b/t/t1408-packed-refs.sh\nindex 41ba1f1d7fc..9469c79a585 100755\n--- a/t/t1408-packed-refs.sh\n+++ b/t/t1408-packed-refs.sh\n@@ -5,6 +5,7 @@ test_description='packed-refs entries are covered by loose refs'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh\nindex aa59954f6c5..6c45965b1e4 100755\n--- a/t/t1410-reflog.sh\n+++ b/t/t1410-reflog.sh\n@@ -7,6 +7,7 @@ test_description='Test prune and reflog expiration'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n check_have () {\ndiff --git a/t/t1451-fsck-buffer.sh b/t/t1451-fsck-buffer.sh\nindex 9ac270abab6..3413da40e4a 100755\n--- a/t/t1451-fsck-buffer.sh\n+++ b/t/t1451-fsck-buffer.sh\n@@ -14,6 +14,8 @@ so.\n These tests _might_ catch such overruns in normal use, but should be run with\n ASan or valgrind for more confidence.\n '\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # the general idea for tags and commits is to build up the \"base\" file\ndiff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh\nindex 577f32dc71f..07a0ff93def 100755\n--- a/t/t3210-pack-refs.sh\n+++ b/t/t3210-pack-refs.sh\n@@ -12,6 +12,7 @@ semantic is still the same.\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'enable reflogs' '\ndiff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh\nindex e3cf0ffbe59..d3e428ff46e 100755\n--- a/t/t3800-mktag.sh\n+++ b/t/t3800-mktag.sh\n@@ -4,6 +4,7 @@\n \n test_description='git mktag: tag object verify test'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n ###########################################################\ndiff --git a/t/t4152-am-subjects.sh b/t/t4152-am-subjects.sh\nindex 4c68245acad..9f2edba1f83 100755\n--- a/t/t4152-am-subjects.sh\n+++ b/t/t4152-am-subjects.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test subject preservation with format-patch | am'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n make_patches() {\ndiff --git a/t/t4254-am-corrupt.sh b/t/t4254-am-corrupt.sh\nindex 54be7da1611..45f1d4f95e5 100755\n--- a/t/t4254-am-corrupt.sh\n+++ b/t/t4254-am-corrupt.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git am with corrupt input'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n make_mbox_with_nul () {\ndiff --git a/t/t4256-am-format-flowed.sh b/t/t4256-am-format-flowed.sh\nindex 2369c4e17ad..1015273bc82 100755\n--- a/t/t4256-am-format-flowed.sh\n+++ b/t/t4256-am-format-flowed.sh\n@@ -2,6 +2,7 @@\n \n test_description='test format=flowed support of git am'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t4257-am-interactive.sh b/t/t4257-am-interactive.sh\nindex aed8f4de3d6..f26d7fd2dbd 100755\n--- a/t/t4257-am-interactive.sh\n+++ b/t/t4257-am-interactive.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='am --interactive tests'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'set up patches to apply' '\ndiff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh\nindex 59e9e77223b..f89809be53c 100755\n--- a/t/t5302-pack-index.sh\n+++ b/t/t5302-pack-index.sh\n@@ -4,6 +4,8 @@\n #\n \n test_description='pack index with 64-bit offsets and object CRC'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t5306-pack-nobase.sh b/t/t5306-pack-nobase.sh\nindex 51973f4a512..846c5ca7d34 100755\n--- a/t/t5306-pack-nobase.sh\n+++ b/t/t5306-pack-nobase.sh\n@@ -6,6 +6,8 @@\n test_description='git-pack-object with missing base\n \n '\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Create A-B chain\ndiff --git a/t/t5317-pack-objects-filter-objects.sh b/t/t5317-pack-objects-filter-objects.sh\nindex 5b707d911b5..b26d476c646 100755\n--- a/t/t5317-pack-objects-filter-objects.sh\n+++ b/t/t5317-pack-objects-filter-objects.sh\n@@ -5,6 +5,7 @@ test_description='git pack-objects using object filtering'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Test blob:none filter.\ndiff --git a/t/t5330-no-lazy-fetch-with-commit-graph.sh b/t/t5330-no-lazy-fetch-with-commit-graph.sh\nindex 2cc7fd7a476..5eb28f0512d 100755\n--- a/t/t5330-no-lazy-fetch-with-commit-graph.sh\n+++ b/t/t5330-no-lazy-fetch-with-commit-graph.sh\n@@ -2,6 +2,7 @@\n \n test_description='test for no lazy fetch with the commit-graph'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup: prepare a repository with a commit' '\ndiff --git a/t/t5403-post-checkout-hook.sh b/t/t5403-post-checkout-hook.sh\nindex 978f240cdac..cfaae547398 100755\n--- a/t/t5403-post-checkout-hook.sh\n+++ b/t/t5403-post-checkout-hook.sh\n@@ -7,6 +7,7 @@ test_description='Test the post-checkout hook.'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5502-quickfetch.sh b/t/t5502-quickfetch.sh\nindex b160f8b7fb7..7b3ff21b984 100755\n--- a/t/t5502-quickfetch.sh\n+++ b/t/t5502-quickfetch.sh\n@@ -5,6 +5,7 @@ test_description='test quickfetch from local'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5573-pull-verify-signatures.sh b/t/t5573-pull-verify-signatures.sh\nindex a53dd8550d0..1221ac05978 100755\n--- a/t/t5573-pull-verify-signatures.sh\n+++ b/t/t5573-pull-verify-signatures.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='pull signature verification tests'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY/lib-gpg.sh\"\n \ndiff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh\nindex 2734e37e880..dc86dea1333 100755\n--- a/t/t5604-clone-reference.sh\n+++ b/t/t5604-clone-reference.sh\n@@ -7,6 +7,7 @@ test_description='test clone --reference'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n base_dir=$(pwd)\ndiff --git a/t/t5613-info-alternate.sh b/t/t5613-info-alternate.sh\nindex 895f46bb911..7708cbafa98 100755\n--- a/t/t5613-info-alternate.sh\n+++ b/t/t5613-info-alternate.sh\n@@ -4,6 +4,8 @@\n #\n \n test_description='test transitive info/alternate entries'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'preparing first repository' '\ndiff --git a/t/t6014-rev-list-all.sh b/t/t6014-rev-list-all.sh\nindex c9bedd29cba..16b8bd1d090 100755\n--- a/t/t6014-rev-list-all.sh\n+++ b/t/t6014-rev-list-all.sh\n@@ -2,6 +2,7 @@\n \n test_description='--all includes detached HEADs'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n \ndiff --git a/t/t6021-rev-list-exclude-hidden.sh b/t/t6021-rev-list-exclude-hidden.sh\nindex 32b2b094138..11c50b7c0dd 100755\n--- a/t/t6021-rev-list-exclude-hidden.sh\n+++ b/t/t6021-rev-list-exclude-hidden.sh\n@@ -2,6 +2,7 @@\n \n test_description='git rev-list --exclude-hidden test'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t6501-freshen-objects.sh b/t/t6501-freshen-objects.sh\nindex 10662456aee..3968b47ed53 100755\n--- a/t/t6501-freshen-objects.sh\n+++ b/t/t6501-freshen-objects.sh\n@@ -28,6 +28,7 @@ test_description='check pruning of dependent objects'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # We care about reachability, so we do not want to use\ndiff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh\nindex ea92ef52a5e..ff09443a0a4 100755\n--- a/t/t7403-submodule-sync.sh\n+++ b/t/t7403-submodule-sync.sh\n@@ -11,6 +11,7 @@ These tests exercise the \"git submodule sync\" subcommand.\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t7612-merge-verify-signatures.sh b/t/t7612-merge-verify-signatures.sh\nindex 61330f71b17..f5c90cc22a1 100755\n--- a/t/t7612-merge-verify-signatures.sh\n+++ b/t/t7612-merge-verify-signatures.sh\n@@ -4,6 +4,7 @@ test_description='merge signature verification tests'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY/lib-gpg.sh\"\n \ndiff --git a/t/t7701-repack-unpack-unreachable.sh b/t/t7701-repack-unpack-unreachable.sh\nindex b7ac4f598a8..ebb267855fe 100755\n--- a/t/t7701-repack-unpack-unreachable.sh\n+++ b/t/t7701-repack-unpack-unreachable.sh\n@@ -5,6 +5,7 @@ test_description='git repack works correctly'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n fsha1=\n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471641","messageId":"patch-v7-02.19-496bc2c46ce-20230206T230142Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"[PATCH v7 02/19] bundle.c: don't leak the \"args\" in the \"struct child_process\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:37Z","receivedAt":"2023-02-06T23:08:18Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a leak that's been here since 7366096de9d (bundle API: change\n\"flags\" to be \"extra_index_pack_args\", 2021-09-05). If we can't verify\nthe bundle, we didn't call child_process_clear() to clear the \"args\".\n\nBut rather than adding an additional child_process_clear() call, let's\nverify the bundle before we start preparing the process we're going to\nspawn. If we fail to verify, we don't need to push anything to the\nchild_process \"args\".\n\nHelped-by: Elijah Newren <newren@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n bundle.c | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/bundle.c b/bundle.c\nindex 4ef7256aa11..9ebb10a8f72 100644\n--- a/bundle.c\n+++ b/bundle.c\n@@ -627,6 +627,10 @@ int unbundle(struct repository *r, struct bundle_header *header,\n \t     enum verify_bundle_flags flags)\n {\n \tstruct child_process ip = CHILD_PROCESS_INIT;\n+\n+\tif (verify_bundle(r, header, flags))\n+\t\treturn -1;\n+\n \tstrvec_pushl(&ip.args, \"index-pack\", \"--fix-thin\", \"--stdin\", NULL);\n \n \t/* If there is a filter, then we need to create the promisor pack. */\n@@ -638,8 +642,6 @@ int unbundle(struct repository *r, struct bundle_header *header,\n \t\tstrvec_clear(extra_index_pack_args);\n \t}\n \n-\tif (verify_bundle(r, header, flags))\n-\t\treturn -1;\n \tip.in = bundle_fd;\n \tip.no_stdout = 1;\n \tip.git_cmd = 1;\n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471642","messageId":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com","subject":"[PATCH v7 00/19] leak fixes: various simple leak fixes","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:35Z","receivedAt":"2023-02-06T23:08:20Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"See\nhttps://lore.kernel.org/git/cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com/#t\nfor the v6. Changes since then:\n\n* Corrected the 17/19 commit message to note that it free()'s an\n  entire allocated struct, not just its \"flex\" member.\n\n* Per my replies on 18/19 and 19/19 in v6 I think those commit\n  messages are correct as-is, so sending this in in case Junio's OK\n  with picking up this version.\n\nCI & branch for this at:\nhttps://lore.kernel.org/git/cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com\n\nÆvar Arnfjörð Bjarmason (19):\n  tests: mark tests as passing with SANITIZE=leak\n  bundle.c: don't leak the \"args\" in the \"struct child_process\"\n  commit-graph: use free_commit_graph() instead of UNLEAK()\n  clone: use free() instead of UNLEAK()\n  various: add missing clear_pathspec(), fix leaks\n  name-rev: don't xstrdup() an already dup'd string\n  repack: fix leaks on error with \"goto cleanup\"\n  worktree: fix a trivial leak in prune_worktrees()\n  http-backend.c: fix \"dir\" and \"cmd_arg\" leaks in cmd_main()\n  http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()\n  commit-graph: fix a parse_options_concat() leak\n  show-branch: free() allocated \"head\" before return\n  builtin/merge.c: use fixed strings, not \"strbuf\", fix leak\n  builtin/merge.c: free \"&buf\" on \"Your local changes...\" error\n  grep.c: refactor free_grep_patterns()\n  grep API: plug memory leaks by freeing \"header_list\"\n  receive-pack: release the linked \"struct command *\" list\n  push: refactor refspec_append_mapped() for subsequent leak-fix\n  push: free_refs() the \"local_refs\" in set_refspecs()\n\n archive.c                                  |  1 +\n builtin/clean.c                            |  1 +\n builtin/clone.c                            |  5 ++--\n builtin/commit-graph.c                     | 10 +++++---\n builtin/merge.c                            | 14 +++++-----\n builtin/name-rev.c                         | 23 ++++++++---------\n builtin/push.c                             | 30 +++++++++++++---------\n builtin/receive-pack.c                     | 11 ++++++++\n builtin/repack.c                           | 13 +++++-----\n builtin/reset.c                            | 11 +++++---\n builtin/show-branch.c                      |  1 +\n builtin/stash.c                            |  7 +++--\n builtin/worktree.c                         |  6 ++---\n bundle.c                                   |  6 +++--\n grep.c                                     | 15 +++++++----\n http-backend.c                             |  9 +++++--\n t/t0023-crlf-am.sh                         |  1 +\n t/t1301-shared-repo.sh                     |  1 +\n t/t1302-repo-version.sh                    |  1 +\n t/t1304-default-acl.sh                     |  1 +\n t/t1408-packed-refs.sh                     |  1 +\n t/t1410-reflog.sh                          |  1 +\n t/t1416-ref-transaction-hooks.sh           |  1 +\n t/t1451-fsck-buffer.sh                     |  2 ++\n t/t2401-worktree-prune.sh                  |  1 +\n t/t2402-worktree-list.sh                   |  1 +\n t/t2406-worktree-repair.sh                 |  1 +\n t/t3210-pack-refs.sh                       |  1 +\n t/t3800-mktag.sh                           |  1 +\n t/t4152-am-subjects.sh                     |  2 ++\n t/t4254-am-corrupt.sh                      |  2 ++\n t/t4256-am-format-flowed.sh                |  1 +\n t/t4257-am-interactive.sh                  |  2 ++\n t/t5001-archive-attr.sh                    |  1 +\n t/t5004-archive-corner-cases.sh            |  2 ++\n t/t5302-pack-index.sh                      |  2 ++\n t/t5306-pack-nobase.sh                     |  2 ++\n t/t5312-prune-corruption.sh                |  1 +\n t/t5317-pack-objects-filter-objects.sh     |  1 +\n t/t5330-no-lazy-fetch-with-commit-graph.sh |  1 +\n t/t5403-post-checkout-hook.sh              |  1 +\n t/t5405-send-pack-rewind.sh                |  1 +\n t/t5406-remote-rejects.sh                  |  1 +\n t/t5502-quickfetch.sh                      |  1 +\n t/t5504-fetch-receive-strict.sh            |  1 +\n t/t5507-remote-environment.sh              |  2 ++\n t/t5522-pull-symlink.sh                    |  1 +\n t/t5523-push-upstream.sh                   |  1 +\n t/t5527-fetch-odd-refs.sh                  |  1 +\n t/t5529-push-errors.sh                     |  2 ++\n t/t5546-receive-limits.sh                  |  2 ++\n t/t5547-push-quarantine.sh                 |  2 ++\n t/t5560-http-backend-noserver.sh           |  1 +\n t/t5561-http-backend.sh                    |  1 +\n t/t5562-http-backend-content-length.sh     |  2 ++\n t/t5573-pull-verify-signatures.sh          |  2 ++\n t/t5604-clone-reference.sh                 |  1 +\n t/t5606-clone-options.sh                   |  1 +\n t/t5613-info-alternate.sh                  |  2 ++\n t/t5705-session-id-in-capabilities.sh      |  1 +\n t/t5810-proto-disable-local.sh             |  2 ++\n t/t5813-proto-disable-ssh.sh               |  2 ++\n t/t6011-rev-list-with-bad-commit.sh        |  1 +\n t/t6014-rev-list-all.sh                    |  1 +\n t/t6021-rev-list-exclude-hidden.sh         |  1 +\n t/t6439-merge-co-error-msgs.sh             |  1 +\n t/t6501-freshen-objects.sh                 |  1 +\n t/t7105-reset-patch.sh                     |  2 ++\n t/t7106-reset-unborn-branch.sh             |  2 ++\n t/t7107-reset-pathspec-file.sh             |  1 +\n t/t7301-clean-interactive.sh               |  1 +\n t/t7403-submodule-sync.sh                  |  1 +\n t/t7409-submodule-detached-work-tree.sh    |  1 +\n t/t7416-submodule-dash-url.sh              |  2 ++\n t/t7450-bad-git-dotfiles.sh                |  2 ++\n t/t7612-merge-verify-signatures.sh         |  1 +\n t/t7701-repack-unpack-unreachable.sh       |  1 +\n 77 files changed, 182 insertions(+), 62 deletions(-)\n\nRange-diff against v6:\n 1:  36da48d4db9 =  1:  ab180d78c7b tests: mark tests as passing with SANITIZE=leak\n 2:  f0f1a388350 =  2:  496bc2c46ce bundle.c: don't leak the \"args\" in the \"struct child_process\"\n 3:  cf0dddf4e8c =  3:  ea9ee63b37a commit-graph: use free_commit_graph() instead of UNLEAK()\n 4:  0430c1fec1b =  4:  56f9227c552 clone: use free() instead of UNLEAK()\n 5:  fb2d9875c73 =  5:  2b5dc52039b various: add missing clear_pathspec(), fix leaks\n 6:  bca659788de =  6:  67b8606c529 name-rev: don't xstrdup() an already dup'd string\n 7:  09950d92940 =  7:  95db54d24b0 repack: fix leaks on error with \"goto cleanup\"\n 8:  cd3eb9e68ff =  8:  81d97d03f42 worktree: fix a trivial leak in prune_worktrees()\n 9:  e80a719913b =  9:  e657992ad14 http-backend.c: fix \"dir\" and \"cmd_arg\" leaks in cmd_main()\n10:  9d9df0caf17 = 10:  1d8088dec84 http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()\n11:  65e25377791 = 11:  badf54d5240 commit-graph: fix a parse_options_concat() leak\n12:  3b1d47b9d62 = 12:  b8536257029 show-branch: free() allocated \"head\" before return\n13:  a85e5f3b14e = 13:  b33d61deaf9 builtin/merge.c: use fixed strings, not \"strbuf\", fix leak\n14:  7dbc422d5b4 = 14:  c1223aad2ae builtin/merge.c: free \"&buf\" on \"Your local changes...\" error\n15:  aa51668b70d = 15:  e2bf3245dd0 grep.c: refactor free_grep_patterns()\n16:  0c51ea7fd2d = 16:  2aea4017491 grep API: plug memory leaks by freeing \"header_list\"\n17:  4b2db91f5cb ! 17:  b02ece0d36b receive-pack: free() the \"ref_name\" in \"struct command\"\n    @@ Metadata\n     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## Commit message ##\n    -    receive-pack: free() the \"ref_name\" in \"struct command\"\n    +    receive-pack: release the linked \"struct command *\" list\n     \n         Fix a memory leak that's been with us since this code was introduced\n    -    in 575f497456e (Add first cut at \"git-receive-pack\", 2005-06-29). See\n    -    eb1af2df0b1 (git-receive-pack: start parsing ref update commands,\n    -    2005-06-29) for the later change that refactored the code to add the\n    -    \"ref_name\" member.\n    +    in [1]. Later in [2] we started using FLEX_ALLOC_MEM() to allocate the\n    +    \"struct command *\".\n    +\n    +    1. 575f497456e (Add first cut at \"git-receive-pack\", 2005-06-29)\n    +    2. eb1af2df0b1 (git-receive-pack: start parsing ref update commands,\n    +       2005-06-29)\n     \n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n    @@ builtin/receive-pack.c: static struct command **queue_command(struct command **t\n     +{\n     +\twhile (commands) {\n     +\t\tstruct command *next = commands->next;\n    ++\n     +\t\tfree(commands);\n     +\t\tcommands = next;\n     +\t}\n18:  aa33f7e05c8 = 18:  d28b710c0ba push: refactor refspec_append_mapped() for subsequent leak-fix\n19:  67076dfba6d = 19:  ba8e5496d96 push: free_refs() the \"local_refs\" in set_refspecs()\n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471643","messageId":"patch-v7-03.19-ea9ee63b37a-20230206T230142Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"[PATCH v7 03/19] commit-graph: use free_commit_graph() instead of UNLEAK()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:38Z","receivedAt":"2023-02-06T23:08:21Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"In 0bfb48e6723 (builtin/commit-graph.c: UNLEAK variables, 2018-10-03)\nthis was made to UNLEAK(), but we can just as easily invoke the\nfree_commit_graph() function added in c3756d5b7fc (commit-graph: add\nfree_commit_graph, 2018-07-11) instead.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/commit-graph.c | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/commit-graph.c b/builtin/commit-graph.c\nindex e8f77f535f3..0102ac8540e 100644\n--- a/builtin/commit-graph.c\n+++ b/builtin/commit-graph.c\n@@ -67,6 +67,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix)\n \tint fd;\n \tstruct stat st;\n \tint flags = 0;\n+\tint ret;\n \n \tstatic struct option builtin_commit_graph_verify_options[] = {\n \t\tOPT_BOOL(0, \"shallow\", &opts.shallow,\n@@ -111,8 +112,9 @@ static int graph_verify(int argc, const char **argv, const char *prefix)\n \tif (!graph)\n \t\treturn !!open_ok;\n \n-\tUNLEAK(graph);\n-\treturn verify_commit_graph(the_repository, graph, flags);\n+\tret = verify_commit_graph(the_repository, graph, flags);\n+\tfree_commit_graph(graph);\n+\treturn ret;\n }\n \n extern int read_replace_refs;\n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471644","messageId":"patch-v7-04.19-56f9227c552-20230206T230142Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"[PATCH v7 04/19] clone: use free() instead of UNLEAK()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:39Z","receivedAt":"2023-02-06T23:08:24Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change an UNLEAK() added in 0c4542738e6 (clone: free or UNLEAK further\npointers when finished, 2021-03-14) to use a \"to_free\" pattern\ninstead. In this case the \"repo\" can be either this absolute_pathdup()\nvalue, or in the \"else if\" branch seen in the context the the\n\"argv[0]\" argument to \"main()\".\n\nWe can only free() the value in the former case, hence the \"to_free\"\npattern.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/clone.c | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 5453ba5277f..ba82f5e4108 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -892,6 +892,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tint is_bundle = 0, is_local;\n \tint reject_shallow = 0;\n \tconst char *repo_name, *repo, *work_tree, *git_dir;\n+\tchar *repo_to_free = NULL;\n \tchar *path = NULL, *dir, *display_repo = NULL;\n \tint dest_exists, real_dest_exists = 0;\n \tconst struct ref *refs, *remote_head;\n@@ -949,7 +950,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tpath = get_repo_path(repo_name, &is_bundle);\n \tif (path) {\n \t\tFREE_AND_NULL(path);\n-\t\trepo = absolute_pathdup(repo_name);\n+\t\trepo = repo_to_free = absolute_pathdup(repo_name);\n \t} else if (strchr(repo_name, ':')) {\n \t\trepo = repo_name;\n \t\tdisplay_repo = transport_anonymize_url(repo);\n@@ -1413,7 +1414,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tfree(unborn_head);\n \tfree(dir);\n \tfree(path);\n-\tUNLEAK(repo);\n+\tfree(repo_to_free);\n \tjunk_mode = JUNK_LEAVE_ALL;\n \n \ttransport_ls_refs_options_release(&transport_ls_refs_options);\n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471645","messageId":"patch-v7-06.19-67b8606c529-20230206T230142Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"[PATCH v7 06/19] name-rev: don't xstrdup() an already dup'd string","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:41Z","receivedAt":"2023-02-06T23:08:25Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When \"add_to_tip_table()\" is called with a non-zero\n\"shorten_unambiguous\" we always return an xstrdup()'d string, which\nwe'd then xstrdup() again, leaking memory. See [1] and [2] for how\nthis leak came about.\n\nWe could xstrdup() only if \"shorten_unambiguous\" wasn't true, but\nlet's instead inline this code, so that information on whether we need\nto xstrdup() is contained within add_to_tip_table().\n\n1. 98c5c4ad015 (name-rev: allow to specify a subpath for --refs\n   option, 2013-06-18)\n2. b23e0b9353e (name-rev: allow converting the exact object name at\n   the tip of a ref, 2013-07-07)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/name-rev.c | 23 ++++++++++-------------\n 1 file changed, 10 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin/name-rev.c b/builtin/name-rev.c\nindex 15535e914a6..49fae523694 100644\n--- a/builtin/name-rev.c\n+++ b/builtin/name-rev.c\n@@ -273,17 +273,6 @@ static int subpath_matches(const char *path, const char *filter)\n \treturn -1;\n }\n \n-static const char *name_ref_abbrev(const char *refname, int shorten_unambiguous)\n-{\n-\tif (shorten_unambiguous)\n-\t\trefname = shorten_unambiguous_ref(refname, 0);\n-\telse if (skip_prefix(refname, \"refs/heads/\", &refname))\n-\t\t; /* refname already advanced */\n-\telse\n-\t\tskip_prefix(refname, \"refs/\", &refname);\n-\treturn refname;\n-}\n-\n struct name_ref_data {\n \tint tags_only;\n \tint name_only;\n@@ -309,11 +298,19 @@ static void add_to_tip_table(const struct object_id *oid, const char *refname,\n \t\t\t     int shorten_unambiguous, struct commit *commit,\n \t\t\t     timestamp_t taggerdate, int from_tag, int deref)\n {\n-\trefname = name_ref_abbrev(refname, shorten_unambiguous);\n+\tchar *short_refname = NULL;\n+\n+\tif (shorten_unambiguous)\n+\t\tshort_refname = shorten_unambiguous_ref(refname, 0);\n+\telse if (skip_prefix(refname, \"refs/heads/\", &refname))\n+\t\t; /* refname already advanced */\n+\telse\n+\t\tskip_prefix(refname, \"refs/\", &refname);\n \n \tALLOC_GROW(tip_table.table, tip_table.nr + 1, tip_table.alloc);\n \toidcpy(&tip_table.table[tip_table.nr].oid, oid);\n-\ttip_table.table[tip_table.nr].refname = xstrdup(refname);\n+\ttip_table.table[tip_table.nr].refname = short_refname ?\n+\t\tshort_refname : xstrdup(refname);\n \ttip_table.table[tip_table.nr].commit = commit;\n \ttip_table.table[tip_table.nr].taggerdate = taggerdate;\n \ttip_table.table[tip_table.nr].from_tag = from_tag;\n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471646","messageId":"patch-v7-05.19-2b5dc52039b-20230206T230142Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"[PATCH v7 05/19] various: add missing clear_pathspec(), fix leaks","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:40Z","receivedAt":"2023-02-06T23:08:30Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix memory leaks resulting from a missing clear_pathspec().\n\n- archive.c: Plug a leak in the \"struct archiver_args\", and\n  clear_pathspec() the \"pathspec\" member that the \"parse_pathspec_arg()\"\n  call in this function populates.\n\n- builtin/clean.c: Fix a memory leak that's been with us since\n  893d839970c (clean: convert to use parse_pathspec, 2013-07-14).\n\n- builtin/reset.c: Add clear_pathspec() calls to cmd_reset(),\n  including to the codepaths where we'd return early.\n\n- builtin/stash.c: Call clear_pathspec() on the pathspec initialized\n  in push_stash().\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n archive.c                       |  1 +\n builtin/clean.c                 |  1 +\n builtin/reset.c                 | 11 ++++++++---\n builtin/stash.c                 |  7 +++++--\n t/t5001-archive-attr.sh         |  1 +\n t/t5004-archive-corner-cases.sh |  2 ++\n t/t7105-reset-patch.sh          |  2 ++\n t/t7106-reset-unborn-branch.sh  |  2 ++\n t/t7107-reset-pathspec-file.sh  |  1 +\n t/t7301-clean-interactive.sh    |  1 +\n 10 files changed, 24 insertions(+), 5 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex 81ff76fce99..f2a8756d84f 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -710,6 +710,7 @@ int write_archive(int argc, const char **argv, const char *prefix,\n \n \tstring_list_clear_func(&args.extra_files, extra_file_info_clear);\n \tfree(args.refname);\n+\tclear_pathspec(&args.pathspec);\n \n \treturn rc;\n }\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex b2701a28158..b15eab328b7 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -1092,5 +1092,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tstrbuf_release(&buf);\n \tstring_list_clear(&del_list, 0);\n \tstring_list_clear(&exclude_list, 0);\n+\tclear_pathspec(&pathspec);\n \treturn (errors != 0);\n }\ndiff --git a/builtin/reset.c b/builtin/reset.c\nindex fea20a9ba0b..e9c10618cd3 100644\n--- a/builtin/reset.c\n+++ b/builtin/reset.c\n@@ -390,7 +390,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \t\tif (reset_type != NONE)\n \t\t\tdie(_(\"options '%s' and '%s' cannot be used together\"), \"--patch\", \"--{hard,mixed,soft}\");\n \t\ttrace2_cmd_mode(\"patch-interactive\");\n-\t\treturn run_add_interactive(rev, \"--patch=reset\", &pathspec);\n+\t\tupdate_ref_status = run_add_interactive(rev, \"--patch=reset\", &pathspec);\n+\t\tgoto cleanup;\n \t}\n \n \t/* git reset tree [--] paths... can be used to\n@@ -439,8 +440,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \t\t\t\t       LOCK_DIE_ON_ERROR);\n \t\tif (reset_type == MIXED) {\n \t\t\tint flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;\n-\t\t\tif (read_from_tree(&pathspec, &oid, intent_to_add))\n-\t\t\t\treturn 1;\n+\t\t\tif (read_from_tree(&pathspec, &oid, intent_to_add)) {\n+\t\t\t\tupdate_ref_status = 1;\n+\t\t\t\tgoto cleanup;\n+\t\t\t}\n \t\t\tthe_index.updated_skipworktree = 1;\n \t\t\tif (!no_refresh && get_git_work_tree()) {\n \t\t\t\tuint64_t t_begin, t_delta_in_ms;\n@@ -488,5 +491,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)\n \n \tdiscard_index(&the_index);\n \n+cleanup:\n+\tclear_pathspec(&pathspec);\n \treturn update_ref_status;\n }\ndiff --git a/builtin/stash.c b/builtin/stash.c\nindex 839569a9803..71a4ee6b1a5 100644\n--- a/builtin/stash.c\n+++ b/builtin/stash.c\n@@ -1727,6 +1727,7 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n \t\tOPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),\n \t\tOPT_END()\n \t};\n+\tint ret;\n \n \tif (argc) {\n \t\tforce_assume = !strcmp(argv[0], \"-p\");\n@@ -1766,8 +1767,10 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n \t\tdie(_(\"the option '%s' requires '%s'\"), \"--pathspec-file-nul\", \"--pathspec-from-file\");\n \t}\n \n-\treturn do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n-\t\t\t     include_untracked, only_staged);\n+\tret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,\n+\t\t\t    include_untracked, only_staged);\n+\tclear_pathspec(&ps);\n+\treturn ret;\n }\n \n static int push_stash_unassumed(int argc, const char **argv, const char *prefix)\ndiff --git a/t/t5001-archive-attr.sh b/t/t5001-archive-attr.sh\nindex 2f6eef5e372..04d300eeda7 100755\n--- a/t/t5001-archive-attr.sh\n+++ b/t/t5001-archive-attr.sh\n@@ -3,6 +3,7 @@\n test_description='git archive attribute tests'\n \n TEST_CREATE_REPO_NO_TEMPLATE=1\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n SUBSTFORMAT='%H (%h)%n'\ndiff --git a/t/t5004-archive-corner-cases.sh b/t/t5004-archive-corner-cases.sh\nindex ae508e21623..9f2c6da80e8 100755\n--- a/t/t5004-archive-corner-cases.sh\n+++ b/t/t5004-archive-corner-cases.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test corner cases of git-archive'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # the 10knuls.tar file is used to test for an empty git generated tar\ndiff --git a/t/t7105-reset-patch.sh b/t/t7105-reset-patch.sh\nindex fc2a6cf5c7a..9b46da7aaa7 100755\n--- a/t/t7105-reset-patch.sh\n+++ b/t/t7105-reset-patch.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git reset --patch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./lib-patch-mode.sh\n \n test_expect_success PERL 'setup' '\ndiff --git a/t/t7106-reset-unborn-branch.sh b/t/t7106-reset-unborn-branch.sh\nindex ecb85c3b823..a0b67a0b843 100755\n--- a/t/t7106-reset-unborn-branch.sh\n+++ b/t/t7106-reset-unborn-branch.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='git reset should work on unborn branch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7107-reset-pathspec-file.sh b/t/t7107-reset-pathspec-file.sh\nindex 523efbecde1..af5ea406db3 100755\n--- a/t/t7107-reset-pathspec-file.sh\n+++ b/t/t7107-reset-pathspec-file.sh\n@@ -2,6 +2,7 @@\n \n test_description='reset --pathspec-from-file'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_tick\ndiff --git a/t/t7301-clean-interactive.sh b/t/t7301-clean-interactive.sh\nindex a07e8b86de2..d82a3210a1d 100755\n--- a/t/t7301-clean-interactive.sh\n+++ b/t/t7301-clean-interactive.sh\n@@ -2,6 +2,7 @@\n \n test_description='git clean -i basic tests'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-terminal.sh\n \n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471647","messageId":"patch-v7-07.19-95db54d24b0-20230206T230142Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"[PATCH v7 07/19] repack: fix leaks on error with \"goto cleanup\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:42Z","receivedAt":"2023-02-06T23:08:32Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"In cmd_repack() when we hit an error, replace \"return ret\" with \"goto\ncleanup\" to ensure we free the necessary data structures.\n\nHelped-by: Elijah Newren <newren@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/repack.c                    | 13 +++++++------\n t/t5312-prune-corruption.sh         |  1 +\n t/t6011-rev-list-with-bad-commit.sh |  1 +\n 3 files changed, 9 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/repack.c b/builtin/repack.c\nindex c1402ad038f..f6493795318 100644\n--- a/builtin/repack.c\n+++ b/builtin/repack.c\n@@ -948,7 +948,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \n \tret = start_command(&cmd);\n \tif (ret)\n-\t\treturn ret;\n+\t\tgoto cleanup;\n \n \tif (geometry) {\n \t\tFILE *in = xfdopen(cmd.in, \"w\");\n@@ -977,7 +977,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \tfclose(out);\n \tret = finish_command(&cmd);\n \tif (ret)\n-\t\treturn ret;\n+\t\tgoto cleanup;\n \n \tif (!names.nr && !po_args.quiet)\n \t\tprintf_ln(_(\"Nothing new to pack.\"));\n@@ -1007,7 +1007,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\t\t\t       &existing_nonkept_packs,\n \t\t\t\t       &existing_kept_packs);\n \t\tif (ret)\n-\t\t\treturn ret;\n+\t\t\tgoto cleanup;\n \n \t\tif (delete_redundant && expire_to) {\n \t\t\t/*\n@@ -1039,7 +1039,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\t\t\t\t       &existing_nonkept_packs,\n \t\t\t\t\t       &existing_kept_packs);\n \t\t\tif (ret)\n-\t\t\t\treturn ret;\n+\t\t\t\tgoto cleanup;\n \t\t}\n \t}\n \n@@ -1115,7 +1115,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\tstring_list_clear(&include, 0);\n \n \t\tif (ret)\n-\t\t\treturn ret;\n+\t\t\tgoto cleanup;\n \t}\n \n \treprepare_packed_git(the_repository);\n@@ -1172,10 +1172,11 @@ int cmd_repack(int argc, const char **argv, const char *prefix)\n \t\twrite_midx_file(get_object_directory(), NULL, NULL, flags);\n \t}\n \n+cleanup:\n \tstring_list_clear(&names, 1);\n \tstring_list_clear(&existing_nonkept_packs, 0);\n \tstring_list_clear(&existing_kept_packs, 0);\n \tclear_pack_geometry(geometry);\n \n-\treturn 0;\n+\treturn ret;\n }\ndiff --git a/t/t5312-prune-corruption.sh b/t/t5312-prune-corruption.sh\nindex 9d8e249ae8b..230cb387122 100755\n--- a/t/t5312-prune-corruption.sh\n+++ b/t/t5312-prune-corruption.sh\n@@ -14,6 +14,7 @@ what currently happens. If that changes, these tests should be revisited.\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'disable reflogs' '\ndiff --git a/t/t6011-rev-list-with-bad-commit.sh b/t/t6011-rev-list-with-bad-commit.sh\nindex bad02cf5b83..b2e422cf0f7 100755\n--- a/t/t6011-rev-list-with-bad-commit.sh\n+++ b/t/t6011-rev-list-with-bad-commit.sh\n@@ -2,6 +2,7 @@\n \n test_description='git rev-list should notice bad commits'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Note:\n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471648","messageId":"patch-v7-08.19-81d97d03f42-20230206T230142Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"[PATCH v7 08/19] worktree: fix a trivial leak in prune_worktrees()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:43Z","receivedAt":"2023-02-06T23:08:33Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"We were leaking both the \"struct strbuf\" in prune_worktrees(), as well\nas the \"path\" we got from should_prune_worktree(). Since these were\nthe only two uses of the \"struct string_list\" let's change it to a\n\"DUP\" and push these to it with \"string_list_append_nodup()\".\n\nFor the string_list_append_nodup() we could also string_list_append()\nthe main_path.buf, and then strbuf_release(&main_path) right away. But\ndoing it this way avoids an allocation, as we already have the \"struct\nstrbuf\" prepared for appending to \"kept\".\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/worktree.c         | 6 +++---\n t/t2401-worktree-prune.sh  | 1 +\n t/t2406-worktree-repair.sh | 1 +\n 3 files changed, 5 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex f51c40f1e1e..254283aa6f5 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -173,7 +173,7 @@ static void prune_worktrees(void)\n {\n \tstruct strbuf reason = STRBUF_INIT;\n \tstruct strbuf main_path = STRBUF_INIT;\n-\tstruct string_list kept = STRING_LIST_INIT_NODUP;\n+\tstruct string_list kept = STRING_LIST_INIT_DUP;\n \tDIR *dir = opendir(git_path(\"worktrees\"));\n \tstruct dirent *d;\n \tif (!dir)\n@@ -184,14 +184,14 @@ static void prune_worktrees(void)\n \t\tif (should_prune_worktree(d->d_name, &reason, &path, expire))\n \t\t\tprune_worktree(d->d_name, reason.buf);\n \t\telse if (path)\n-\t\t\tstring_list_append(&kept, path)->util = xstrdup(d->d_name);\n+\t\t\tstring_list_append_nodup(&kept, path)->util = xstrdup(d->d_name);\n \t}\n \tclosedir(dir);\n \n \tstrbuf_add_absolute_path(&main_path, get_git_common_dir());\n \t/* massage main worktree absolute path to match 'gitdir' content */\n \tstrbuf_strip_suffix(&main_path, \"/.\");\n-\tstring_list_append(&kept, strbuf_detach(&main_path, NULL));\n+\tstring_list_append_nodup(&kept, strbuf_detach(&main_path, NULL));\n \tprune_dups(&kept);\n \tstring_list_clear(&kept, 1);\n \ndiff --git a/t/t2401-worktree-prune.sh b/t/t2401-worktree-prune.sh\nindex 3d28c7f06b2..568a47ec426 100755\n--- a/t/t2401-worktree-prune.sh\n+++ b/t/t2401-worktree-prune.sh\n@@ -5,6 +5,7 @@ test_description='prune $GIT_DIR/worktrees'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success initialize '\ndiff --git a/t/t2406-worktree-repair.sh b/t/t2406-worktree-repair.sh\nindex 5c44453e1c1..8970780efcc 100755\n--- a/t/t2406-worktree-repair.sh\n+++ b/t/t2406-worktree-repair.sh\n@@ -2,6 +2,7 @@\n \n test_description='test git worktree repair'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471649","messageId":"patch-v7-09.19-e657992ad14-20230206T230142Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"[PATCH v7 09/19] http-backend.c: fix \"dir\" and \"cmd_arg\" leaks in cmd_main()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:44Z","receivedAt":"2023-02-06T23:08:35Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Free the \"dir\" variable after we're done with it. Before\n917adc03608 (http-backend: add GIT_PROJECT_ROOT environment var,\n2009-10-30) there was no leak here, as we'd get it via getenv(), but\nsince 917adc03608 we've xstrdup()'d it (or the equivalent), so we need\nto free() it.\n\nWe also need to free the \"cmd_arg\" variable, which has been leaked\never since it was added in 2f4038ab337 (Git-aware CGI to provide dumb\nHTTP transport, 2009-10-30).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n http-backend.c | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git a/http-backend.c b/http-backend.c\nindex 6eb3b2fe51c..67819d931ce 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -786,6 +786,7 @@ int cmd_main(int argc, const char **argv)\n \tif (!getenv(\"GIT_HTTP_EXPORT_ALL\") &&\n \t    access(\"git-daemon-export-ok\", F_OK) )\n \t\tnot_found(&hdr, \"Repository not exported: '%s'\", dir);\n+\tfree(dir);\n \n \thttp_config();\n \tmax_request_buffer = git_env_ulong(\"GIT_HTTP_MAX_REQUEST_BUFFER\",\n@@ -795,5 +796,6 @@ int cmd_main(int argc, const char **argv)\n \t\tsetenv(GIT_PROTOCOL_ENVIRONMENT, proto_header, 0);\n \n \tcmd->imp(&hdr, cmd_arg);\n+\tfree(cmd_arg);\n \treturn 0;\n }\n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471650","messageId":"patch-v7-11.19-badf54d5240-20230206T230142Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"[PATCH v7 11/19] commit-graph: fix a parse_options_concat() leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:46Z","receivedAt":"2023-02-06T23:08:41Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the parse_options_concat() was added to this file in\n84e4484f128 (commit-graph: use parse_options_concat(), 2021-08-23) we\nwouldn't free() it if we returned early in these cases.\n\nSince \"result\" is 0 by default we can \"goto cleanup\" in both cases,\nand only need to set \"result\" if write_commit_graph_reachable() fails.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/commit-graph.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/commit-graph.c b/builtin/commit-graph.c\nindex 0102ac8540e..93704f95a9d 100644\n--- a/builtin/commit-graph.c\n+++ b/builtin/commit-graph.c\n@@ -269,8 +269,8 @@ static int graph_write(int argc, const char **argv, const char *prefix)\n \n \tif (opts.reachable) {\n \t\tif (write_commit_graph_reachable(odb, flags, &write_opts))\n-\t\t\treturn 1;\n-\t\treturn 0;\n+\t\t\tresult = 1;\n+\t\tgoto cleanup;\n \t}\n \n \tif (opts.stdin_packs) {\n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471651","messageId":"patch-v7-10.19-1d8088dec84-20230206T230142Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"[PATCH v7 10/19] http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:45Z","receivedAt":"2023-02-06T23:08:48Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us ever since\n2f4038ab337 (Git-aware CGI to provide dumb HTTP transport,\n2009-10-30). In this case we're not calling regerror() after a failed\nregexec(), and don't otherwise use \"re\" afterwards.\n\nWe can therefore simplify this code by calling regfree() right after\nthe regexec(). An alternative fix would be to add a regfree() to both\nthe \"return\" and \"break\" path in this for-loop.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n http-backend.c | 7 +++++--\n 1 file changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/http-backend.c b/http-backend.c\nindex 67819d931ce..8ab58e55f85 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -759,10 +759,14 @@ int cmd_main(int argc, const char **argv)\n \t\tstruct service_cmd *c = &services[i];\n \t\tregex_t re;\n \t\tregmatch_t out[1];\n+\t\tint ret;\n \n \t\tif (regcomp(&re, c->pattern, REG_EXTENDED))\n \t\t\tdie(\"Bogus regex in service table: %s\", c->pattern);\n-\t\tif (!regexec(&re, dir, 1, out, 0)) {\n+\t\tret = regexec(&re, dir, 1, out, 0);\n+\t\tregfree(&re);\n+\n+\t\tif (!ret) {\n \t\t\tsize_t n;\n \n \t\t\tif (strcmp(method, c->method))\n@@ -774,7 +778,6 @@ int cmd_main(int argc, const char **argv)\n \t\t\tdir[out[0].rm_so] = 0;\n \t\t\tbreak;\n \t\t}\n-\t\tregfree(&re);\n \t}\n \n \tif (!cmd)\n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471652","messageId":"patch-v7-12.19-b8536257029-20230206T230142Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"[PATCH v7 12/19] show-branch: free() allocated \"head\" before return","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:47Z","receivedAt":"2023-02-06T23:08:50Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Stop leaking the \"head\" variable, which we've been leaking since it\nwas originally added in [1], and in its current form since [2]\n\n1. ed378ec7e85 (Make ref resolution saner, 2006-09-11)\n2. d9e557a320b (show-branch: store resolved head in heap buffer,\n   2017-02-14).\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/show-branch.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/show-branch.c b/builtin/show-branch.c\nindex c013abaf942..358ac3e519a 100644\n--- a/builtin/show-branch.c\n+++ b/builtin/show-branch.c\n@@ -956,5 +956,6 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)\n \t\tif (shown_merge_point && --extra < 0)\n \t\t\tbreak;\n \t}\n+\tfree(head);\n \treturn 0;\n }\n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471653","messageId":"patch-v7-13.19-b33d61deaf9-20230206T230142Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"[PATCH v7 13/19] builtin/merge.c: use fixed strings, not \"strbuf\", fix leak","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:48Z","receivedAt":"2023-02-06T23:08:57Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Follow-up 465028e0e25 (merge: add missing strbuf_release(),\n2021-10-07) and address the \"msg\" memory leak in this block. We could\nfree \"&msg\" before the \"goto done\" here, but even better is to avoid\nallocating it in the first place.\n\nBy repeating the \"Fast-forward\" string here we can avoid using a\n\"struct strbuf\" altogether.\n\nSuggested-by: René Scharfe <l.s.r@web.de>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/merge.c                | 11 ++++-------\n t/t6439-merge-co-error-msgs.sh |  1 +\n 2 files changed, 5 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 74de2ebd2b3..32733e551d4 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -1560,7 +1560,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t!common->next &&\n \t\t\toideq(&common->item->object.oid, &head_commit->object.oid)) {\n \t\t/* Again the most common case of merging one remote. */\n-\t\tstruct strbuf msg = STRBUF_INIT;\n+\t\tconst char *msg = have_message ?\n+\t\t\t\"Fast-forward (no commit created; -m option ignored)\" :\n+\t\t\t\"Fast-forward\";\n \t\tstruct commit *commit;\n \n \t\tif (verbosity >= 0) {\n@@ -1570,10 +1572,6 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t       find_unique_abbrev(&remoteheads->item->object.oid,\n \t\t\t\t\t\t  DEFAULT_ABBREV));\n \t\t}\n-\t\tstrbuf_addstr(&msg, \"Fast-forward\");\n-\t\tif (have_message)\n-\t\t\tstrbuf_addstr(&msg,\n-\t\t\t\t\" (no commit created; -m option ignored)\");\n \t\tcommit = remoteheads->item;\n \t\tif (!commit) {\n \t\t\tret = 1;\n@@ -1592,9 +1590,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\tgoto done;\n \t\t}\n \n-\t\tfinish(head_commit, remoteheads, &commit->object.oid, msg.buf);\n+\t\tfinish(head_commit, remoteheads, &commit->object.oid, msg);\n \t\tremove_merge_branch_state(the_repository);\n-\t\tstrbuf_release(&msg);\n \t\tgoto done;\n \t} else if (!remoteheads->next && common->next)\n \t\t;\ndiff --git a/t/t6439-merge-co-error-msgs.sh b/t/t6439-merge-co-error-msgs.sh\nindex 52cf0c87690..0cbec57cdab 100755\n--- a/t/t6439-merge-co-error-msgs.sh\n+++ b/t/t6439-merge-co-error-msgs.sh\n@@ -5,6 +5,7 @@ test_description='unpack-trees error messages'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n \n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471654","messageId":"patch-v7-15.19-e2bf3245dd0-20230206T230142Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"[PATCH v7 15/19] grep.c: refactor free_grep_patterns()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:50Z","receivedAt":"2023-02-06T23:08:58Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Refactor the free_grep_patterns() function to split out the freeing of\nthe \"struct grep_pat\" it contains. Right now we're only freeing the\n\"pattern_list\", but we should be freeing another member of the same\ntype, which we'll do in the subsequent commit.\n\nLet's also replace the \"return\" if we don't have an\n\"opt->pattern_expression\" with a conditional call of\nfree_pattern_expr().\n\nBefore db84376f981 (grep.c: remove \"extended\" in favor of\n\"pattern_expression\", fix segfault, 2022-10-11) the pattern here was:\n\n\tif (!x)\n\t\treturn;\n\tfree_pattern_expr(y);\n\nWhile at it, instead of:\n\n\tif (!x)\n\t\treturn;\n\tfree_pattern_expr(x);\n\nLet's instead do:\n\n\tif (x)\n\t\tfree_pattern_expr(x);\n\nThis will make it easier to free additional members from\nfree_grep_patterns() in the future.\n\nHelped-by: Elijah Newren <newren@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n grep.c | 14 +++++++++-----\n 1 file changed, 9 insertions(+), 5 deletions(-)\n\ndiff --git a/grep.c b/grep.c\nindex 1687f65b64f..f8708e1fd20 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -769,11 +769,11 @@ static void free_pattern_expr(struct grep_expr *x)\n \tfree(x);\n }\n \n-void free_grep_patterns(struct grep_opt *opt)\n+static void free_grep_pat(struct grep_pat *pattern)\n {\n \tstruct grep_pat *p, *n;\n \n-\tfor (p = opt->pattern_list; p; p = n) {\n+\tfor (p = pattern; p; p = n) {\n \t\tn = p->next;\n \t\tswitch (p->token) {\n \t\tcase GREP_PATTERN: /* atom */\n@@ -790,10 +790,14 @@ void free_grep_patterns(struct grep_opt *opt)\n \t\t}\n \t\tfree(p);\n \t}\n+}\n \n-\tif (!opt->pattern_expression)\n-\t\treturn;\n-\tfree_pattern_expr(opt->pattern_expression);\n+void free_grep_patterns(struct grep_opt *opt)\n+{\n+\tfree_grep_pat(opt->pattern_list);\n+\n+\tif (opt->pattern_expression)\n+\t\tfree_pattern_expr(opt->pattern_expression);\n }\n \n static const char *end_of_line(const char *cp, unsigned long *left)\n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471655","messageId":"patch-v7-14.19-c1223aad2ae-20230206T230142Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"[PATCH v7 14/19] builtin/merge.c: free \"&buf\" on \"Your local changes...\" error","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:49Z","receivedAt":"2023-02-06T23:09:01Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Plug a memory leak introduced in [1], since that change didn't follow\nthe \"goto done\" pattern introduced in [2] we'd leak the \"&buf\" memory.\n\n1. e4cdfe84a0d (merge: abort if index does not match HEAD for trivial\n   merges, 2022-07-23)\n2. d5a35c114ab (Copy resolve_ref() return value for longer use,\n   2011-11-13)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/merge.c | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 32733e551d4..5a834b1f291 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -1618,7 +1618,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t\terror(_(\"Your local changes to the following files would be overwritten by merge:\\n  %s\"),\n \t\t\t\t      sb.buf);\n \t\t\t\tstrbuf_release(&sb);\n-\t\t\t\treturn 2;\n+\t\t\t\tret = 2;\n+\t\t\t\tgoto done;\n \t\t\t}\n \n \t\t\t/* See if it is really trivial. */\n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471656","messageId":"patch-v7-16.19-2aea4017491-20230206T230142Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"[PATCH v7 16/19] grep API: plug memory leaks by freeing \"header_list\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:51Z","receivedAt":"2023-02-06T23:09:12Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"When the \"header_list\" struct member was added in [1], freeing this\nfield was neglected. Fix that now, so that commands like\n\n\t./git -P log -1 --color=always --author=A origin/master\n\nwill run leak-free.\n\n1. 80235ba79ef (\"log --author=me --grep=it\" should find intersection,\n   not union, 2010-01-17)\n\nHelped-by: Elijah Newren <newren@gmail.com>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n grep.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/grep.c b/grep.c\nindex f8708e1fd20..92ece4b7fa3 100644\n--- a/grep.c\n+++ b/grep.c\n@@ -795,6 +795,7 @@ static void free_grep_pat(struct grep_pat *pattern)\n void free_grep_patterns(struct grep_opt *opt)\n {\n \tfree_grep_pat(opt->pattern_list);\n+\tfree_grep_pat(opt->header_list);\n \n \tif (opt->pattern_expression)\n \t\tfree_pattern_expr(opt->pattern_expression);\n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471657","messageId":"patch-v7-18.19-d28b710c0ba-20230206T230142Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"[PATCH v7 18/19] push: refactor refspec_append_mapped() for subsequent leak-fix","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:53Z","receivedAt":"2023-02-06T23:09:17Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"The set_refspecs() caller of refspec_append_mapped() (added in [1])\nleft open the question[2] of whether the \"remote\" we lazily fetch\nmight be NULL in the \"[...]uniquely name our ref?\" case, as\nremote_get() can return NULL.\n\nIf we got past the \"[...]uniquely name our ref?\" case we'd have\nalready segfaulted if we tried to dereference it as\n\"remote->push.nr\". In these cases the config mechanism & previous\nremote validation will have bailed out earlier.\n\nLet's refactor this code to clarify that, we'll now BUG() out if we\ncan't get a \"remote\", and will no longer retrieve it for these common\ncases where we don't need it.\n\n1. ca02465b413 (push: use remote.$name.push as a refmap, 2013-12-03)\n2. https://lore.kernel.org/git/c0c07b89-7eaf-21cd-748e-e14ea57f09fd@web.de/\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/push.c | 29 +++++++++++++++++------------\n 1 file changed, 17 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/push.c b/builtin/push.c\nindex 60ac8017e52..97b35eca3ab 100644\n--- a/builtin/push.c\n+++ b/builtin/push.c\n@@ -63,16 +63,9 @@ static struct refspec rs = REFSPEC_INIT_PUSH;\n static struct string_list push_options_config = STRING_LIST_INIT_DUP;\n \n static void refspec_append_mapped(struct refspec *refspec, const char *ref,\n-\t\t\t\t  struct remote *remote, struct ref *local_refs)\n+\t\t\t\t  struct remote *remote, struct ref *matched)\n {\n \tconst char *branch_name;\n-\tstruct ref *matched = NULL;\n-\n-\t/* Does \"ref\" uniquely name our ref? */\n-\tif (count_refspec_match(ref, local_refs, &matched) != 1) {\n-\t\trefspec_append(refspec, ref);\n-\t\treturn;\n-\t}\n \n \tif (remote->push.nr) {\n \t\tstruct refspec_item query;\n@@ -120,12 +113,24 @@ static void set_refspecs(const char **refs, int nr, const char *repo)\n \t\t\t\tdie(_(\"--delete only accepts plain target ref names\"));\n \t\t\trefspec_appendf(&rs, \":%s\", ref);\n \t\t} else if (!strchr(ref, ':')) {\n-\t\t\tif (!remote) {\n-\t\t\t\t/* lazily grab remote and local_refs */\n-\t\t\t\tremote = remote_get(repo);\n+\t\t\tstruct ref *matched = NULL;\n+\n+\t\t\t/* lazily grab local_refs */\n+\t\t\tif (!local_refs)\n \t\t\t\tlocal_refs = get_local_heads();\n+\n+\t\t\t/* Does \"ref\" uniquely name our ref? */\n+\t\t\tif (count_refspec_match(ref, local_refs, &matched) != 1) {\n+\t\t\t\trefspec_append(&rs, ref);\n+\t\t\t} else {\n+\t\t\t\t/* lazily grab remote */\n+\t\t\t\tif (!remote)\n+\t\t\t\t\tremote = remote_get(repo);\n+\t\t\t\tif (!remote)\n+\t\t\t\t\tBUG(\"must get a remote for repo '%s'\", repo);\n+\n+\t\t\t\trefspec_append_mapped(&rs, ref, remote, matched);\n \t\t\t}\n-\t\t\trefspec_append_mapped(&rs, ref, remote, local_refs);\n \t\t} else\n \t\t\trefspec_append(&rs, ref);\n \t}\n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471658","messageId":"patch-v7-17.19-b02ece0d36b-20230206T230142Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"[PATCH v7 17/19] receive-pack: release the linked \"struct command *\" list","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:52Z","receivedAt":"2023-02-06T23:09:19Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us since this code was introduced\nin [1]. Later in [2] we started using FLEX_ALLOC_MEM() to allocate the\n\"struct command *\".\n\n1. 575f497456e (Add first cut at \"git-receive-pack\", 2005-06-29)\n2. eb1af2df0b1 (git-receive-pack: start parsing ref update commands,\n   2005-06-29)\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/receive-pack.c                 | 11 +++++++++++\n t/t5405-send-pack-rewind.sh            |  1 +\n t/t5406-remote-rejects.sh              |  1 +\n t/t5507-remote-environment.sh          |  2 ++\n t/t5522-pull-symlink.sh                |  1 +\n t/t5527-fetch-odd-refs.sh              |  1 +\n t/t5560-http-backend-noserver.sh       |  1 +\n t/t5561-http-backend.sh                |  1 +\n t/t5562-http-backend-content-length.sh |  2 ++\n t/t5705-session-id-in-capabilities.sh  |  1 +\n 10 files changed, 22 insertions(+)\n\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex a90af303630..cd5c7a28eff 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -2032,6 +2032,16 @@ static struct command **queue_command(struct command **tail,\n \treturn &cmd->next;\n }\n \n+static void free_commands(struct command *commands)\n+{\n+\twhile (commands) {\n+\t\tstruct command *next = commands->next;\n+\n+\t\tfree(commands);\n+\t\tcommands = next;\n+\t}\n+}\n+\n static void queue_commands_from_cert(struct command **tail,\n \t\t\t\t     struct strbuf *push_cert)\n {\n@@ -2569,6 +2579,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n \t\trun_receive_hook(commands, \"post-receive\", 1,\n \t\t\t\t &push_options);\n \t\trun_update_post_hook(commands);\n+\t\tfree_commands(commands);\n \t\tstring_list_clear(&push_options, 0);\n \t\tif (auto_gc) {\n \t\t\tstruct child_process proc = CHILD_PROCESS_INIT;\ndiff --git a/t/t5405-send-pack-rewind.sh b/t/t5405-send-pack-rewind.sh\nindex 11f03239a06..1686ac13aa6 100755\n--- a/t/t5405-send-pack-rewind.sh\n+++ b/t/t5405-send-pack-rewind.sh\n@@ -5,6 +5,7 @@ test_description='forced push to replace commit we do not have'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t5406-remote-rejects.sh b/t/t5406-remote-rejects.sh\nindex dcbeb420827..d6a99466338 100755\n--- a/t/t5406-remote-rejects.sh\n+++ b/t/t5406-remote-rejects.sh\n@@ -2,6 +2,7 @@\n \n test_description='remote push rejects are reported by client'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t5507-remote-environment.sh b/t/t5507-remote-environment.sh\nindex e6149295b18..c6a6957c500 100755\n--- a/t/t5507-remote-environment.sh\n+++ b/t/t5507-remote-environment.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check environment showed to remote side of transports'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'set up \"remote\" push situation' '\ndiff --git a/t/t5522-pull-symlink.sh b/t/t5522-pull-symlink.sh\nindex bcff460d0a2..394bc60cb8e 100755\n--- a/t/t5522-pull-symlink.sh\n+++ b/t/t5522-pull-symlink.sh\n@@ -2,6 +2,7 @@\n \n test_description='pulling from symlinked subdir'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # The scenario we are building:\ndiff --git a/t/t5527-fetch-odd-refs.sh b/t/t5527-fetch-odd-refs.sh\nindex e2770e4541f..98ece27c6a0 100755\n--- a/t/t5527-fetch-odd-refs.sh\n+++ b/t/t5527-fetch-odd-refs.sh\n@@ -4,6 +4,7 @@ test_description='test fetching of oddly-named refs'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # afterwards we will have:\ndiff --git a/t/t5560-http-backend-noserver.sh b/t/t5560-http-backend-noserver.sh\nindex d30cf4f5b83..f75068de648 100755\n--- a/t/t5560-http-backend-noserver.sh\n+++ b/t/t5560-http-backend-noserver.sh\n@@ -4,6 +4,7 @@ test_description='test git-http-backend-noserver'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n HTTPD_DOCUMENT_ROOT_PATH=\"$TRASH_DIRECTORY\"\ndiff --git a/t/t5561-http-backend.sh b/t/t5561-http-backend.sh\nindex 9c57d843152..e1d3b8caed0 100755\n--- a/t/t5561-http-backend.sh\n+++ b/t/t5561-http-backend.sh\n@@ -4,6 +4,7 @@ test_description='test git-http-backend'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-httpd.sh\n \ndiff --git a/t/t5562-http-backend-content-length.sh b/t/t5562-http-backend-content-length.sh\nindex b68ec22d3fd..7ee9858a78b 100755\n--- a/t/t5562-http-backend-content-length.sh\n+++ b/t/t5562-http-backend-content-length.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test git-http-backend respects CONTENT_LENGTH'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_lazy_prereq GZIP 'gzip --version'\ndiff --git a/t/t5705-session-id-in-capabilities.sh b/t/t5705-session-id-in-capabilities.sh\nindex ed38c76c290..b8a722ec27e 100755\n--- a/t/t5705-session-id-in-capabilities.sh\n+++ b/t/t5705-session-id-in-capabilities.sh\n@@ -2,6 +2,7 @@\n \n test_description='session ID in capabilities'\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n REPO=\"$(pwd)/repo\"\n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471659","messageId":"patch-v7-19.19-ba8e5496d96-20230206T230142Z-avarab@gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"[PATCH v7 19/19] push: free_refs() the \"local_refs\" in set_refspecs()","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2023-02-06T23:07:54Z","receivedAt":"2023-02-06T23:09:33Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Fix a memory leak that's been with us since this code was added in\nca02465b413 (push: use remote.$name.push as a refmap, 2013-12-03).\n\nThe \"remote = remote_get(...)\" added in the same commit would seem to\nleak based only on the context here, but that function is a wrapper\nfor sticking the remotes we fetch into \"the_repository->remote_state\".\n\nSee fd3cb0501e1 (remote: move static variables into per-repository\nstruct, 2021-11-17) for the addition of code in repository.c that\nfree's the \"remote\" allocated here.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/push.c                          | 1 +\n t/t1416-ref-transaction-hooks.sh        | 1 +\n t/t2402-worktree-list.sh                | 1 +\n t/t5504-fetch-receive-strict.sh         | 1 +\n t/t5523-push-upstream.sh                | 1 +\n t/t5529-push-errors.sh                  | 2 ++\n t/t5546-receive-limits.sh               | 2 ++\n t/t5547-push-quarantine.sh              | 2 ++\n t/t5606-clone-options.sh                | 1 +\n t/t5810-proto-disable-local.sh          | 2 ++\n t/t5813-proto-disable-ssh.sh            | 2 ++\n t/t7409-submodule-detached-work-tree.sh | 1 +\n t/t7416-submodule-dash-url.sh           | 2 ++\n t/t7450-bad-git-dotfiles.sh             | 2 ++\n 14 files changed, 21 insertions(+)\n\ndiff --git a/builtin/push.c b/builtin/push.c\nindex 97b35eca3ab..8f7d326ab3f 100644\n--- a/builtin/push.c\n+++ b/builtin/push.c\n@@ -134,6 +134,7 @@ static void set_refspecs(const char **refs, int nr, const char *repo)\n \t\t} else\n \t\t\trefspec_append(&rs, ref);\n \t}\n+\tfree_refs(local_refs);\n }\n \n static int push_url_of_remote(struct remote *remote, const char ***url_p)\ndiff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh\nindex 27731722a5b..b32ca798f9f 100755\n--- a/t/t1416-ref-transaction-hooks.sh\n+++ b/t/t1416-ref-transaction-hooks.sh\n@@ -5,6 +5,7 @@ test_description='reference transaction hooks'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success setup '\ndiff --git a/t/t2402-worktree-list.sh b/t/t2402-worktree-list.sh\nindex 79e0fce2d90..9ad9be0c208 100755\n--- a/t/t2402-worktree-list.sh\n+++ b/t/t2402-worktree-list.sh\n@@ -5,6 +5,7 @@ test_description='test git worktree list'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh\nindex 88d3c56750a..0b8ab4afdbe 100755\n--- a/t/t5504-fetch-receive-strict.sh\n+++ b/t/t5504-fetch-receive-strict.sh\n@@ -4,6 +4,7 @@ test_description='fetch/receive strict mode'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup and inject \"corrupt or missing\" object' '\ndiff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh\nindex fdb42920564..c9acc076353 100755\n--- a/t/t5523-push-upstream.sh\n+++ b/t/t5523-push-upstream.sh\n@@ -4,6 +4,7 @@ test_description='push with --set-upstream'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-terminal.sh\n \ndiff --git a/t/t5529-push-errors.sh b/t/t5529-push-errors.sh\nindex ce85fd30ad1..0247137cb36 100755\n--- a/t/t5529-push-errors.sh\n+++ b/t/t5529-push-errors.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='detect some push errors early (before contacting remote)'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup commits' '\ndiff --git a/t/t5546-receive-limits.sh b/t/t5546-receive-limits.sh\nindex 0b0e987fdb7..eed3c9d81ab 100755\n--- a/t/t5546-receive-limits.sh\n+++ b/t/t5546-receive-limits.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check receive input limits'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n # Let's run tests with different unpack limits: 1 and 10000\ndiff --git a/t/t5547-push-quarantine.sh b/t/t5547-push-quarantine.sh\nindex 1876fb34e51..9f899b8c7d7 100755\n--- a/t/t5547-push-quarantine.sh\n+++ b/t/t5547-push-quarantine.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check quarantine of objects during push'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'create picky dest repo' '\ndiff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh\nindex cf221e92c4d..27f9f776389 100755\n--- a/t/t5606-clone-options.sh\n+++ b/t/t5606-clone-options.sh\n@@ -4,6 +4,7 @@ test_description='basic clone options'\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t5810-proto-disable-local.sh b/t/t5810-proto-disable-local.sh\nindex c1ef99b85c2..862610256fb 100755\n--- a/t/t5810-proto-disable-local.sh\n+++ b/t/t5810-proto-disable-local.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test disabling of local paths in clone/fetch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY/lib-proto-disable.sh\"\n \ndiff --git a/t/t5813-proto-disable-ssh.sh b/t/t5813-proto-disable-ssh.sh\nindex 3f084ee3065..2e975dc70ec 100755\n--- a/t/t5813-proto-disable-ssh.sh\n+++ b/t/t5813-proto-disable-ssh.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='test disabling of git-over-ssh in clone/fetch'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY/lib-proto-disable.sh\"\n \ndiff --git a/t/t7409-submodule-detached-work-tree.sh b/t/t7409-submodule-detached-work-tree.sh\nindex 374ed481e9c..574a6fc526e 100755\n--- a/t/t7409-submodule-detached-work-tree.sh\n+++ b/t/t7409-submodule-detached-work-tree.sh\n@@ -13,6 +13,7 @@ TEST_NO_CREATE_REPO=1\n GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7416-submodule-dash-url.sh b/t/t7416-submodule-dash-url.sh\nindex 3ebd9859814..7cf72b9a076 100755\n--- a/t/t7416-submodule-dash-url.sh\n+++ b/t/t7416-submodule-dash-url.sh\n@@ -1,6 +1,8 @@\n #!/bin/sh\n \n test_description='check handling of disallowed .gitmodule urls'\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n \n test_expect_success 'setup' '\ndiff --git a/t/t7450-bad-git-dotfiles.sh b/t/t7450-bad-git-dotfiles.sh\nindex ba1f569bcbb..0d0c3f2c683 100755\n--- a/t/t7450-bad-git-dotfiles.sh\n+++ b/t/t7450-bad-git-dotfiles.sh\n@@ -12,6 +12,8 @@ Such as:\n \n   - symlinked .gitmodules, etc\n '\n+\n+TEST_PASSES_SANITIZE_LEAK=true\n . ./test-lib.sh\n . \"$TEST_DIRECTORY\"/lib-pack.sh\n \n-- \n2.39.1.1425.gac85d95d48c\n\n"},{"id":"471663","messageId":"xmqq357i2wex.fsf@gitster.g","threadId":"59011","inReplyTo":"230206.86sffi67ce.gmgdl@evledraar.gmail.com","subject":"Re: [PATCH v6 18/19] push: refactor refspec_append_mapped() for subsequent leak-fix","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-02-06T23:42:30Z","receivedAt":"2023-02-06T23:42:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n> I think you're mistaken, or I'm misunderstanding you. For e.g. the 29th\n> test in t4301-merge-tree-write-tree.sh where we do:\n>\n> \tgit push read-only side1 side2 side3\n>\n> We'll only invoke \"get_local_heads()\" once, not once for each of the\n> refs.\n\nAhh.  get_local_heads() appears inside this conditional in the\noriginal.\n\n\t} else if (!strchr(ref, ':')) {\n\t\tif (!remote) {\n\t\t\tremote = remote_get(repo);\n\t\t\tlocal_refs = get_local_heads();\n\t\t}\n\t        refspec_append_mapped(...);\n\t} else\n\t\t...\n\nSo the original was using !remote as the switch to make both remote\nand local_refs assigned onnly once.  The rewritten code makes them\nseparately \"find first non-null\".\n\nOK.\n"},{"id":"471666","messageId":"xmqqttzy1geq.fsf@gitster.g","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"Re: [PATCH v7 00/19] leak fixes: various simple leak fixes","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-02-07T00:13:33Z","receivedAt":"2023-02-07T00:13:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> See\n> https://lore.kernel.org/git/cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com/#t\n> for the v6. Changes since then:\n>\n> * Corrected the 17/19 commit message to note that it free()'s an\n>   entire allocated struct, not just its \"flex\" member.\n\nYup.  There isn't much point in saying that the struct gained a\nflex-array member during the course of its life.  The fact that we\nforgot to free the struct but now we do is what matters.\n\n> * Per my replies on 18/19 and 19/19 in v6 I think those commit\n>   messages are correct as-is, so sending this in in case Junio's OK\n>   with picking up this version.\n\nThese looked OK to me.\n\nThanks.\n"},{"id":"471667","messageId":"CABPp-BE4o-8A4B4dV0bWo+7J5S_0s8UgZA4LRN=nyupKzqbXRQ@mail.gmail.com","threadId":"59011","inReplyTo":"cover-v7-00.19-00000000000-20230206T230141Z-avarab@gmail.com","subject":"Re: [PATCH v7 00/19] leak fixes: various simple leak fixes","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2023-02-07T03:40:00Z","receivedAt":"2023-02-07T03:40:25Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Mon, Feb 6, 2023 at 3:08 PM Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:\n>\n> See\n> https://lore.kernel.org/git/cover-v6-00.19-00000000000-20230202T094704Z-avarab@gmail.com/#t\n> for the v6. Changes since then:\n>\n> * Corrected the 17/19 commit message to note that it free()'s an\n>   entire allocated struct, not just its \"flex\" member.\n>\n> * Per my replies on 18/19 and 19/19 in v6 I think those commit\n>   messages are correct as-is, so sending this in in case Junio's OK\n>   with picking up this version.\n\nThis version corrects the issues I noted in v5 (actually v6 did too, I\njust didn't get around to reviewing soon enough).  Thanks for working\non this, Ævar!\n\nReviewed-by: Elijah Newren <newren@gmail.com>\n"}]}