mirror of
https://github.com/git/git.git
synced 2024-11-08 15:19:28 +01:00
builtin/merge: fix leaking struct cmdnames
in get_strategy()
In "builtin/merge.c" we use the helper infrastructure to figure out what merge strategies there are. We never free contents of the `cmdnames` structures though and thus leak their memory. Fix this by exposing the already existing `clean_cmdnames()` function to release their memory. As this name isn't quite idiomatic, rename it to `cmdnames_release()` while at it. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
6e95f4ee03
commit
77241a6b5e
@ -164,7 +164,7 @@ static struct strategy *get_strategy(const char *name)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct strategy *ret;
|
struct strategy *ret;
|
||||||
static struct cmdnames main_cmds, other_cmds;
|
static struct cmdnames main_cmds = {0}, other_cmds = {0};
|
||||||
static int loaded;
|
static int loaded;
|
||||||
char *default_strategy = getenv("GIT_TEST_MERGE_ALGORITHM");
|
char *default_strategy = getenv("GIT_TEST_MERGE_ALGORITHM");
|
||||||
|
|
||||||
@ -182,10 +182,9 @@ static struct strategy *get_strategy(const char *name)
|
|||||||
return &all_strategy[i];
|
return &all_strategy[i];
|
||||||
|
|
||||||
if (!loaded) {
|
if (!loaded) {
|
||||||
struct cmdnames not_strategies;
|
struct cmdnames not_strategies = {0};
|
||||||
loaded = 1;
|
loaded = 1;
|
||||||
|
|
||||||
memset(¬_strategies, 0, sizeof(struct cmdnames));
|
|
||||||
load_command_list("git-merge-", &main_cmds, &other_cmds);
|
load_command_list("git-merge-", &main_cmds, &other_cmds);
|
||||||
for (i = 0; i < main_cmds.cnt; i++) {
|
for (i = 0; i < main_cmds.cnt; i++) {
|
||||||
int j, found = 0;
|
int j, found = 0;
|
||||||
@ -197,6 +196,8 @@ static struct strategy *get_strategy(const char *name)
|
|||||||
add_cmdname(¬_strategies, ent->name, ent->len);
|
add_cmdname(¬_strategies, ent->name, ent->len);
|
||||||
}
|
}
|
||||||
exclude_cmds(&main_cmds, ¬_strategies);
|
exclude_cmds(&main_cmds, ¬_strategies);
|
||||||
|
|
||||||
|
cmdnames_release(¬_strategies);
|
||||||
}
|
}
|
||||||
if (!is_in_cmdlist(&main_cmds, name) && !is_in_cmdlist(&other_cmds, name)) {
|
if (!is_in_cmdlist(&main_cmds, name) && !is_in_cmdlist(&other_cmds, name)) {
|
||||||
fprintf(stderr, _("Could not find merge strategy '%s'.\n"), name);
|
fprintf(stderr, _("Could not find merge strategy '%s'.\n"), name);
|
||||||
@ -216,6 +217,9 @@ static struct strategy *get_strategy(const char *name)
|
|||||||
CALLOC_ARRAY(ret, 1);
|
CALLOC_ARRAY(ret, 1);
|
||||||
ret->name = xstrdup(name);
|
ret->name = xstrdup(name);
|
||||||
ret->attr = NO_TRIVIAL;
|
ret->attr = NO_TRIVIAL;
|
||||||
|
|
||||||
|
cmdnames_release(&main_cmds);
|
||||||
|
cmdnames_release(&other_cmds);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
help.c
12
help.c
@ -157,7 +157,7 @@ void add_cmdname(struct cmdnames *cmds, const char *name, int len)
|
|||||||
cmds->names[cmds->cnt++] = ent;
|
cmds->names[cmds->cnt++] = ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clean_cmdnames(struct cmdnames *cmds)
|
void cmdnames_release(struct cmdnames *cmds)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < cmds->cnt; ++i)
|
for (i = 0; i < cmds->cnt; ++i)
|
||||||
@ -359,8 +359,8 @@ void list_all_main_cmds(struct string_list *list)
|
|||||||
for (i = 0; i < main_cmds.cnt; i++)
|
for (i = 0; i < main_cmds.cnt; i++)
|
||||||
string_list_append(list, main_cmds.names[i]->name);
|
string_list_append(list, main_cmds.names[i]->name);
|
||||||
|
|
||||||
clean_cmdnames(&main_cmds);
|
cmdnames_release(&main_cmds);
|
||||||
clean_cmdnames(&other_cmds);
|
cmdnames_release(&other_cmds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_all_other_cmds(struct string_list *list)
|
void list_all_other_cmds(struct string_list *list)
|
||||||
@ -375,8 +375,8 @@ void list_all_other_cmds(struct string_list *list)
|
|||||||
for (i = 0; i < other_cmds.cnt; i++)
|
for (i = 0; i < other_cmds.cnt; i++)
|
||||||
string_list_append(list, other_cmds.names[i]->name);
|
string_list_append(list, other_cmds.names[i]->name);
|
||||||
|
|
||||||
clean_cmdnames(&main_cmds);
|
cmdnames_release(&main_cmds);
|
||||||
clean_cmdnames(&other_cmds);
|
cmdnames_release(&other_cmds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_cmds_by_category(struct string_list *list,
|
void list_cmds_by_category(struct string_list *list,
|
||||||
@ -689,7 +689,7 @@ const char *help_unknown_cmd(const char *cmd)
|
|||||||
if (autocorrect && n == 1 && SIMILAR_ENOUGH(best_similarity)) {
|
if (autocorrect && n == 1 && SIMILAR_ENOUGH(best_similarity)) {
|
||||||
const char *assumed = main_cmds.names[0]->name;
|
const char *assumed = main_cmds.names[0]->name;
|
||||||
main_cmds.names[0] = NULL;
|
main_cmds.names[0] = NULL;
|
||||||
clean_cmdnames(&main_cmds);
|
cmdnames_release(&main_cmds);
|
||||||
fprintf_ln(stderr,
|
fprintf_ln(stderr,
|
||||||
_("WARNING: You called a Git command named '%s', "
|
_("WARNING: You called a Git command named '%s', "
|
||||||
"which does not exist."),
|
"which does not exist."),
|
||||||
|
2
help.h
2
help.h
@ -13,6 +13,8 @@ struct cmdnames {
|
|||||||
} **names;
|
} **names;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void cmdnames_release(struct cmdnames *cmds);
|
||||||
|
|
||||||
static inline void mput_char(char c, unsigned int num)
|
static inline void mput_char(char c, unsigned int num)
|
||||||
{
|
{
|
||||||
while (num--)
|
while (num--)
|
||||||
|
@ -14,6 +14,7 @@ Testing a custom strategy.
|
|||||||
* (tag: c0) c0
|
* (tag: c0) c0
|
||||||
"
|
"
|
||||||
|
|
||||||
|
TEST_PASSES_SANITIZE_LEAK=true
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
test_expect_success 'set up custom strategy' '
|
test_expect_success 'set up custom strategy' '
|
||||||
|
Loading…
Reference in New Issue
Block a user