Merge branch 'jk/leakfix'

Code clean-up.

* jk/leakfix:
  submodule--helper: fix leak of core.worktree value
  config: fix leak in git_config_get_expiry_in_days()
  config: drop git_config_get_string_const()
  config: fix leaks from git_config_get_string_const()
  checkout: fix leak of non-existent branch names
  submodule--helper: use strbuf_release() to free strbufs
  clear_pattern_list(): clear embedded hashmaps
This commit is contained in:
Junio C Hamano 2020-08-27 14:04:49 -07:00
commit 0d9a8e33f9
17 changed files with 70 additions and 53 deletions

View File

@ -319,14 +319,14 @@ function body:
... ...
git_config(git_default_config, NULL); git_config(git_default_config, NULL);
if (git_config_get_string_const("user.name", &cfg_name) > 0) if (git_config_get_string_tmp("user.name", &cfg_name) > 0)
printf(_("No name is found in config\n")); printf(_("No name is found in config\n"));
else else
printf(_("Your name: %s\n"), cfg_name); printf(_("Your name: %s\n"), cfg_name);
---- ----
`git_config()` will grab the configuration from config files known to Git and `git_config()` will grab the configuration from config files known to Git and
apply standard precedence rules. `git_config_get_string_const()` will look up apply standard precedence rules. `git_config_get_string_tmp()` will look up
a specific key ("user.name") and give you the value. There are a number of a specific key ("user.name") and give you the value. There are a number of
single-key lookup functions like this one; you can see them all (and more info single-key lookup functions like this one; you can see them all (and more info
about how to use `git_config()`) in `Documentation/technical/api-config.txt`. about how to use `git_config()`) in `Documentation/technical/api-config.txt`.

View File

