Merge branch 'ah/plugleaks'

Leak plugging.

* ah/plugleaks:
  reset: clear_unpack_trees_porcelain to plug leak
  builtin/rebase: fix options.strategy memory lifecycle
  builtin/merge: free found_ref when done
  builtin/mv: free or UNLEAK multiple pointers at end of cmd_mv
  convert: release strbuf to avoid leak
  read-cache: call diff_setup_done to avoid leak
  ref-filter: also free head for ATOM_HEAD to avoid leak
  diffcore-rename: move old_dir/new_dir definition to plug leak
  builtin/for-each-repo: remove unnecessary argv copy to plug leak
  builtin/submodule--helper: release unused strbuf to avoid leak
  environment: move strbuf into block to plug leak
  fmt-merge-msg: free newly allocated temporary strings when done
This commit is contained in:
Junio C Hamano 2021-08-04 13:28:52 -07:00
commit 31f9acf9ce
12 changed files with 42 additions and 27 deletions

View File

@ -10,18 +10,16 @@ static const char * const for_each_repo_usage[] = {
NULL
};
static int run_command_on_repo(const char *path,
void *cbdata)
static int run_command_on_repo(const char *path, int argc, const char ** argv)
{
int i;
struct child_process child = CHILD_PROCESS_INIT;
struct strvec *args = (struct strvec *)cbdata;
child.git_cmd = 1;
strvec_pushl(&child.args, "-C", path, NULL);
for (i = 0; i < args->nr; i++)
strvec_push(&child.args, args->v[i]);
for (i = 0; i < argc; i++)
strvec_push(&child.args, argv[i]);
return run_command(&child);
}
@ -31,7 +29,6 @@ int cmd_for_each_repo(int argc, const char **argv, const char *prefix)
static const char *config_key = NULL;
int i, result = 0;
const struct string_list *values;
struct strvec args = STRVEC_INIT;
const struct option options[] = {
OPT_STRING(0, "config", &config_key, N_("config"),
@ -45,9 +42,6 @@ int cmd_for_each_repo(int argc, const char **argv, const char *prefix)
if (!config_key)
die(_("missing --config=<config>"));
for (i = 0; i < argc; i++)
strvec_push(&args, argv[i]);
values = repo_config_get_value_multi(the_repository,
config_key);
@ -59,7 +53,7 @@ int cmd_for_each_repo(int argc, const char **argv, const char *prefix)
return 0;
for (i = 0; !result && i < values->nr; i++)
result = run_command_on_repo(values->items[i].string, &args);
result = run_command_on_repo(values->items[i].string, argc, argv);
return result;
}

View File

@ -503,7 +503,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
struct strbuf bname = STRBUF_INIT;
struct merge_remote_desc *desc;
const char *ptr;
char *found_ref;
char *found_ref = NULL;
int len, early;
strbuf_branchname(&bname, remote, 0);
@ -586,6 +586,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
strbuf_addf(msg, "%s\t\tcommit '%s'\n",
oid_to_hex(&remote_head->object.oid), remote);
cleanup:
free(found_ref);
strbuf_release(&buf);
strbuf_release(&bname);
}

View File

@ -303,5 +303,10 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
COMMIT_LOCK | SKIP_IF_UNCHANGED))
die(_("Unable to write new index file"));
string_list_clear(&src_for_dst, 0);
UNLEAK(source);
UNLEAK(dest_path);
free(submodule_gitfile);
free(modes);
return 0;
}

View File

@ -139,7 +139,7 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts)
replay.ignore_date = opts->ignore_date;
replay.gpg_sign = xstrdup_or_null(opts->gpg_sign_opt);
if (opts->strategy)
replay.strategy = opts->strategy;
replay.strategy = xstrdup_or_null(opts->strategy);
else if (!replay.strategy && replay.default_strategy) {
replay.strategy = replay.default_strategy;
replay.default_strategy = NULL;
@ -2109,6 +2109,7 @@ cleanup:
free(options.head_name);
free(options.gpg_sign_opt);
free(options.cmd);
free(options.strategy);
strbuf_release(&options.git_format_patch_opt);
free(squash_onto_name);
return ret;

View File

@ -187,11 +187,13 @@ static char *relative_url(const char *remote_url,
out = xstrdup(sb.buf + 2);
else
out = xstrdup(sb.buf);
strbuf_reset(&sb);
if (!up_path || !is_relative)
if (!up_path || !is_relative) {
strbuf_release(&sb);
return out;
}
strbuf_reset(&sb);
strbuf_addf(&sb, "%s%s", up_path, out);
free(out);
return strbuf_detach(&sb, NULL);

View File

@ -916,6 +916,7 @@ done:
else
strbuf_swap(dst, &nbuf);
strbuf_release(&nbuf);
strbuf_release(&filter_status);
return !err;
}
@ -966,6 +967,7 @@ done:
if (err)
handle_filter_error(&filter_status, entry, 0);
strbuf_release(&filter_status);
return !err;
}

