Plug various leans reported by LSAN.

* ah/plugleaks:
  builtin/rm: avoid leaking pathspec and seen
  builtin/rebase: release git_format_patch_opt too
  builtin/for-each-ref: free filter and UNLEAK sorting.
  mailinfo: also free strbuf lists when clearing mailinfo
  builtin/checkout: clear pending objects after diffing
  builtin/check-ignore: clear_pathspec before returning
  builtin/bugreport: don't leak prefixed filename
  branch: FREE_AND_NULL instead of NULL'ing real_ref
  bloom: clear each bloom_key after use
  ls-files: free max_prefix when done
  wt-status: fix multiple small leaks
  revision: free remainder of old commit list in limit_list
This commit is contained in:
Junio C Hamano 2021-05-07 12:47:41 +09:00
Родитель 8585d6c04a 37be11994f
Коммит 936e58851a
13 изменённых файлов: 36 добавлений и 23 удалений

Просмотреть файл

@ -283,6 +283,7 @@ struct bloom_filter *get_or_compute_bloom_filter(struct repository *r,
struct bloom_key key;
fill_bloom_key(e->path, strlen(e->path), &key, settings);
add_key_to_filter(&key, filter, settings);
clear_bloom_key(&key);
}
cleanup:

Просмотреть файл

@ -294,7 +294,7 @@ void create_branch(struct repository *r,
if (explicit_tracking)
die(_(upstream_not_branch), start_name);
else
real_ref = NULL;
FREE_AND_NULL(real_ref);
}
break;
default:

Просмотреть файл

@ -129,6 +129,7 @@ int cmd_bugreport(int argc, const char **argv, const char *prefix)
char *option_output = NULL;
char *option_suffix = "%Y-%m-%d-%H%M";
const char *user_relative_path = NULL;
char *prefixed_filename;
const struct option bugreport_options[] = {
OPT_STRING('o', "output-directory", &option_output, N_("path"),
@ -142,9 +143,9 @@ int cmd_bugreport(int argc, const char **argv, const char *prefix)
bugreport_usage, 0);
/* Prepare the path to put the result */
strbuf_addstr(&report_path,
prefix_filename(prefix,
option_output ? option_output : ""));
prefixed_filename = prefix_filename(prefix,
option_output ? option_output : "");
strbuf_addstr(&report_path, prefixed_filename);
strbuf_complete(&report_path, '/');
strbuf_addstr(&report_path, "git-bugreport-");
@ -189,6 +190,7 @@ int cmd_bugreport(int argc, const char **argv, const char *prefix)
fprintf(stderr, _("Created new report at '%s'.\n"),
user_relative_path);
free(prefixed_filename);
UNLEAK(buffer);
UNLEAK(report_path);
return !!launch_editor(report_path.buf, NULL, NULL);

Просмотреть файл

@ -119,6 +119,7 @@ static int check_ignore(struct dir_struct *dir,
num_ignored++;
}
free(seen);
clear_pathspec(&pathspec);
return num_ignored;
}

Просмотреть файл

@ -607,6 +607,7 @@ static void show_local_changes(struct object *head,
diff_setup_done(&rev.diffopt);
add_pending_object(&rev, head, NULL);
run_diff_index(&rev, 0);
object_array_clear(&rev.pending);
}
static void describe_detached_head(const char *msg, struct commit *commit)

Просмотреть файл

@ -94,5 +94,8 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
strbuf_release(&err);
strbuf_release(&output);
ref_array_clear(&array);
free_commit_list(filter.with_commit);
free_commit_list(filter.no_commit);
UNLEAK(sorting);
return 0;
}

Просмотреть файл

@ -607,7 +607,7 @@ static int option_parse_exclude_standard(const struct option *opt,
int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
{
int require_work_tree = 0, show_tag = 0, i;
const char *max_prefix;
char *max_prefix;
struct dir_struct dir;
struct pattern_list *pl;
struct string_list exclude_list = STRING_LIST_INIT_NODUP;
@ -785,5 +785,6 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
}
dir_clear(&dir);
free(max_prefix);
return 0;
}

Просмотреть файл

@ -2109,6 +2109,7 @@ cleanup:
free(options.head_name);
free(options.gpg_sign_opt);
free(options.cmd);
strbuf_release(&options.git_format_patch_opt);
free(squash_onto_name);
return ret;
}

Просмотреть файл

@ -342,6 +342,8 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
if (!seen_any)
exit(ret);
}
clear_pathspec(&pathspec);
free(seen);
if (!index_only)
submodules_absorb_gitdir_if_needed();

Просмотреть файл