@ -30,8 +30,8 @@ struct gitdiff_data {
static void git_apply_config(void) static void git_apply_config(void)
{ {
git_config_get_string_const("apply.whitespace", &apply_default_whitespace); git_config_get_string("apply.whitespace", &apply_default_whitespace);
git_config_get_string_const("apply.ignorewhitespace", &apply_default_ignorewhitespace); git_config_get_string("apply.ignorewhitespace", &apply_default_ignorewhitespace);
git_config(git_xmerge_config, NULL); git_config(git_xmerge_config, NULL);
} }

View File

@ -1120,8 +1120,10 @@ static void setup_new_branch_info_and_source_tree(
if (!check_refname_format(new_branch_info->path, 0) && if (!check_refname_format(new_branch_info->path, 0) &&
!read_ref(new_branch_info->path, &branch_rev)) !read_ref(new_branch_info->path, &branch_rev))
oidcpy(rev, &branch_rev); oidcpy(rev, &branch_rev);
else else {
free((char *)new_branch_info->path);
new_branch_info->path = NULL; /* not an existing branch */ new_branch_info->path = NULL; /* not an existing branch */
}
new_branch_info->commit = lookup_commit_reference_gently(the_repository, rev, 1); new_branch_info->commit = lookup_commit_reference_gently(the_repository, rev, 1);
if (!new_branch_info->commit) { if (!new_branch_info->commit) {

View File

@ -648,7 +648,7 @@ static void prepare_format_display(struct ref *ref_map)
struct ref *rm; struct ref *rm;
const char *format = "full"; const char *format = "full";
git_config_get_string_const("fetch.output", &format); git_config_get_string_tmp("fetch.output", &format);
if (!strcasecmp(format, "full")) if (!strcasecmp(format, "full"))
compact_format = 0; compact_format = 0;
else if (!strcasecmp(format, "compact")) else if (!strcasecmp(format, "compact"))

View File

@ -1511,7 +1511,7 @@ static void determine_submodule_update_strategy(struct repository *r,
if (parse_submodule_update_strategy(update, out) < 0) if (parse_submodule_update_strategy(update, out) < 0)
die(_("Invalid update mode '%s' for submodule path '%s'"), die(_("Invalid update mode '%s' for submodule path '%s'"),
update, path); update, path);
} else if (!repo_config_get_string_const(r, key, &val)) { } else if (!repo_config_get_string_tmp(r, key, &val)) {
if (parse_submodule_update_strategy(val, out) < 0) if (parse_submodule_update_strategy(val, out) < 0)
die(_("Invalid update mode '%s' configured for submodule path '%s'"), die(_("Invalid update mode '%s' configured for submodule path '%s'"),
val, path); val, path);
@ -1667,7 +1667,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
} }
key = xstrfmt("submodule.%s.update", sub->name); key = xstrfmt("submodule.%s.update", sub->name);
if (!repo_config_get_string_const(the_repository, key, &update_string)) { if (!repo_config_get_string_tmp(the_repository, key, &update_string)) {
update_type = parse_submodule_update_type(update_string); update_type = parse_submodule_update_type(update_string);
} else { } else {
update_type = sub->update_strategy.type; update_type = sub->update_strategy.type;
@ -1690,7 +1690,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
strbuf_reset(&sb); strbuf_reset(&sb);
strbuf_addf(&sb, "submodule.%s.url", sub->name); strbuf_addf(&sb, "submodule.%s.url", sub->name);
if (repo_config_get_string_const(the_repository, sb.buf, &url)) { if (repo_config_get_string_tmp(the_repository, sb.buf, &url)) {
if (starts_with_dot_slash(sub->url) || if (starts_with_dot_slash(sub->url) ||
starts_with_dot_dot_slash(sub->url)) { starts_with_dot_dot_slash(sub->url)) {
url = compute_submodule_clone_url(sub->url); url = compute_submodule_clone_url(sub->url);
@ -1747,8 +1747,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
"--no-single-branch"); "--no-single-branch");
cleanup: cleanup:
strbuf_reset(&displaypath_sb); strbuf_release(&displaypath_sb);
strbuf_reset(&sb); strbuf_release(&sb);
if (need_free_url) if (need_free_url)
free((void*)url); free((void*)url);
@ -1976,7 +1976,7 @@ static const char *remote_submodule_branch(const char *path)
return NULL; return NULL;
key = xstrfmt("submodule.%s.branch", sub->name); key = xstrfmt("submodule.%s.branch", sub->name);
if (repo_config_get_string_const(the_repository, key, &branch)) if (repo_config_get_string_tmp(the_repository, key, &branch))
branch = sub->branch; branch = sub->branch;
free(key); free(key);
@ -2101,7 +2101,7 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
{ {
const struct submodule *sub; const struct submodule *sub;
const char *path; const char *path;
char *cw; const char *cw;
struct repository subrepo; struct repository subrepo;
if (argc != 2) if (argc != 2)
@ -2116,7 +2116,7 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
if (repo_submodule_init(&subrepo, the_repository, sub)) if (repo_submodule_init(&subrepo, the_repository, sub))
die(_("could not get a repository handle for submodule '%s'"), path); die(_("could not get a repository handle for submodule '%s'"), path);
if (!repo_config_get_string(&subrepo, "core.worktree", &cw)) { if (!repo_config_get_string_tmp(&subrepo, "core.worktree", &cw)) {
char *cfg_file, *abs_path; char *cfg_file, *abs_path;
const char *rel_path; const char *rel_path;
struct strbuf sb = STRBUF_INIT; struct strbuf sb = STRBUF_INIT;

View File

@ -921,8 +921,8 @@ extern int assume_unchanged;
extern int prefer_symlink_refs; extern int prefer_symlink_refs;
extern int warn_ambiguous_refs; extern int warn_ambiguous_refs;
extern int warn_on_object_refname_ambiguity; extern int warn_on_object_refname_ambiguity;
extern const char *apply_default_whitespace; extern char *apply_default_whitespace;
extern const char *apply_default_ignorewhitespace; extern char *apply_default_ignorewhitespace;
extern const char *git_attributes_file; extern const char *git_attributes_file;
extern const char *git_hooks_path; extern const char *git_hooks_path;
extern int zlib_compression_level; extern int zlib_compression_level;

View File

@ -47,7 +47,7 @@ const char *unique_tracking_name(const char *name, struct object_id *oid,
{ {
struct tracking_name_data cb_data = TRACKING_NAME_DATA_INIT; struct tracking_name_data cb_data = TRACKING_NAME_DATA_INIT;
const char *default_remote = NULL; const char *default_remote = NULL;
if (!git_config_get_string_const("checkout.defaultremote", &default_remote)) if (!git_config_get_string_tmp("checkout.defaultremote", &default_remote))
cb_data.default_remote = default_remote; cb_data.default_remote = default_remote;
cb_data.src_ref = xstrfmt("refs/heads/%s", name); cb_data.src_ref = xstrfmt("refs/heads/%s", name);
cb_data.dst_oid = oid; cb_data.dst_oid = oid;
@ -55,7 +55,6 @@ const char *unique_tracking_name(const char *name, struct object_id *oid,
if (dwim_remotes_matched) if (dwim_remotes_matched)
*dwim_remotes_matched = cb_data.num_matches; *dwim_remotes_matched = cb_data.num_matches;
free(cb_data.src_ref); free(cb_data.src_ref);
free((char *)default_remote);
if (cb_data.num_matches == 1) { if (cb_data.num_matches == 1) {
free(cb_data.default_dst_ref); free(cb_data.default_dst_ref);
free(cb_data.default_dst_oid); free(cb_data.default_dst_oid);

View File

@ -2006,18 +2006,27 @@ const struct string_list *git_configset_get_value_multi(struct config_set *cs, c
return e ? &e->value_list : NULL; return e ? &e->value_list : NULL;
} }
int git_configset_get_string_const(struct config_set *cs, const char *key, const char **dest) int git_configset_get_string(struct config_set *cs, const char *key, char **dest)
{ {
const char *value; const char *value;
if (!git_configset_get_value(cs, key, &value)) if (!git_configset_get_value(cs, key, &value))
return git_config_string(dest, key, value); return git_config_string((const char **)dest, key, value);
else else
return 1; return 1;
} }
int git_configset_get_string(struct config_set *cs, const char *key, char **dest) int git_configset_get_string_tmp(struct config_set *cs, const char *key,
const char **dest)
{ {
return git_configset_get_string_const(cs, key, (const char **)dest); const char *value;
if (!git_configset_get_value(cs, key, &value)) {
if (!value)
return config_error_nonbool(key);
*dest = value;
return 0;
} else {
return 1;
}
} }
int git_configset_get_int(struct config_set *cs, const char *key, int *dest) int git_configset_get_int(struct config_set *cs, const char *key, int *dest)
@ -2147,22 +2156,26 @@ const struct string_list *repo_config_get_value_multi(struct repository *repo,
return git_configset_get_value_multi(repo->config, key); return git_configset_get_value_multi(repo->config, key);
} }
int repo_config_get_string_const(struct repository *repo, int repo_config_get_string(struct repository *repo,
const char *key, const char **dest) const char *key, char **dest)
{ {
int ret; int ret;
git_config_check_init(repo); git_config_check_init(repo);
ret = git_configset_get_string_const(repo->config, key, dest); ret = git_configset_get_string(repo->config, key, dest);
if (ret < 0) if (ret < 0)
git_die_config(key, NULL); git_die_config(key, NULL);
return ret; return ret;
} }
int repo_config_get_string(struct repository *repo, int repo_config_get_string_tmp(struct repository *repo,
const char *key, char **dest) const char *key, const char **dest)
{ {
int ret;
git_config_check_init(repo); git_config_check_init(repo);
return repo_config_get_string_const(repo, key, (const char **)dest); ret = git_configset_get_string_tmp(repo->config, key, dest);
if (ret < 0)
git_die_config(key, NULL);
return ret;
} }
int repo_config_get_int(struct repository *repo, int repo_config_get_int(struct repository *repo,
@ -2232,16 +2245,16 @@ const struct string_list *git_config_get_value_multi(const char *key)
return repo_config_get_value_multi(the_repository, key); return repo_config_get_value_multi(the_repository, key);
} }
int git_config_get_string_const(const char *key, const char **dest)
{
return repo_config_get_string_const(the_repository, key, dest);
}
int git_config_get_string(const char *key, char **dest) int git_config_get_string(const char *key, char **dest)
{ {
return repo_config_get_string(the_repository, key, dest); return repo_config_get_string(the_repository, key, dest);
} }
int git_config_get_string_tmp(const char *key, const char **dest)
{
return repo_config_get_string_tmp(the_repository, key, dest);
}
int git_config_get_int(const char *key, int *dest) int git_config_get_int(const char *key, int *dest)
{ {
return repo_config_get_int(the_repository, key, dest); return repo_config_get_int(the_repository, key, dest);
@ -2274,7 +2287,7 @@ int git_config_get_pathname(const char *key, const char **dest)
int git_config_get_expiry(const char *key, const char **output) int git_config_get_expiry(const char *key, const char **output)
{ {
int ret = git_config_get_string_const(key, output); int ret = git_config_get_string(key, (char **)output);
if (ret) if (ret)
return ret; return ret;
if (strcmp(*output, "now")) { if (strcmp(*output, "now")) {
@ -2287,11 +2300,11 @@ int git_config_get_expiry(const char *key, const char **output)
int git_config_get_expiry_in_days(const char *key, timestamp_t *expiry, timestamp_t now) int git_config_get_expiry_in_days(const char *key, timestamp_t *expiry, timestamp_t now)
{ {
char *expiry_string; const char *expiry_string;
intmax_t days; intmax_t days;
timestamp_t when; timestamp_t when;
if (git_config_get_string(key, &expiry_string)) if (git_config_get_string_tmp(key, &expiry_string))
return 1; /* no such thing */ return 1; /* no such thing */
if (git_parse_signed(expiry_string, &days, maximum_signed_value_of_type(int))) { if (git_parse_signed(expiry_string, &days, maximum_signed_value_of_type(int))) {

View File

@ -458,8 +458,8 @@ void git_configset_clear(struct config_set *cs);
*/ */
int git_configset_get_value(struct config_set *cs, const char *key, const char **dest); int git_configset_get_value(struct config_set *cs, const char *key, const char **dest);
int git_configset_get_string_const(struct config_set *cs, const char *key, const char **dest);
int git_configset_get_string(struct config_set *cs, const char *key, char **dest); int git_configset_get_string(struct config_set *cs, const char *key, char **dest);
int git_configset_get_string_tmp(struct config_set *cs, const char *key, const char **dest);
int git_configset_get_int(struct config_set *cs, const char *key, int *dest); int git_configset_get_int(struct config_set *cs, const char *key, int *dest);
int git_configset_get_ulong(struct config_set *cs, const char *key, unsigned long *dest); int git_configset_get_ulong(struct config_set *cs, const char *key, unsigned long *dest);
int git_configset_get_bool(struct config_set *cs, const char *key, int *dest); int git_configset_get_bool(struct config_set *cs, const char *key, int *dest);
@ -474,10 +474,10 @@ int repo_config_get_value(struct repository *repo,
const char *key, const char **value); const char *key, const char **value);
const struct string_list *repo_config_get_value_multi(struct repository *repo, const struct string_list *repo_config_get_value_multi(struct repository *repo,
const char *key); const char *key);
int repo_config_get_string_const(struct repository *repo,
const char *key, const char **dest);
int repo_config_get_string(struct repository *repo, int repo_config_get_string(struct repository *repo,
const char *key, char **dest); const char *key, char **dest);
int repo_config_get_string_tmp(struct repository *repo,
const char *key, const char **dest);
int repo_config_get_int(struct repository *repo, int repo_config_get_int(struct repository *repo,
const char *key, int *dest); const char *key, int *dest);
int repo_config_get_ulong(struct repository *repo, int repo_config_get_ulong(struct repository *repo,
@ -529,13 +529,14 @@ void git_config_clear(void);
* error message and returns -1. When the configuration variable `key` is * error message and returns -1. When the configuration variable `key` is
* not found, returns 1 without touching `dest`. * not found, returns 1 without touching `dest`.
*/ */
int git_config_get_string_const(const char *key, const char **dest); int git_config_get_string(const char *key, char **dest);
/** /**
* Similar to `git_config_get_string_const`, except that retrieved value * Similar to `git_config_get_string`, but does not allocate any new
* copied into the `dest` parameter is a mutable string. * memory; on success `dest` will point to memory owned by the config
* machinery, which could be invalidated if it is discarded and reloaded.
*/ */
int git_config_get_string(const char *key, char **dest); int git_config_get_string_tmp(const char *key, const char **dest);
/** /**
* Finds and parses the value to an integer for the configuration variable * Finds and parses the value to an integer for the configuration variable

View File

@ -1052,7 +1052,7 @@ static const char *get_ssh_command(void)
if ((ssh = getenv("GIT_SSH_COMMAND"))) if ((ssh = getenv("GIT_SSH_COMMAND")))
return ssh; return ssh;
if (!git_config_get_string_const("core.sshcommand", &ssh)) if (!git_config_get_string_tmp("core.sshcommand", &ssh))
return ssh; return ssh;
return NULL; return NULL;
@ -1071,7 +1071,7 @@ static void override_ssh_variant(enum ssh_variant *ssh_variant)
{ {
const char *variant = getenv("GIT_SSH_VARIANT"); const char *variant = getenv("GIT_SSH_VARIANT");
if (!variant && git_config_get_string_const("ssh.variant", &variant)) if (!variant && git_config_get_string_tmp("ssh.variant", &variant))
return; return;
if (!strcmp(variant, "auto")) if (!strcmp(variant, "auto"))

2
dir.c
View File

@ -921,6 +921,8 @@ void clear_pattern_list(struct pattern_list *pl)
free(pl->patterns[i]); free(pl->patterns[i]);
free(pl->patterns); free(pl->patterns);
free(pl->filebuf); free(pl->filebuf);
hashmap_free_entries(&pl->recursive_hashmap, struct pattern_entry, ent);
hashmap_free_entries(&pl->parent_hashmap, struct pattern_entry, ent);
memset(pl, 0, sizeof(*pl)); memset(pl, 0, sizeof(*pl));
} }

View File

@ -40,7 +40,7 @@ const char *git_sequence_editor(void)
const char *editor = getenv("GIT_SEQUENCE_EDITOR"); const char *editor = getenv("GIT_SEQUENCE_EDITOR");
if (!editor) if (!editor)
git_config_get_string_const("sequence.editor", &editor); git_config_get_string_tmp("sequence.editor", &editor);
if (!editor) if (!editor)
editor = git_editor(); editor = git_editor();

View File

@ -35,8 +35,8 @@ int repository_format_precious_objects;
int repository_format_worktree_config; int repository_format_worktree_config;
const char *git_commit_encoding; const char *git_commit_encoding;
const char *git_log_output_encoding; const char *git_log_output_encoding;
const char *apply_default_whitespace; char *apply_default_whitespace;
const char *apply_default_ignorewhitespace; char *apply_default_ignorewhitespace;
const char *git_attributes_file; const char *git_attributes_file;
const char *git_hooks_path; const char *git_hooks_path;
int zlib_compression_level = Z_BEST_SPEED; int zlib_compression_level = Z_BEST_SPEED;

2
help.c
View File

@ -375,7 +375,7 @@ void list_cmds_by_config(struct string_list *list)
{ {
const char *cmd_list; const char *cmd_list;
if (git_config_get_string_const("completion.commands", &cmd_list)) if (git_config_get_string_tmp("completion.commands", &cmd_list))
return; return;
string_list_sort(list); string_list_sort(list);

View File

@ -21,7 +21,7 @@ enum protocol_version get_protocol_version_config(void)
const char *git_test_k = "GIT_TEST_PROTOCOL_VERSION"; const char *git_test_k = "GIT_TEST_PROTOCOL_VERSION";
const char *git_test_v; const char *git_test_v;
if (!git_config_get_string_const("protocol.version", &value)) { if (!git_config_get_string_tmp("protocol.version", &value)) {
enum protocol_version version = parse_protocol_version(value); enum protocol_version version = parse_protocol_version(value);
if (version == protocol_unknown_version) if (version == protocol_unknown_version)

View File

@ -194,7 +194,7 @@ void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
char *key; char *key;
key = xstrfmt("submodule.%s.ignore", submodule->name); key = xstrfmt("submodule.%s.ignore", submodule->name);
if (repo_config_get_string_const(the_repository, key, &ignore)) if (repo_config_get_string_tmp(the_repository, key, &ignore))
ignore = submodule->ignore; ignore = submodule->ignore;
free(key); free(key);
@ -1299,7 +1299,7 @@ static int get_fetch_recurse_config(const struct submodule *submodule,
int fetch_recurse = submodule->fetch_recurse; int fetch_recurse = submodule->fetch_recurse;
key = xstrfmt("submodule.%s.fetchRecurseSubmodules", submodule->name); key = xstrfmt("submodule.%s.fetchRecurseSubmodules", submodule->name);
if (!repo_config_get_string_const(spf->r, key, &value)) { if (!repo_config_get_string_tmp(spf->r, key, &value)) {
fetch_recurse = parse_fetch_recurse_submodules_arg(key, value); fetch_recurse = parse_fetch_recurse_submodules_arg(key, value);
} }
free(key); free(key);

View File

@ -126,7 +126,7 @@ int cmd__config(int argc, const char **argv)
goto exit1; goto exit1;
} }
} else if (argc == 3 && !strcmp(argv[1], "get_string")) { } else if (argc == 3 && !strcmp(argv[1], "get_string")) {
if (!git_config_get_string_const(argv[2], &v)) { if (!git_config_get_string_tmp(argv[2], &v)) {
printf("%s\n", v); printf("%s\n", v);
goto exit0; goto exit0;
} else { } else {