From: Patrick Steinhardt <ps@pks.im>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>
Subject: [PATCH v2 00/20] Memory leak fixes (pt.5)
Date: Thu, 22 Aug 2024 11:17:08 +0200 [thread overview]
Message-ID: <cover.1724315484.git.ps@pks.im> (raw)
In-Reply-To: <cover.1724159575.git.ps@pks.im>
Hi,
this is version 2 of this patch series that fixes another set of memory
leaks.
Changes compared to v1:
- Remove spaces between cast and variable.
- Clarify why we move the `ctx.entries_nr` block.
- Adapt sideband colors to use `git_config_get_string_tmp()` such that
we do not have to allocate the strings in the first place.
- Fix more memory leaks for config values in the remote state.
- Refactor `unbundle()` to not free extra args passed by the caller
anymore. Instead, this is now always done by the caler.
Thanks!
Patrick
Patrick Steinhardt (20):
mailinfo: fix leaking header data
convert: fix leaks when resetting attributes
pretty: fix memory leaks when parsing pretty formats
pretty: fix leaking key/value separator buffer
builtin/merge-tree: fix leaking `-X` strategy options
builtin/upload-archive: fix leaking args passed to `write_archive()`
builtin/archive: fix leaking `OPT_FILENAME()` value
midx-write: fix leaking hashfile on error cases
builtin/repack: fix leaks when computing packs to repack
t/helper: fix leaking multi-pack-indices in "read-midx"
transport: fix leaking OID arrays in git:// transport data
builtin/send-pack: fix leaking refspecs
sideband: fix leaks when configuring sideband colors
builtin/fetch-pack: fix leaking refs
remote: fix leaking config strings
remote: fix leaks when matching refspecs
remote: fix leaking peer ref when expanding refmap
builtin/fetch: fix leaking transaction with `--atomic`
transport: fix leaking arguments when fetching from bundle
transport: fix leaking negotiation tips
archive.c | 10 ++++
builtin/archive.c | 7 ++-
builtin/bundle.c | 2 +
builtin/fetch-pack.c | 20 ++++---
builtin/fetch.c | 8 +--
builtin/merge-tree.c | 13 ++++-
builtin/repack.c | 36 +++++++++---
builtin/send-pack.c | 1 +
builtin/upload-archive.c | 8 ++-
bundle.c | 4 +-
convert.c | 3 +
mailinfo.c | 17 +++++-
midx-write.c | 24 ++++----
pretty.c | 13 ++++-
remote.c | 85 +++++++++++++++++++++++------
sideband.c | 15 +++--
t/helper/test-read-midx.c | 8 ++-
t/t4150-am.sh | 1 +
t/t4205-log-pretty-formats.sh | 2 +
t/t4301-merge-tree-write-tree.sh | 1 +
t/t5000-tar-tree.sh | 1 +
t/t5003-archive-zip.sh | 1 +
t/t5100-mailinfo.sh | 1 +
t/t5319-multi-pack-index.sh | 2 +
t/t5400-send-pack.sh | 1 +
t/t5401-update-hooks.sh | 2 +
t/t5408-send-pack-stdin.sh | 2 +
t/t5409-colorize-remote-messages.sh | 1 +
t/t5501-fetch-push-alternates.sh | 1 +
t/t5505-remote.sh | 1 +
t/t5510-fetch.sh | 1 +
t/t5519-push-alternates.sh | 1 +
t/t5536-fetch-conflicts.sh | 1 +
t/t5548-push-porcelain.sh | 1 +
t/t5553-set-upstream.sh | 1 +
t/t5574-fetch-output.sh | 1 +
t/t5703-upload-pack-ref-in-want.sh | 1 +
t/t5812-proto-disable-http.sh | 2 +
t/t6050-replace.sh | 1 +
t/t7704-repack-cruft.sh | 1 +
transport.c | 8 +++
41 files changed, 237 insertions(+), 73 deletions(-)
Range-diff against v1:
1: 69e30ea5179 = 1: 69e30ea5179 mailinfo: fix leaking header data
2: ed0f01bf92c = 2: ed0f01bf92c convert: fix leaks when resetting attributes
3: 82f3908f962 ! 3: 8a1963685e7 pretty: fix memory leaks when parsing pretty formats
@@ pretty.c: static int git_pretty_formats_config(const char *var, const char *valu
commit_formats_len++;
}
-+ free((char *) commit_format->name);
++ free((char *)commit_format->name);
commit_format->name = xstrdup(name);
commit_format->format = CMIT_FMT_USERFORMAT;
if (git_config_string(&fmt, var, value))
return -1;
- if (skip_prefix(fmt, "format:", &commit_format->user_format)) {
-+ free((char *) commit_format->user_format);
++ free((char *)commit_format->user_format);
+ if (skip_prefix(fmt, "format:", &stripped)) {
commit_format->is_tformat = 0;
- } else if (skip_prefix(fmt, "tformat:", &commit_format->user_format)) {
4: 696467780e6 = 4: 1c368a4489a pretty: fix leaking key/value separator buffer
5: 53db2fc7206 = 5: c62c5e9604e builtin/merge-tree: fix leaking `-X` strategy options
6: 5b05a325218 = 6: afdd7f90b13 builtin/upload-archive: fix leaking args passed to `write_archive()`
7: bad575df126 = 7: 38487f3f65b builtin/archive: fix leaking `OPT_FILENAME()` value
8: 5f042ce5098 ! 8: 693c93ddbf7 midx-write: fix leaking hashfile on error cases
@@ Commit message
hashfile and finalizing it anymore this is sufficient to fix the memory
leak.
+ While at it, also move around the block checking for `ctx.entries_nr`.
+ This change is not required to fix the memory leak, but it feels natural
+ to move together all massaging of parameters before we go with them and
+ execute the actual logic.
+
Signed-off-by: Patrick Steinhardt <ps@pks.im>
## midx-write.c ##
9: 5c820da9761 = 9: 6bca72e5c57 builtin/repack: fix leaks when computing packs to repack
10: 9caf5eeea93 = 10: 48b60279d18 t/helper: fix leaking multi-pack-indices in "read-midx"
11: 8e12c55536d = 11: 0cb440ef648 transport: fix leaking OID arrays in git:// transport data
12: 5d8e0a3d8b4 = 12: f4300c9326b builtin/send-pack: fix leaking refspecs
13: 5d09959b642 ! 13: 28805c15a42 sideband: fix leaks when configuring sideband colors
@@ Commit message
We read a bunch of configs in `use_sideband_colors()` to configure the
colors that Git should use. We never free the strings read from the
- config though, causing memory leaks. Fix those.
+ config though, causing memory leaks.
+
+ Refactor the code to use `git_config_get_string_tmp()` instead, which
+ does not allocate memory. As we throw the strings away after parsing
+ them anyway there is no need to use allocated strings.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
@@ sideband.c: static int use_sideband_colors(void)
const char *key = "color.remote";
struct strbuf sb = STRBUF_INIT;
- char *value;
-+ char *value = NULL;
++ const char *value;
int i;
if (use_sideband_colors_cached >= 0)
-@@ sideband.c: static int use_sideband_colors(void)
- } else {
+ return use_sideband_colors_cached;
+
+- if (!git_config_get_string(key, &value)) {
++ if (!git_config_get_string_tmp(key, &value))
+ use_sideband_colors_cached = git_config_colorbool(key, value);
+- } else if (!git_config_get_string("color.ui", &value)) {
++ else if (!git_config_get_string_tmp("color.ui", &value))
+ use_sideband_colors_cached = git_config_colorbool("color.ui", value);
+- } else {
++ else
use_sideband_colors_cached = GIT_COLOR_AUTO;
- }
-+ FREE_AND_NULL(value);
+- }
for (i = 0; i < ARRAY_SIZE(keywords); i++) {
strbuf_reset(&sb);
strbuf_addf(&sb, "%s.%s", key, keywords[i].keyword);
- if (git_config_get_string(sb.buf, &value))
- continue;
-- if (color_parse(value, keywords[i].color))
+- if (git_config_get_string(sb.buf, &value))
- continue;
+- if (color_parse(value, keywords[i].color))
++ if (git_config_get_string_tmp(sb.buf, &value))
+ continue;
+ color_parse(value, keywords[i].color);
-+ FREE_AND_NULL(value);
}
+
strbuf_release(&sb);
14: 1c94195488d = 14: aac84c5a2b7 builtin/fetch-pack: fix leaking refs
15: 97346d6f944 ! 15: 532328b7814 remote: fix leaking config strings
@@ Commit message
We're leaking several config strings when assembling remotes, either
because we do not free preceding values in case a config was set
multiple times, or because we do not free them when releasing the remote
- state. Plug those leaks.
+ state. This includes config strings for "branch" sections, "insteadOf",
+ "pushInsteadOf", and "pushDefault".
+
+ Plug those leaks.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
## remote.c ##
+@@ remote.c: static struct branch *make_branch(struct remote_state *remote_state,
+ return ret;
+ }
+
++static void branch_release(struct branch *branch)
++{
++ free((char *)branch->name);
++ free((char *)branch->refname);
++ free(branch->remote_name);
++ free(branch->pushremote_name);
++ for (int i = 0; i < branch->merge_nr; i++)
++ refspec_item_clear(branch->merge[i]);
++ free(branch->merge);
++}
++
+ static struct rewrite *make_rewrite(struct rewrites *r,
+ const char *base, size_t len)
+ {
+@@ remote.c: static struct rewrite *make_rewrite(struct rewrites *r,
+ return ret;
+ }
+
++static void rewrites_release(struct rewrites *r)
++{
++ for (int i = 0; i < r->rewrite_nr; i++)
++ free((char *)r->rewrite[i]->base);
++ free(r->rewrite);
++ memset(r, 0, sizeof(*r));
++}
++
+ static void add_instead_of(struct rewrite *rewrite, const char *instead_of)
+ {
+ ALLOC_GROW(rewrite->instead_of, rewrite->instead_of_nr + 1, rewrite->instead_of_alloc);
@@ remote.c: static int handle_config(const char *key, const char *value,
return -1;
branch = make_branch(remote_state, name, namelen);
@@ remote.c: static int handle_config(const char *key, const char *value,
return git_config_string(&remote->foreign_vcs, key, value);
}
return 0;
-@@ remote.c: void remote_state_clear(struct remote_state *remote_state)
+@@ remote.c: struct remote_state *remote_state_new(void)
+
+ void remote_state_clear(struct remote_state *remote_state)
+ {
++ struct hashmap_iter iter;
++ struct branch *b;
+ int i;
+
for (i = 0; i < remote_state->remotes_nr; i++)
remote_clear(remote_state->remotes[i]);
FREE_AND_NULL(remote_state->remotes);
@@ remote.c: void remote_state_clear(struct remote_state *remote_state)
remote_state->remotes_alloc = 0;
remote_state->remotes_nr = 0;
++ rewrites_release(&remote_state->rewrites);
++ rewrites_release(&remote_state->rewrites_push);
++
+ hashmap_clear_and_free(&remote_state->remotes_hash, struct remote, ent);
+- hashmap_clear_and_free(&remote_state->branches_hash, struct remote, ent);
++ hashmap_for_each_entry(&remote_state->branches_hash, &iter, b, ent) {
++ branch_release(b);
++ free(b);
++ }
++ hashmap_clear(&remote_state->branches_hash);
+ }
+
+ /*
16: e1d0be37636 = 16: 440b3d99372 remote: fix leaks when matching refspecs
17: 773fe580d75 = 17: 662ec4e6484 remote: fix leaking peer ref when expanding refmap
18: 9ede792550e = 18: dbd8eaa2cb1 builtin/fetch: fix leaking transaction with `--atomic`
19: b72f7d1ee39 ! 19: 4c5740afe43 transport: fix leaking arguments when fetching from bundle
@@ Commit message
transport: fix leaking arguments when fetching from bundle
In `fetch_refs_from_bundle()` we assemble a vector of arguments to pass
- to `unbundle()`, but never free it. Fix this leak.
+ to `unbundle()`, but never free it. And in theory we wouldn't have to
+ because `unbundle()` already knows to free the vector for us. But it
+ fails to do so when it exits early due to `verify_bundle()` failing.
+
+ The calling convention that the arguments are freed by the callee and
+ not the caller feels somewhat weird. Refactor the code such that it is
+ instead the responsibility of the caller to free the vector, adapting
+ the only two callsites where we pass extra arguments. This also fixes
+ the memory leak.
This memory leak gets hit in t5510, but fixing it isn't sufficient to
make the whole test suite pass.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
+ ## builtin/bundle.c ##
+@@ builtin/bundle.c: static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix)
+ &extra_index_pack_args, 0) ||
+ list_bundle_refs(&header, argc, argv);
+ bundle_header_release(&header);
++
+ cleanup:
++ strvec_clear(&extra_index_pack_args);
+ free(bundle_file);
+ return ret;
+ }
+
+ ## bundle.c ##
+@@ bundle.c: int unbundle(struct repository *r, struct bundle_header *header,
+ if (flags & VERIFY_BUNDLE_FSCK)
+ strvec_push(&ip.args, "--fsck-objects");
+
+- if (extra_index_pack_args) {
++ if (extra_index_pack_args)
+ strvec_pushv(&ip.args, extra_index_pack_args->v);
+- strvec_clear(extra_index_pack_args);
+- }
+
+ ip.in = bundle_fd;
+ ip.no_stdout = 1;
+
## transport.c ##
@@ transport.c: static int fetch_refs_from_bundle(struct transport *transport,
&extra_index_pack_args,
20: e8f479deeb2 = 20: c3d2b035761 transport: fix leaking negotiation tips
--
2.46.0.164.g477ce5ccd6.dirty
next prev parent reply other threads:[~2024-08-22 9:17 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-20 14:04 [PATCH 00/20] Memory leak fixes (pt.5) Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 01/20] mailinfo: fix leaking header data Patrick Steinhardt
2024-08-20 19:25 ` Junio C Hamano
2024-08-20 14:05 ` [PATCH 02/20] convert: fix leaks when resetting attributes Patrick Steinhardt
2024-08-20 19:51 ` Junio C Hamano
2024-08-20 14:05 ` [PATCH 03/20] pretty: fix memory leaks when parsing pretty formats Patrick Steinhardt
2024-08-20 20:36 ` Junio C Hamano
2024-08-22 8:19 ` Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 04/20] pretty: fix leaking key/value separator buffer Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 05/20] builtin/merge-tree: fix leaking `-X` strategy options Patrick Steinhardt
2024-08-20 22:10 ` Junio C Hamano
2024-08-20 14:05 ` [PATCH 06/20] builtin/upload-archive: fix leaking args passed to `write_archive()` Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 07/20] builtin/archive: fix leaking `OPT_FILENAME()` value Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 08/20] midx-write: fix leaking hashfile on error cases Patrick Steinhardt
2024-08-20 23:19 ` Junio C Hamano
2024-08-22 8:19 ` Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 09/20] builtin/repack: fix leaks when computing packs to repack Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 10/20] t/helper: fix leaking multi-pack-indices in "read-midx" Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 11/20] transport: fix leaking OID arrays in git:// transport data Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 12/20] builtin/send-pack: fix leaking refspecs Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 13/20] sideband: fix leaks when configuring sideband colors Patrick Steinhardt
2024-08-20 23:52 ` Junio C Hamano
2024-08-22 8:19 ` Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 14/20] builtin/fetch-pack: fix leaking refs Patrick Steinhardt
2024-08-21 17:46 ` Junio C Hamano
2024-08-20 14:05 ` [PATCH 15/20] remote: fix leaking config strings Patrick Steinhardt
2024-08-21 17:58 ` Junio C Hamano
2024-08-22 8:19 ` Patrick Steinhardt
2024-08-22 16:04 ` Junio C Hamano
2024-08-20 14:05 ` [PATCH 16/20] remote: fix leaks when matching refspecs Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 17/20] remote: fix leaking peer ref when expanding refmap Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 18/20] builtin/fetch: fix leaking transaction with `--atomic` Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 19/20] transport: fix leaking arguments when fetching from bundle Patrick Steinhardt
2024-08-21 18:07 ` Junio C Hamano
2024-08-22 8:19 ` Patrick Steinhardt
2024-08-22 16:06 ` Junio C Hamano
2024-08-20 14:06 ` [PATCH 20/20] transport: fix leaking negotiation tips Patrick Steinhardt
2024-08-22 9:17 ` Patrick Steinhardt [this message]
2024-08-22 9:17 ` [PATCH v2 01/20] mailinfo: fix leaking header data Patrick Steinhardt
2024-08-22 9:17 ` [PATCH v2 02/20] convert: fix leaks when resetting attributes Patrick Steinhardt
2024-08-22 9:17 ` [PATCH v2 03/20] pretty: fix memory leaks when parsing pretty formats Patrick Steinhardt
2024-08-22 9:17 ` [PATCH v2 04/20] pretty: fix leaking key/value separator buffer Patrick Steinhardt
2024-08-22 9:17 ` [PATCH v2 05/20] builtin/merge-tree: fix leaking `-X` strategy options Patrick Steinhardt
2024-08-22 9:17 ` [PATCH v2 06/20] builtin/upload-archive: fix leaking args passed to `write_archive()` Patrick Steinhardt
2024-08-22 9:17 ` [PATCH v2 07/20] builtin/archive: fix leaking `OPT_FILENAME()` value Patrick Steinhardt
2024-08-22 9:17 ` [PATCH v2 08/20] midx-write: fix leaking hashfile on error cases Patrick Steinhardt
2024-08-22 9:17 ` [PATCH v2 09/20] builtin/repack: fix leaks when computing packs to repack Patrick Steinhardt
2024-08-22 9:17 ` [PATCH v2 10/20] t/helper: fix leaking multi-pack-indices in "read-midx" Patrick Steinhardt
2024-08-22 9:17 ` [PATCH v2 11/20] transport: fix leaking OID arrays in git:// transport data Patrick Steinhardt
2024-08-22 9:17 ` [PATCH v2 12/20] builtin/send-pack: fix leaking refspecs Patrick Steinhardt
2024-08-22 9:17 ` [PATCH v2 13/20] sideband: fix leaks when configuring sideband colors Patrick Steinhardt
2024-08-22 9:17 ` [PATCH v2 14/20] builtin/fetch-pack: fix leaking refs Patrick Steinhardt
2024-08-22 9:17 ` [PATCH v2 15/20] remote: fix leaking config strings Patrick Steinhardt
2024-08-22 9:17 ` [PATCH v2 16/20] remote: fix leaks when matching refspecs Patrick Steinhardt
2024-08-22 9:18 ` [PATCH v2 17/20] remote: fix leaking peer ref when expanding refmap Patrick Steinhardt
2024-08-22 9:18 ` [PATCH v2 18/20] builtin/fetch: fix leaking transaction with `--atomic` Patrick Steinhardt
2024-08-22 9:18 ` [PATCH v2 19/20] transport: fix leaking arguments when fetching from bundle Patrick Steinhardt
2024-08-22 18:21 ` Junio C Hamano
2024-08-22 9:18 ` [PATCH v2 20/20] transport: fix leaking negotiation tips Patrick Steinhardt
2024-08-22 19:01 ` [PATCH v2 00/20] Memory leak fixes (pt.5) Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cover.1724315484.git.ps@pks.im \
--to=ps@pks.im \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).