Fix memory leaks in transport_push(), where remote_refs and local_refs are never freed. 116 bytes in 1 blocks are definitely lost in loss record 56 of 103 at 0x484486F: malloc (vg_replace_malloc.c:381) by 0x4938D7E: strdup (strdup.c:42) by 0x628418: xstrdup (wrapper.c:39) by 0x4FD454: process_capabilities (connect.c:232) by 0x4FD454: get_remote_heads (connect.c:354) by 0x610A38: handshake (transport.c:333) by 0x612B02: transport_push (transport.c:1302) by 0x4803D6: push_with_options (push.c:357) by 0x4811D6: do_push (push.c:414) by 0x4811D6: cmd_push (push.c:650) by 0x405210: run_builtin (git.c:465) by 0x405210: handle_builtin (git.c:719) by 0x406363: run_argv (git.c:786) by 0x406363: cmd_main (git.c:917) by 0x404F17: main (common-main.c:56) 5,912 (388 direct, 5,524 indirect) bytes in 2 blocks are definitely lost in loss record 98 of 103 at 0x4849464: calloc (vg_replace_malloc.c:1328) by 0x628705: xcalloc (wrapper.c:150) by 0x5C216D: alloc_ref_with_prefix (remote.c:975) by 0x5C232A: alloc_ref (remote.c:983) by 0x5C232A: one_local_ref (remote.c:2299) by 0x5C232A: one_local_ref (remote.c:2289) by 0x5BDB03: do_for_each_repo_ref_iterator (iterator.c:418) by 0x5B4C4F: do_for_each_ref (refs.c:1486) by 0x5B4C4F: refs_for_each_ref (refs.c:1492) by 0x5B4C4F: for_each_ref (refs.c:1497) by 0x5C6ADF: get_local_heads (remote.c:2310) by 0x612A85: transport_push (transport.c:1286) by 0x4803D6: push_with_options (push.c:357) by 0x4811D6: do_push (push.c:414) by 0x4811D6: cmd_push (push.c:650) by 0x405210: run_builtin (git.c:465) by 0x405210: handle_builtin (git.c:719) by 0x406363: run_argv (git.c:786) by 0x406363: cmd_main (git.c:917) Signed-off-by: Frantisek Hrbata <frantisek@xxxxxxxxxx> --- For remote_refs it might be worth to leave the freeing to transport_disconnect() and introduce helper similar to transport_get_remote_refs(). transport.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/transport.c b/transport.c index 0b9c5a427d..4c5d9db7f2 100644 --- a/transport.c +++ b/transport.c @@ -1276,8 +1276,8 @@ int transport_push(struct repository *r, struct refspec *rs, int flags, unsigned int *reject_reasons) { - struct ref *remote_refs; - struct ref *local_refs; + struct ref *remote_refs = NULL; + struct ref *local_refs = NULL; int match_flags = MATCH_REFS_NONE; int verbose = (transport->verbose > 0); int quiet = (transport->verbose < 0); @@ -1295,10 +1295,11 @@ int transport_push(struct repository *r, if (!transport->vtable->push_refs) return 1; + ret = -1; local_refs = get_local_heads(); if (check_push_refs(local_refs, rs) < 0) - return -1; + goto done; refspec_ref_prefixes(rs, &transport_options.ref_prefixes); @@ -1319,7 +1320,7 @@ int transport_push(struct repository *r, match_flags |= MATCH_REFS_FOLLOW_TAGS; if (match_push_refs(local_refs, &remote_refs, rs, match_flags)) - return -1; + goto done; if (transport->smart_options && transport->smart_options->cas && @@ -1333,7 +1334,7 @@ int transport_push(struct repository *r, if (!(flags & TRANSPORT_PUSH_NO_HOOK)) if (run_pre_push_hook(transport, remote_refs)) - return -1; + goto done; if ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND | TRANSPORT_RECURSE_SUBMODULES_ONLY)) && @@ -1417,6 +1418,9 @@ int transport_push(struct repository *r, else if (!quiet && !ret && !transport_refs_pushed(remote_refs)) fprintf(stderr, "Everything up-to-date\n"); +done: + free_refs(local_refs); + free_refs(remote_refs); return ret; } -- 2.35.1