Skip to content

Commit 4385f8a

Browse files
committed
Merge branch 'ps/leakfixes-part-3'
More leakfixes. * ps/leakfixes-part-3: (24 commits) commit-reach: fix trivial memory leak when computing reachability convert: fix leaking config strings entry: fix leaking pathnames during delayed checkout object-name: fix leaking commit list items t/test-repository: fix leaking repository builtin/credential-cache: fix trivial leaks builtin/worktree: fix leaking derived branch names builtin/shortlog: fix various trivial memory leaks builtin/rerere: fix various trivial memory leaks builtin/credential-store: fix leaking credential builtin/show-branch: fix several memory leaks builtin/rev-parse: fix memory leak with `--parseopt` builtin/stash: fix various trivial memory leaks builtin/remote: fix various trivial memory leaks builtin/remote: fix leaking strings in `branch_list` builtin/ls-remote: fix leaking `pattern` strings builtin/submodule--helper: fix leaking buffer in `is_tip_reachable` builtin/submodule--helper: fix leaking clone depth parameter builtin/name-rev: fix various trivial memory leaks builtin/describe: fix trivial memory leak when describing blob ...
2 parents 25673b1 + f30bfaf commit 4385f8a

Some content is hidden

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

57 files changed

+256
-88
lines changed

builtin/credential-cache.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ static void spawn_daemon(const char *socket)
8888
die_errno("unable to read result code from cache daemon");
8989
if (r != 3 || memcmp(buf, "ok\n", 3))
9090
die("cache daemon did not start: %.*s", r, buf);
91+
92+
child_process_clear(&daemon);
9193
close(daemon.out);
9294
}
9395

@@ -137,7 +139,8 @@ static void announce_capabilities(void)
137139

138140
int cmd_credential_cache(int argc, const char **argv, const char *prefix)
139141
{
140-
char *socket_path = NULL;
142+
const char *socket_path_arg = NULL;
143+
char *socket_path;
141144
int timeout = 900;
142145
const char *op;
143146
const char * const usage[] = {
@@ -147,7 +150,7 @@ int cmd_credential_cache(int argc, const char **argv, const char *prefix)
147150
struct option options[] = {
148151
OPT_INTEGER(0, "timeout", &timeout,
149152
"number of seconds to cache credentials"),
150-
OPT_STRING(0, "socket", &socket_path, "path",
153+
OPT_STRING(0, "socket", &socket_path_arg, "path",
151154
"path of cache-daemon socket"),
152155
OPT_END()
153156
};
@@ -160,6 +163,7 @@ int cmd_credential_cache(int argc, const char **argv, const char *prefix)
160163
if (!have_unix_sockets())
161164
die(_("credential-cache unavailable; no unix socket support"));
162165

166+
socket_path = xstrdup_or_null(socket_path_arg);
163167
if (!socket_path)
164168
socket_path = get_socket_path();
165169
if (!socket_path)
@@ -176,6 +180,7 @@ int cmd_credential_cache(int argc, const char **argv, const char *prefix)
176180
else
177181
; /* ignore unknown operation */
178182

183+
free(socket_path);
179184
return 0;
180185
}
181186

builtin/credential-store.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,5 +218,6 @@ int cmd_credential_store(int argc, const char **argv, const char *prefix)
218218
; /* Ignore unknown operation. */
219219

220220
string_list_clear(&fns, 0);
221+
credential_clear(&c);
221222
return 0;
222223
}

builtin/describe.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,7 @@ static void describe_blob(struct object_id oid, struct strbuf *dst)
529529
traverse_commit_list(&revs, process_commit, process_object, &pcd);
530530
reset_revision_walk();
531531
release_revisions(&revs);
532+
strvec_clear(&args);
532533
}
533534