View File

@ -448,9 +448,9 @@ static void update_dir_rename_counts(struct dir_rename_info *info,
const char *oldname,
const char *newname)
{
char *old_dir = xstrdup(oldname);
char *new_dir = xstrdup(newname);
char new_dir_first_char = new_dir[0];
char *old_dir;
char *new_dir;
const char new_dir_first_char = newname[0];
int first_time_in_loop = 1;
if (!info->setup)
@ -475,6 +475,10 @@ static void update_dir_rename_counts(struct dir_rename_info *info,
*/
return;
old_dir = xstrdup(oldname);
new_dir = xstrdup(newname);
while (1) {
int drd_flag = NOT_RELEVANT;

View File

@ -253,21 +253,20 @@ static int git_work_tree_initialized;
*/
void set_git_work_tree(const char *new_work_tree)
{
struct strbuf realpath = STRBUF_INIT;
if (git_work_tree_initialized) {
struct strbuf realpath = STRBUF_INIT;
strbuf_realpath(&realpath, new_work_tree, 1);
new_work_tree = realpath.buf;
if (strcmp(new_work_tree, the_repository->worktree))
die("internal error: work tree has already been set\n"
"Current worktree: %s\nNew worktree: %s",
the_repository->worktree, new_work_tree);
strbuf_release(&realpath);
return;
}
git_work_tree_initialized = 1;
repo_set_worktree(the_repository, new_work_tree);
strbuf_release(&realpath);
}
const char *get_git_work_tree(void)

View File

@ -108,6 +108,7 @@ static int handle_line(char *line, struct merge_parents *merge_parents)
struct origin_data *origin_data;
char *src;
const char *origin, *tag_name;
char *to_free = NULL;
struct src_data *src_data;
struct string_list_item *item;
int pulling_head = 0;
@ -183,12 +184,13 @@ static int handle_line(char *line, struct merge_parents *merge_parents)
if (!strcmp(".", src) || !strcmp(src, origin)) {
int len = strlen(origin);
if (origin[0] == '\'' && origin[len - 1] == '\'')
origin = xmemdupz(origin + 1, len - 2);
origin = to_free = xmemdupz(origin + 1, len - 2);
} else
origin = xstrfmt("%s of %s", origin, src);
origin = to_free = xstrfmt("%s of %s", origin, src);
if (strcmp(".", src))
origin_data->is_local_branch = 0;
string_list_append(&origins, origin)->util = origin_data;
free(to_free);
return 0;
}

View File

@ -2506,6 +2506,7 @@ int repo_index_has_changes(struct repository *repo,
opt.flags.exit_with_status = 1;
if (!sb)
opt.flags.quick = 1;
diff_setup_done(&opt);
do_diff_cache(&cmp, &opt);
diffcore_std(&opt);
for (i = 0; sb && i < diff_queued_diff.nr; i++) {

View File

@ -2226,8 +2226,12 @@ void ref_array_clear(struct ref_array *array)
FREE_AND_NULL(array->items);
array->nr = array->alloc = 0;
for (i = 0; i < used_atom_cnt; i++)
free((char *)used_atom[i].name);
for (i = 0; i < used_atom_cnt; i++) {
struct used_atom *atom = &used_atom[i];
if (atom->atom_type == ATOM_HEAD)
free(atom->u.head);
free((char *)atom->name);
}
FREE_AND_NULL(used_atom);
used_atom_cnt = 0;

View File

@ -21,7 +21,7 @@ int reset_head(struct repository *r, struct object_id *oid, const char *action,
struct object_id head_oid;
struct tree_desc desc[2] = { { NULL }, { NULL } };
struct lock_file lock = LOCK_INIT;
struct unpack_trees_options unpack_tree_opts;
struct unpack_trees_options unpack_tree_opts = { 0 };
struct tree *tree;
const char *reflog_action;
struct strbuf msg = STRBUF_INIT;
@ -49,7 +49,6 @@ int reset_head(struct repository *r, struct object_id *oid, const char *action,
if (refs_only)
goto reset_head_refs;
memset(&unpack_tree_opts, 0, sizeof(unpack_tree_opts));
setup_unpack_trees_porcelain(&unpack_tree_opts, action);
unpack_tree_opts.head_idx = 1;
unpack_tree_opts.src_index = r->index;
@ -134,6 +133,7 @@ reset_head_refs:
leave_reset_head:
strbuf_release(&msg);
rollback_lock_file(&lock);
clear_unpack_trees_porcelain(&unpack_tree_opts);
while (nr)
free((void *)desc[--nr].buffer);
return ret;