@ -821,7 +821,7 @@ static int handle_commit_msg(struct mailinfo *mi, struct strbuf *line)
for (i = 0; header[i]; i++) {
if (mi->s_hdr_data[i])
strbuf_release(mi->s_hdr_data[i]);
mi->s_hdr_data[i] = NULL;
FREE_AND_NULL(mi->s_hdr_data[i]);
}
return 0;
}
@ -1236,22 +1236,14 @@ void setup_mailinfo(struct mailinfo *mi)
void clear_mailinfo(struct mailinfo *mi)
{
int i;
strbuf_release(&mi->name);
strbuf_release(&mi->email);
strbuf_release(&mi->charset);
strbuf_release(&mi->inbody_header_accum);
free(mi->message_id);
if (mi->p_hdr_data)
for (i = 0; mi->p_hdr_data[i]; i++)
strbuf_release(mi->p_hdr_data[i]);
free(mi->p_hdr_data);
if (mi->s_hdr_data)
for (i = 0; mi->s_hdr_data[i]; i++)
strbuf_release(mi->s_hdr_data[i]);
free(mi->s_hdr_data);
strbuf_list_free(mi->p_hdr_data);
strbuf_list_free(mi->s_hdr_data);
while (mi->content < mi->content_top) {
free(*(mi->content_top));

Просмотреть файл

@ -1393,20 +1393,20 @@ static int limit_list(struct rev_info *revs)
{
int slop = SLOP;
timestamp_t date = TIME_MAX;
struct commit_list *list = revs->commits;
struct commit_list *original_list = revs->commits;
struct commit_list *newlist = NULL;
struct commit_list **p = &newlist;
struct commit_list *bottom = NULL;
struct commit *interesting_cache = NULL;
if (revs->ancestry_path) {
bottom = collect_bottom_commits(list);
bottom = collect_bottom_commits(original_list);
if (!bottom)
die("--ancestry-path given but there are no bottom commits");
}
while (list) {
struct commit *commit = pop_commit(&list);
while (original_list) {
struct commit *commit = pop_commit(&original_list);
struct object *obj = &commit->object;
show_early_output_fn_t show;
@ -1415,11 +1415,11 @@ static int limit_list(struct rev_info *revs)
if (revs->max_age != -1 && (commit->date < revs->max_age))
obj->flags |= UNINTERESTING;
if (process_parents(revs, commit, &list, NULL) < 0)
if (process_parents(revs, commit, &original_list, NULL) < 0)
return -1;
if (obj->flags & UNINTERESTING) {
mark_parents_uninteresting(commit);
slop = still_interesting(list, date, slop, &interesting_cache);
slop = still_interesting(original_list, date, slop, &interesting_cache);
if (slop)
continue;
break;
@ -1452,14 +1452,17 @@ static int limit_list(struct rev_info *revs)
* Check if any commits have become TREESAME by some of their parents
* becoming UNINTERESTING.
*/
if (limiting_can_increase_treesame(revs))
if (limiting_can_increase_treesame(revs)) {
struct commit_list *list = NULL;
for (list = newlist; list; list = list->next) {
struct commit *c = list->item;
if (c->object.flags & (UNINTERESTING | TREESAME))
continue;
update_treesame(revs, c);
}
}
free_commit_list(original_list);
revs->commits = newlist;
return 0;
}

Просмотреть файл

@ -209,6 +209,8 @@ void strbuf_list_free(struct strbuf **sbs)
{
struct strbuf **s = sbs;
if (!s)
return;
while (*s) {
strbuf_release(*s);
free(*s++);

Просмотреть файл

@ -616,6 +616,7 @@ static void wt_status_collect_changes_worktree(struct wt_status *s)
rev.diffopt.rename_score = s->rename_score >= 0 ? s->rename_score : rev.diffopt.rename_score;
copy_pathspec(&rev.prune_data, &s->pathspec);
run_diff_files(&rev, 0);
clear_pathspec(&rev.prune_data);
}
static void wt_status_collect_changes_index(struct wt_status *s)
@ -652,6 +653,8 @@ static void wt_status_collect_changes_index(struct wt_status *s)
rev.diffopt.rename_score = s->rename_score >= 0 ? s->rename_score : rev.diffopt.rename_score;
copy_pathspec(&rev.prune_data, &s->pathspec);
run_diff_index(&rev, 1);
object_array_clear(&rev.pending);
clear_pathspec(&rev.prune_data);
}
static void wt_status_collect_changes_initial(struct wt_status *s)
@ -2480,6 +2483,7 @@ int has_uncommitted_changes(struct repository *r,
diff_setup_done(&rev_info.diffopt);
result = run_diff_index(&rev_info, 1);
object_array_clear(&rev_info.pending);
return diff_result_code(&rev_info.diffopt, result);
}