This is a collection of various otherwise unrelated tree-wide fixes for memory leaks. See v1 for a (short) overview: https://lore.kernel.org/git/cover-00.14-00000000000-20220302T170718Z-avarab@xxxxxxxxx/ This re-roll addresses issues Derrick Stolee noted. There's a trivial commit-message change in 1/14, and a rather trivial (but important) change in how a variable is incremented in 7/14. That change to v1 is actually small, but the range-diff is big since "git diff" picks a different way to "anchor" the diff as a result. Ævar Arnfjörð Bjarmason (14): index-pack: fix memory leaks merge-base: free() allocated "struct commit **" list diff.c: free "buf" in diff_words_flush() urlmatch.c: add and use a *_release() function remote-curl.c: free memory in cmd_main() bundle: call strvec_clear() on allocated strvec transport: stop needlessly copying bundle header references submodule--helper: fix trivial leak in module_add() commit-graph: fix memory leak in misused string_list API commit-graph: stop fill_oids_from_packs() progress on error and free() lockfile API users: simplify and don't leak "path" range-diff: plug memory leak in common invocation range-diff: plug memory leak in read_patches() repository.c: free the "path cache" in repo_clear() apply.c | 7 ++++++- apply.h | 2 ++ builtin/bundle.c | 1 + builtin/commit-graph.c | 6 +++--- builtin/config.c | 2 +- builtin/index-pack.c | 5 +++++ builtin/merge-base.c | 5 ++++- builtin/sparse-checkout.c | 3 +-- builtin/submodule--helper.c | 5 ++++- commit-graph.c | 18 +++++++++++------- commit-graph.h | 2 +- credential.c | 1 + diff.c | 1 + path.h | 14 -------------- range-diff.c | 30 +++++++++++++----------------- remote-curl.c | 12 ++++++++---- repository.c | 16 ++++++++++++++++ repository.h | 14 +++++++++++++- transport.c | 25 ++++++++++++++++--------- urlmatch.c | 5 +++++ urlmatch.h | 1 + 21 files changed, 113 insertions(+), 62 deletions(-) Range-diff against v1: 1: bcba06e1d28 ! 1: f46af9ad13f index-pack: fix memory leaks @@ Commit message Fix various memory leaks in "git index-pack", due to how tightly coupled this command is with the revision walking this doesn't make - any new tests pass, but e.g. this now passes, and had several failures before: + any new tests pass. + + But e.g. this now passes, and had several failures before, i.e. we + still have failures in tests 3, 5 etc., which are being skipped here. ./t5300-pack-object.sh --run=1-2,4,6-27,30-42 - it is a bit odd that we'll free "opts.anomaly", since the "opts" is a + It is a bit odd that we'll free "opts.anomaly", since the "opts" is a "struct pack_idx_option" declared in pack.h. In pack-write.c there's a reset_pack_idx_option(), but it only wipes the contents, but doesn't free() anything. 2: 4c28f056ec2 = 2: 4ee2881adfb merge-base: free() allocated "struct commit **" list 3: 5d2793039ad = 3: 90517a05582 diff.c: free "buf" in diff_words_flush() 4: 7f7077e8476 = 4: d51f6ae0963 urlmatch.c: add and use a *_release() function 5: 8891fd44c7c = 5: f0a26db8a87 remote-curl.c: free memory in cmd_main() 6: 52e2c2a8281 = 6: c636770b5d6 bundle: call strvec_clear() on allocated strvec 7: be62ca89bf5 ! 7: b3f7753a790 transport: stop needlessly copying bundle header references @@ transport.c: struct bundle_transport_data { unsigned get_refs_from_bundle_called : 1; }; +-static struct ref *get_refs_from_bundle(struct transport *transport, +- int for_push, +- struct transport_ls_refs_options *transport_options) +static void get_refs_from_bundle_inner(struct transport *transport) + { + struct bundle_transport_data *data = transport->data; +- struct ref *result = NULL; +- int i; +- +- if (for_push) +- return NULL; + + data->get_refs_from_bundle_called = 1; + +@@ transport.c: static struct ref *get_refs_from_bundle(struct transport *transport, + die(_("could not read bundle '%s'"), transport->url); + + transport->hash_algo = data->header.hash_algo; ++} ++ ++static struct ref *get_refs_from_bundle(struct transport *transport, ++ int for_push, ++ struct transport_ls_refs_options *transport_options) +{ + struct bundle_transport_data *data = transport->data; ++ struct ref *result = NULL; ++ int i; + -+ if (data->fd > 0) -+ close(data->fd); -+ data->fd = read_bundle_header(transport->url, &data->header); -+ if (data->fd < 0) -+ die(_("could not read bundle '%s'"), transport->url); -+ -+ transport->hash_algo = data->header.hash_algo; -+} ++ if (for_push) ++ return NULL; + - static struct ref *get_refs_from_bundle(struct transport *transport, - int for_push, - struct transport_ls_refs_options *transport_options) -@@ transport.c: static struct ref *get_refs_from_bundle(struct transport *transport, - if (for_push) - return NULL; - -- data->get_refs_from_bundle_called = 1; -- -- if (data->fd > 0) -- close(data->fd); -- data->fd = read_bundle_header(transport->url, &data->header); -- if (data->fd < 0) -- die(_("could not read bundle '%s'"), transport->url); -- -- transport->hash_algo = data->header.hash_algo; + get_refs_from_bundle_inner(transport); for (i = 0; i < data->header.references.nr; i++) { struct string_list_item *e = data->header.references.items + i; @@ transport.c: static int fetch_refs_from_bundle(struct transport *transport, - if (transport->progress) strvec_push(&extra_index_pack_args, "-v"); -- if (!data->get_refs_from_bundle_called) + if (!data->get_refs_from_bundle_called) - get_refs_from_bundle(transport, 0, NULL); -+ if (!data->get_refs_from_bundle_called++) + get_refs_from_bundle_inner(transport); ret = unbundle(the_repository, &data->header, data->fd, &extra_index_pack_args); 8: 122fdf7bb41 = 8: af3ca2f0b5f submodule--helper: fix trivial leak in module_add() 9: b5512deb26f = 9: 3fadb265d13 commit-graph: fix memory leak in misused string_list API 10: 27f0883e8d8 = 10: 27f5190ce59 commit-graph: stop fill_oids_from_packs() progress on error and free() 11: cc8beed10be = 11: 217754edc62 lockfile API users: simplify and don't leak "path" 12: 6d13c2530db = 12: 148382d9529 range-diff: plug memory leak in common invocation 13: e7b823f70c8 = 13: c6e61b85491 range-diff: plug memory leak in read_patches() 14: 954de5191c3 = 14: d70a4394f2b repository.c: free the "path cache" in repo_clear() -- 2.35.1.1248.gb68c9165ad8