534535
static void describe(const char *arg, int last_one)
@@ -619,6 +620,8 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
619620
if (contains) {
620621
struct string_list_item *item;
621622
struct strvec args;
623+
const char **argv_copy;
624+
int ret;
622625

623626
strvec_init(&args);
624627
strvec_pushl(&args, "name-rev",
@@ -637,7 +640,21 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
637640
strvec_pushv(&args, argv);
638641
else
639642
strvec_push(&args, "HEAD");
640-
return cmd_name_rev(args.nr, args.v, prefix);
643+
644+
/*
645+
* `cmd_name_rev()` modifies the array, so we'd leak its
646+
* contained strings if we didn't do a copy here.
647+
*/
648+
ALLOC_ARRAY(argv_copy, args.nr + 1);
649+
for (size_t i = 0; i < args.nr; i++)
650+
argv_copy[i] = args.v[i];
651+
argv_copy[args.nr] = NULL;
652+
653+
ret = cmd_name_rev(args.nr, argv_copy, prefix);
654+
655+
strvec_clear(&args);
656+
free(argv_copy);
657+
return ret;
641658
}
642659

643660
hashmap_init(&names, commit_name_neq, NULL, 0);
@@ -679,7 +696,6 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
679696
} else if (dirty) {
680697
struct lock_file index_lock = LOCK_INIT;
681698
struct rev_info revs;
682-
struct strvec args = STRVEC_INIT;
683699
int fd;
684700

685701
setup_work_tree();
@@ -694,8 +710,9 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
694710
repo_update_index_if_able(the_repository, &index_lock);
695711

696712
repo_init_revisions(the_repository, &revs, prefix);
697-
strvec_pushv(&args, diff_index_args);
698-
if (setup_revisions(args.nr, args.v, &revs, NULL) != 1)
713+
714+
if (setup_revisions(ARRAY_SIZE(diff_index_args) - 1,
715+
diff_index_args, &revs, NULL) != 1)
699716
BUG("malformed internal diff-index command line");
700717
run_diff_index(&revs, 0);
701718

builtin/log.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1434,6 +1434,7 @@ static void make_cover_letter(struct rev_info *rev, int use_separate_file,
14341434
int need_8bit_cte = 0;
14351435
struct pretty_print_context pp = {0};
14361436
struct commit *head = list[0];
1437+
char *to_free = NULL;
14371438

14381439
if (!cmit_fmt_is_mail(rev->commit_format))
14391440
die(_("cover letter needs email format"));
@@ -1455,7 +1456,7 @@ static void make_cover_letter(struct rev_info *rev, int use_separate_file,
14551456
}
14561457

14571458
if (!branch_name)
1458-
branch_name = find_branch_name(rev);
1459+
branch_name = to_free = find_branch_name(rev);
14591460

14601461
pp.fmt = CMIT_FMT_EMAIL;
14611462
pp.date_mode.type = DATE_RFC2822;
@@ -1466,6 +1467,7 @@ static void make_cover_letter(struct rev_info *rev, int use_separate_file,
14661467
encoding, need_8bit_cte, cfg);
14671468
fprintf(rev->diffopt.file, "%s\n", sb.buf);
14681469

1470+
free(to_free);
14691471
free(pp.after_subject);
14701472
strbuf_release(&sb);
14711473

builtin/ls-remote.c

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,16 @@ static const char * const ls_remote_usage[] = {
1919
* Is there one among the list of patterns that match the tail part
2020
* of the path?
2121
*/
22-
static int tail_match(const char **pattern, const char *path)
22+
static int tail_match(const struct strvec *pattern, const char *path)
2323
{
24-
const char *p;
2524
char *pathbuf;
2625

27-
if (!pattern)
26+
if (!pattern->nr)
2827
return 1; /* no restriction */
2928

3029
pathbuf = xstrfmt("/%s", path);
31-
while ((p = *(pattern++)) != NULL) {
32-
if (!wildmatch(p, pathbuf, 0)) {
30+
for (size_t i = 0; i < pattern->nr; i++) {
31+
if (!wildmatch(pattern->v[i], pathbuf, 0)) {
3332
free(pathbuf);
3433
return 1;
3534
}
@@ -47,7 +46,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
4746
int status = 0;
4847
int show_symref_target = 0;
4948
const char *uploadpack = NULL;
50-
const char **pattern = NULL;
49+
struct strvec pattern = STRVEC_INIT;
5150
struct transport_ls_refs_options transport_options =
5251
TRANSPORT_LS_REFS_OPTIONS_INIT;
5352
int i;
@@ -93,13 +92,8 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
9392

9493
packet_trace_identity("ls-remote");
9594

96-
if (argc > 1) {
97-
int i;
98-
CALLOC_ARRAY(pattern, argc);
99-
for (i = 1; i < argc; i++) {
100-
pattern[i - 1] = xstrfmt("*/%s", argv[i]);
101-
}
102-
}
95+
for (int i = 1; i < argc; i++)
96+
strvec_pushf(&pattern, "*/%s", argv[i]);
10397

10498
if (flags & REF_TAGS)
10599
strvec_push(&transport_options.ref_prefixes, "refs/tags/");
@@ -136,7 +130,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
136130
struct ref_array_item *item;
137131
if (!check_ref_type(ref, flags))
138132
continue;
139-
if (!tail_match(pattern, ref->name))
133+
if (!tail_match(&pattern, ref->name))
140134
continue;
141135
item = ref_array_push(&ref_array, ref->name, &ref->old_oid);
142136
item->symref = xstrdup_or_null(ref->symref);
@@ -158,5 +152,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
158152
if (transport_disconnect(transport))
159153
status = 1;
160154
transport_ls_refs_options_release(&transport_options);
155+
156+
strvec_clear(&pattern);
161157
return status;
162158
}

builtin/name-rev.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,9 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
677677
always, allow_undefined, data.name_only);
678678
}
679679

680-
UNLEAK(string_pool);
681-
UNLEAK(revs);
680+
string_list_clear(&data.ref_filters, 0);
681+
string_list_clear(&data.exclude_filters, 0);
682+
mem_pool_discard(&string_pool, 0);
683+
object_array_clear(&revs);
682684
return 0;
683685
}

builtin/remote.c

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ struct branch_info {
258258
char *push_remote_name;
259259
};
260260

261-
static struct string_list branch_list = STRING_LIST_INIT_NODUP;
261+
static struct string_list branch_list = STRING_LIST_INIT_DUP;
262262

263263
static const char *abbrev_ref(const char *name, const char *prefix)
264264
{
@@ -292,8 +292,8 @@ static int config_read_branches(const char *key, const char *value,
292292
type = PUSH_REMOTE;
293293
else
294294
return 0;
295-
name = xmemdupz(key, key_len);
296295

296+
name = xmemdupz(key, key_len);
297297
item = string_list_insert(&branch_list, name);
298298

299299
if (!item->util)
@@ -337,6 +337,7 @@ static int config_read_branches(const char *key, const char *value,
337337
BUG("unexpected type=%d", type);
338338
}
339339

340+
free(name);
340341
return 0;
341342
}
342343

@@ -554,13 +555,16 @@ static int add_branch_for_removal(const char *refname,
554555
refspec.dst = (char *)refname;
555556
if (remote_find_tracking(branches->remote, &refspec))
556557
return 0;
558+
free(refspec.src);
557559

558560
/* don't delete a branch if another remote also uses it */
559561
for (kr = branches->keep->list; kr; kr = kr->next) {
560562
memset(&refspec, 0, sizeof(refspec));
561563
refspec.dst = (char *)refname;
562-
if (!remote_find_tracking(kr->remote, &refspec))
564+
if (!remote_find_tracking(kr->remote, &refspec)) {
565+
free(refspec.src);
563566
return 0;
567+
}
564568
}
565569

566570
/* don't delete non-remote-tracking refs */
@@ -667,7 +671,11 @@ static int config_read_push_default(const char *key, const char *value,
667671
static void handle_push_default(const char* old_name, const char* new_name)
668672
{
669673
struct push_default_info push_default = {
670-
old_name, CONFIG_SCOPE_UNKNOWN, STRBUF_INIT, -1 };
674+
.old_name = old_name,
675+
.scope = CONFIG_SCOPE_UNKNOWN,
676+
.origin = STRBUF_INIT,
677+
.linenr = -1,
678+
};
671679
git_config(config_read_push_default, &push_default);
672680
if (push_default.scope >= CONFIG_SCOPE_COMMAND)
673681
; /* pass */
@@ -687,6 +695,8 @@ static void handle_push_default(const char* old_name, const char* new_name)
687695
push_default.origin.buf, push_default.linenr,
688696
old_name);
689697
}
698+
699+
strbuf_release(&push_default.origin);
690700
}
691701

692702

@@ -784,7 +794,7 @@ static int mv(int argc, const char **argv, const char *prefix)
784794
}
785795

786796
if (!refspec_updated)
787-
return 0;
797+
goto out;
788798

789799
/*
790800
* First remove symrefs, then rename the rest, finally create
@@ -850,10 +860,15 @@ static int mv(int argc, const char **argv, const char *prefix)
850860
display_progress(progress, ++refs_renamed_nr);
851861
}
852862
stop_progress(&progress);
853-
string_list_clear(&remote_branches, 1);
854863

855864
handle_push_default(rename.old_name, rename.new_name);
856865

866+
out:
867+
string_list_clear(&remote_branches, 1);
868+
strbuf_release(&old_remote_context);
869+
strbuf_release(&buf);
870+
strbuf_release(&buf2);
871+
strbuf_release(&buf3);
857872
return 0;
858873
}
859874

@@ -944,12 +959,21 @@ static int rm(int argc, const char **argv, const char *prefix)
944959

945960
if (!result) {
946961
strbuf_addf(&buf, "remote.%s", remote->name);
947-
if (git_config_rename_section(buf.buf, NULL) < 1)
948-
return error(_("Could not remove config section '%s'"), buf.buf);
962+
if (git_config_rename_section(buf.buf, NULL) < 1) {
963+
result = error(_("Could not remove config section '%s'"), buf.buf);
964+
goto out;
965+
}
949966

950967
handle_push_default(remote->name, NULL);
951968
}
952969

970+
out:
971+
for (struct known_remote *r = known_remotes.list; r;) {
972+
struct known_remote *next = r->next;
973+
free(r);
974+
r = next;
975+
}
976+
strbuf_release(&buf);
953977
return result;
954978
}
955979

@@ -982,8 +1006,10 @@ static int append_ref_to_tracked_list(const char *refname,
9821006

9831007
memset(&refspec, 0, sizeof(refspec));
9841008
refspec.dst = (char *)refname;
985-
if (!remote_find_tracking(states->remote, &refspec))
1009+
if (!remote_find_tracking(states->remote, &refspec)) {
9861010
string_list_append(&states->tracked, abbrev_branch(refspec.src));
1011+
free(refspec.src);
1012+
}
9871013

9881014
return 0;
9891015
}

0 commit comments

Comments
 (0)