Skip to content

Commit f5ccb53

Browse files
pks-tgitster
authored andcommitted
remote: fix leaking config strings
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. This includes config strings for "branch" sections, "insteadOf", "pushInsteadOf", and "pushDefault". Plug those leaks. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 46e4406 commit f5ccb53

File tree

1 file changed

+38
-2
lines changed

1 file changed

+38
-2
lines changed

remote.c

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,17 @@ static struct branch *make_branch(struct remote_state *remote_state,
243243
return ret;
244244
}
245245

246+
static void branch_release(struct branch *branch)
247+
{
248+
free((char *)branch->name);
249+
free((char *)branch->refname);
250+
free(branch->remote_name);
251+
free(branch->pushremote_name);
252+
for (int i = 0; i < branch->merge_nr; i++)
253+
refspec_item_clear(branch->merge[i]);
254+
free(branch->merge);
255+
}
256+
246257
static struct rewrite *make_rewrite(struct rewrites *r,
247258
const char *base, size_t len)
248259
{
@@ -263,6 +274,14 @@ static struct rewrite *make_rewrite(struct rewrites *r,
263274
return ret;
264275
}
265276

277+
static void rewrites_release(struct rewrites *r)
278+
{
279+
for (int i = 0; i < r->rewrite_nr; i++)
280+
free((char *)r->rewrite[i]->base);
281+
free(r->rewrite);
282+
memset(r, 0, sizeof(*r));
283+
}
284+
266285
static void add_instead_of(struct rewrite *rewrite, const char *instead_of)
267286
{
268287
ALLOC_GROW(rewrite->instead_of, rewrite->instead_of_nr + 1, rewrite->instead_of_alloc);
@@ -373,8 +392,10 @@ static int handle_config(const char *key, const char *value,
373392
return -1;
374393
branch = make_branch(remote_state, name, namelen);
375394
if (!strcmp(subkey, "remote")) {
395+
FREE_AND_NULL(branch->remote_name);
376396
return git_config_string(&branch->remote_name, key, value);
377397
} else if (!strcmp(subkey, "pushremote")) {
398+
FREE_AND_NULL(branch->pushremote_name);
378399
return git_config_string(&branch->pushremote_name, key, value);
379400
} else if (!strcmp(subkey, "merge")) {
380401
if (!value)
@@ -406,9 +427,11 @@ static int handle_config(const char *key, const char *value,
406427
return 0;
407428

408429
/* Handle remote.* variables */
409-
if (!name && !strcmp(subkey, "pushdefault"))
430+
if (!name && !strcmp(subkey, "pushdefault")) {
431+
FREE_AND_NULL(remote_state->pushremote_name);
410432
return git_config_string(&remote_state->pushremote_name, key,
411433
value);
434+
}
412435

413436
if (!name)
414437
return 0;
@@ -475,12 +498,15 @@ static int handle_config(const char *key, const char *value,
475498
else if (!strcmp(value, "--tags"))
476499
remote->fetch_tags = 2;
477500
} else if (!strcmp(subkey, "proxy")) {
501+
FREE_AND_NULL(remote->http_proxy);
478502
return git_config_string(&remote->http_proxy,
479503
key, value);
480504
} else if (!strcmp(subkey, "proxyauthmethod")) {
505+
FREE_AND_NULL(remote->http_proxy_authmethod);
481506
return git_config_string(&remote->http_proxy_authmethod,
482507
key, value);
483508
} else if (!strcmp(subkey, "vcs")) {
509+
FREE_AND_NULL(remote->foreign_vcs);
484510
return git_config_string(&remote->foreign_vcs, key, value);
485511
}
486512
return 0;
@@ -2797,16 +2823,26 @@ struct remote_state *remote_state_new(void)
27972823

27982824
void remote_state_clear(struct remote_state *remote_state)
27992825
{
2826+
struct hashmap_iter iter;
2827+
struct branch *b;
28002828
int i;
28012829

28022830
for (i = 0; i < remote_state->remotes_nr; i++)
28032831
remote_clear(remote_state->remotes[i]);
28042832
FREE_AND_NULL(remote_state->remotes);
2833+
FREE_AND_NULL(remote_state->pushremote_name);
28052834
remote_state->remotes_alloc = 0;
28062835
remote_state->remotes_nr = 0;
28072836

2837+
rewrites_release(&remote_state->rewrites);
2838+
rewrites_release(&remote_state->rewrites_push);
2839+
28082840
hashmap_clear_and_free(&remote_state->remotes_hash, struct remote, ent);
2809-
hashmap_clear_and_free(&remote_state->branches_hash, struct remote, ent);
2841+
hashmap_for_each_entry(&remote_state->branches_hash, &iter, b, ent) {
2842+
branch_release(b);
2843+
free(b);
2844+
}
2845+
hashmap_clear(&remote_state->branches_hash);
28102846
}
28112847

28122848
/*

0 commit comments

Comments
 (0)