Skip to content

Commit 72972ea

Browse files
committed
Merge branch 'ab/various-leak-fixes'
Leak fixes. * ab/various-leak-fixes: push: free_refs() the "local_refs" in set_refspecs() push: refactor refspec_append_mapped() for subsequent leak-fix receive-pack: release the linked "struct command *" list grep API: plug memory leaks by freeing "header_list" grep.c: refactor free_grep_patterns() builtin/merge.c: free "&buf" on "Your local changes..." error builtin/merge.c: use fixed strings, not "strbuf", fix leak show-branch: free() allocated "head" before return commit-graph: fix a parse_options_concat() leak http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}() http-backend.c: fix "dir" and "cmd_arg" leaks in cmd_main() worktree: fix a trivial leak in prune_worktrees() repack: fix leaks on error with "goto cleanup" name-rev: don't xstrdup() an already dup'd string various: add missing clear_pathspec(), fix leaks clone: use free() instead of UNLEAK() commit-graph: use free_commit_graph() instead of UNLEAK() bundle.c: don't leak the "args" in the "struct child_process" tests: mark tests as passing with SANITIZE=leak
2 parents 6aac634 + c65d18c commit 72972ea

File tree

77 files changed

+182
-62
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+182
-62
lines changed

archive.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,7 @@ int write_archive(int argc, const char **argv, const char *prefix,
710710

711711
string_list_clear_func(&args.extra_files, extra_file_info_clear);
712712
free(args.refname);
713+
clear_pathspec(&args.pathspec);
713714

714715
return rc;
715716
}

builtin/clean.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,5 +1092,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
10921092
strbuf_release(&buf);
10931093
string_list_clear(&del_list, 0);
10941094
string_list_clear(&exclude_list, 0);
1095+
clear_pathspec(&pathspec);
10951096
return (errors != 0);
10961097
}

builtin/clone.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
892892
int is_bundle = 0, is_local;
893893
int reject_shallow = 0;
894894
const char *repo_name, *repo, *work_tree, *git_dir;
895+
char *repo_to_free = NULL;
895896
char *path = NULL, *dir, *display_repo = NULL;
896897
int dest_exists, real_dest_exists = 0;
897898
const struct ref *refs, *remote_head;
@@ -949,7 +950,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
949950
path = get_repo_path(repo_name, &is_bundle);
950951
if (path) {
951952
FREE_AND_NULL(path);
952-
repo = absolute_pathdup(repo_name);
953+
repo = repo_to_free = absolute_pathdup(repo_name);
953954
} else if (strchr(repo_name, ':')) {
954955
repo = repo_name;
955956
display_repo = transport_anonymize_url(repo);
@@ -1417,7 +1418,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
14171418
free(unborn_head);
14181419
free(dir);
14191420
free(path);
1420-
UNLEAK(repo);
1421+
free(repo_to_free);
14211422
junk_mode = JUNK_LEAVE_ALL;
14221423

14231424
transport_ls_refs_options_release(&transport_ls_refs_options);

builtin/commit-graph.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix)
6767
int fd;
6868
struct stat st;
6969
int flags = 0;
70+
int ret;
7071

7172
static struct option builtin_commit_graph_verify_options[] = {
7273
OPT_BOOL(0, "shallow", &opts.shallow,
@@ -111,8 +112,9 @@ static int graph_verify(int argc, const char **argv, const char *prefix)
111112
if (!graph)
112113
return !!open_ok;
113114

114-
UNLEAK(graph);
115-
return verify_commit_graph(the_repository, graph, flags);
115+
ret = verify_commit_graph(the_repository, graph, flags);
116+
free_commit_graph(graph);
117+
return ret;
116118
}
117119

118120
extern int read_replace_refs;
@@ -267,8 +269,8 @@ static int graph_write(int argc, const char **argv, const char *prefix)
267269

268270
if (opts.reachable) {
269271
if (write_commit_graph_reachable(odb, flags, &write_opts))
270-
return 1;
271-
return 0;
272+
result = 1;
273+
goto cleanup;
272274
}
273275

274276
if (opts.stdin_packs) {

builtin/merge.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,7 +1560,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
15601560
!common->next &&
15611561
oideq(&common->item->object.oid, &head_commit->object.oid)) {
15621562
/* Again the most common case of merging one remote. */
1563-
struct strbuf msg = STRBUF_INIT;
1563+
const char *msg = have_message ?
1564+
"Fast-forward (no commit created; -m option ignored)" :
1565+
"Fast-forward";
15641566
struct commit *commit;
15651567

15661568
if (verbosity >= 0) {
@@ -1570,10 +1572,6 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
15701572
find_unique_abbrev(&remoteheads->item->object.oid,
15711573
DEFAULT_ABBREV));
15721574
}
1573-
strbuf_addstr(&msg, "Fast-forward");
1574-
if (have_message)
1575-
strbuf_addstr(&msg,
1576-
" (no commit created; -m option ignored)");
15771575
commit = remoteheads->item;
15781576
if (!commit) {
15791577
ret = 1;
@@ -1592,9 +1590,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
15921590
goto done;
15931591
}
15941592

1595-
finish(head_commit, remoteheads, &commit->object.oid, msg.buf);
1593+
finish(head_commit, remoteheads, &commit->object.oid, msg);
15961594
remove_merge_branch_state(the_repository);
1597-
strbuf_release(&msg);
15981595
goto done;
15991596
} else if (!remoteheads->next && common->next)
16001597
;
@@ -1621,7 +1618,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
16211618
error(_("Your local changes to the following files would be overwritten by merge:\n %s"),
16221619
sb.buf);
16231620
strbuf_release(&sb);
1624-
return 2;
1621+
ret = 2;
1622+
goto done;
16251623
}
16261624

16271625
/* See if it is really trivial. */

builtin/name-rev.c

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -265,17 +265,6 @@ static int subpath_matches(const char *path, const char *filter)
265265
return -1;
266266
}
267267

268-
static const char *name_ref_abbrev(const char *refname, int shorten_unambiguous)
269-
{
270-
if (shorten_unambiguous)
271-
refname = shorten_unambiguous_ref(refname, 0);
272-
else if (skip_prefix(refname, "refs/heads/", &refname))
273-
; /* refname already advanced */
274-
else
275-
skip_prefix(refname, "refs/", &refname);
276-
return refname;
277-
}
278-
279268
struct name_ref_data {
280269
int tags_only;
281270
int name_only;
@@ -301,11 +290,19 @@ static void add_to_tip_table(const struct object_id *oid, const char *refname,
301290
int shorten_unambiguous, struct commit *commit,
302291
timestamp_t taggerdate, int from_tag, int deref)
303292
{
304-
refname = name_ref_abbrev(refname, shorten_unambiguous);
293+
char *short_refname = NULL;
294+
295+
if (shorten_unambiguous)
296+
short_refname = shorten_unambiguous_ref(refname, 0);
297+
else if (skip_prefix(refname, "refs/heads/", &refname))
298+
; /* refname already advanced */
299+
else
300+
skip_prefix(refname, "refs/", &refname);
305301

306302
ALLOC_GROW(tip_table.table, tip_table.nr + 1, tip_table.alloc);
307303
oidcpy(&tip_table.table[tip_table.nr].oid, oid);
308-
tip_table.table[tip_table.nr].refname = xstrdup(refname);
304+
tip_table.table[tip_table.nr].refname = short_refname ?
305+
short_refname : xstrdup(refname);
309306
tip_table.table[tip_table.nr].commit = commit;
310307
tip_table.table[tip_table.nr].taggerdate = taggerdate;
311308
tip_table.table[tip_table.nr].from_tag = from_tag;

builtin/push.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,9 @@ static struct refspec rs = REFSPEC_INIT_PUSH;
6363
static struct string_list push_options_config = STRING_LIST_INIT_DUP;
6464

6565
static void refspec_append_mapped(struct refspec *refspec, const char *ref,
66-
struct remote *remote, struct ref *local_refs)
66+
struct remote *remote, struct ref *matched)
6767
{
6868
const char *branch_name;
69-
struct ref *matched = NULL;
70-
71-
/* Does "ref" uniquely name our ref? */
72-
if (count_refspec_match(ref, local_refs, &matched) != 1) {
73-
refspec_append(refspec, ref);
74-
return;
75-
}
7669

7770
if (remote->push.nr) {
7871
struct refspec_item query;
@@ -120,15 +113,28 @@ static void set_refspecs(const char **refs, int nr, const char *repo)
120113
die(_("--delete only accepts plain target ref names"));
121114
refspec_appendf(&rs, ":%s", ref);
122115
} else if (!strchr(ref, ':')) {
123-
if (!remote) {
124-
/* lazily grab remote and local_refs */
125-
remote = remote_get(repo);
116+
struct ref *matched = NULL;
117+
118+
/* lazily grab local_refs */
119+
if (!local_refs)
126120
local_refs = get_local_heads();
121+
122+
/* Does "ref" uniquely name our ref? */
123+
if (count_refspec_match(ref, local_refs, &matched) != 1) {
124+
refspec_append(&rs, ref);
125+
} else {
126+
/* lazily grab remote */
127+
if (!remote)
128+
remote = remote_get(repo);
129+
if (!remote)
130+
BUG("must get a remote for repo '%s'", repo);
131+
132+
refspec_append_mapped(&rs, ref, remote, matched);
127133
}
128-
refspec_append_mapped(&rs, ref, remote, local_refs);
129134
} else
130135
refspec_append(&rs, ref);
131136
}
137+
free_refs(local_refs);
132138
}
133139

134140
static int push_url_of_remote(struct remote *remote, const char ***url_p)

builtin/receive-pack.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2032,6 +2032,16 @@ static struct command **queue_command(struct command **tail,
20322032
return &cmd->next;
20332033
}
20342034

2035+
static void free_commands(struct command *commands)
2036+
{
2037+
while (commands) {
2038+
struct command *next = commands->next;
2039+
2040+
free(commands);
2041+
commands = next;
2042+
}
2043+
}
2044+
20352045
static void queue_commands_from_cert(struct command **tail,
20362046
struct strbuf *push_cert)
20372047
{
@@ -2569,6 +2579,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
25692579
run_receive_hook(commands, "post-receive", 1,
25702580
&push_options);
25712581
run_update_post_hook(commands);
2582+
free_commands(commands);
25722583
string_list_clear(&push_options, 0);
25732584
if (auto_gc) {
25742585
struct child_process proc = CHILD_PROCESS_INIT;

builtin/repack.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -948,7 +948,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
948948

949949
ret = start_command(&cmd);
950950
if (ret)
951-
return ret;
951+
goto cleanup;
952952

953953
if (geometry) {
954954
FILE *in = xfdopen(cmd.in, "w");
@@ -977,7 +977,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
977977
fclose(out);
978978
ret = finish_command(&cmd);
979979
if (ret)
980-
return ret;
980+
goto cleanup;
981981

982982
if (!names.nr && !po_args.quiet)
983983
printf_ln(_("Nothing new to pack."));
@@ -1007,7 +1007,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
10071007
&existing_nonkept_packs,
10081008
&existing_kept_packs);
10091009
if (ret)
1010-
return ret;
1010+
goto cleanup;
10111011

10121012
if (delete_redundant && expire_to) {
10131013
/*
@@ -1039,7 +1039,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
10391039
&existing_nonkept_packs,
10401040
&existing_kept_packs);
10411041
if (ret)
1042-
return ret;
1042+
goto cleanup;
10431043
}
10441044
}
10451045

@@ -1115,7 +1115,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
11151115
string_list_clear(&include, 0);
11161116

11171117
if (ret)
1118-
return ret;
1118+
goto cleanup;
11191119
}
11201120

11211121
reprepare_packed_git(the_repository);
@@ -1172,10 +1172,11 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
11721172
write_midx_file(get_object_directory(), NULL, NULL, flags);
11731173
}
11741174

1175+
cleanup:
11751176
string_list_clear(&names, 1);
11761177
string_list_clear(&existing_nonkept_packs, 0);
11771178
string_list_clear(&existing_kept_packs, 0);
11781179
clear_pack_geometry(geometry);
11791180

1180-
return 0;
1181+
return ret;
11811182
}

builtin/reset.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -391,8 +391,9 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
391391
if (reset_type != NONE)
392392
die(_("options '%s' and '%s' cannot be used together"), "--patch", "--{hard,mixed,soft}");
393393
trace2_cmd_mode("patch-interactive");
394-
return !!run_add_p(the_repository, ADD_P_RESET, rev,
394+
update_ref_status = !!run_add_p(the_repository, ADD_P_RESET, rev,
395395
&pathspec);
396+
goto cleanup;
396397
}
397398

398399
/* git reset tree [--] paths... can be used to
@@ -441,8 +442,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
441442
LOCK_DIE_ON_ERROR);
442443
if (reset_type == MIXED) {
443444
int flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;
444-
if (read_from_tree(&pathspec, &oid, intent_to_add))
445-
return 1;
445+
if (read_from_tree(&pathspec, &oid, intent_to_add)) {
446+
update_ref_status = 1;
447+
goto cleanup;
448+
}
446449
the_index.updated_skipworktree = 1;
447450
if (!no_refresh && get_git_work_tree()) {
448451
uint64_t t_begin, t_delta_in_ms;
@@ -490,5 +493,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
490493

491494
discard_index(&the_index);
492495

496+
cleanup:
497+
clear_pathspec(&pathspec);
493498
return update_ref_status;
494499
}

0 commit comments

Comments
 (0)