Merge branch 'ab/plug-leak-in-revisions'

Plug the memory leaks from the trickiest API of all, the revision
walker.

* ab/plug-leak-in-revisions: (27 commits)
  revisions API: add a TODO for diff_free(&revs->diffopt)
  revisions API: have release_revisions() release "topo_walk_info"
  revisions API: have release_revisions() release "date_mode"
  revisions API: call diff_free(&revs->pruning) in revisions_release()
  revisions API: release "reflog_info" in release revisions()
  revisions API: clear "boundary_commits" in release_revisions()
  revisions API: have release_revisions() release "prune_data"
  revisions API: have release_revisions() release "grep_filter"
  revisions API: have release_revisions() release "filter"
  revisions API: have release_revisions() release "cmdline"
  revisions API: have release_revisions() release "mailmap"
  revisions API: have release_revisions() release "commits"
  revisions API users: use release_revisions() for "prune_data" users
  revisions API users: use release_revisions() with UNLEAK()
  revisions API users: use release_revisions() in builtin/log.c
  revisions API users: use release_revisions() in http-push.c
  revisions API users: add "goto cleanup" for release_revisions()
  stash: always have the owner of "stash_info" free it
  revisions API users: use release_revisions() needing REV_INFO_INIT
  revision.[ch]: document and move code declared around "init"
  ...
This commit is contained in:
Junio C Hamano
2022-06-07 14:10:56 -07:00
117 changed files with 500 additions and 190 deletions

View File

@ -231,7 +231,8 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
}
if (mailmap) {
rev->mailmap = xcalloc(1, sizeof(struct string_list));
rev->mailmap = xmalloc(sizeof(struct string_list));
string_list_init_nodup(rev->mailmap);
read_mailmap(rev->mailmap);
}
@ -294,6 +295,12 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
cmd_log_init_finish(argc, argv, prefix, rev, opt);
}
static int cmd_log_deinit(int ret, struct rev_info *rev)
{
release_revisions(rev);
return ret;
}
/*
* This gives a rough estimate for how many commits we
* will print out in the list.
@ -565,7 +572,7 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix)
cmd_log_init(argc, argv, prefix, &rev, &opt);
if (!rev.diffopt.output_format)
rev.diffopt.output_format = DIFF_FORMAT_RAW;
return cmd_log_walk(&rev);
return cmd_log_deinit(cmd_log_walk(&rev), &rev);
}
static void show_tagger(const char *buf, struct rev_info *rev)
@ -689,7 +696,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
cmd_log_init(argc, argv, prefix, &rev, &opt);
if (!rev.no_walk)
return cmd_log_walk(&rev);
return cmd_log_deinit(cmd_log_walk(&rev), &rev);
count = rev.pending.nr;
objects = rev.pending.objects;
@ -749,8 +756,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
rev.diffopt.no_free = 0;
diff_free(&rev.diffopt);
free(objects);
return ret;
return cmd_log_deinit(ret, &rev);
}
/*
@ -778,7 +784,7 @@ int cmd_log_reflog(int argc, const char **argv, const char *prefix)
rev.always_show_header = 1;
cmd_log_init_finish(argc, argv, prefix, &rev, &opt);
return cmd_log_walk(&rev);
return cmd_log_deinit(cmd_log_walk(&rev), &rev);
}
static void log_setup_revisions_tweak(struct rev_info *rev,
@ -809,7 +815,7 @@ int cmd_log(int argc, const char **argv, const char *prefix)
opt.revarg_opt = REVARG_COMMITTISH;
opt.tweak = log_setup_revisions_tweak;
cmd_log_init(argc, argv, prefix, &rev, &opt);
return cmd_log_walk(&rev);
return cmd_log_deinit(cmd_log_walk(&rev), &rev);
}
/* format-patch */
@ -1764,6 +1770,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
struct commit *commit;
struct commit **list = NULL;
struct rev_info rev;
char *to_free = NULL;
struct setup_revision_opt s_r_opt;
int nr = 0, total, i;
int use_stdout = 0;
@ -1965,7 +1972,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
strbuf_addch(&buf, '\n');
}
rev.extra_headers = strbuf_detach(&buf, NULL);
rev.extra_headers = to_free = strbuf_detach(&buf, NULL);
if (from) {
if (split_ident_line(&rev.from_ident, from, strlen(from)))
@ -2186,8 +2193,10 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
prepare_bases(&bases, base, list, nr);
}
if (in_reply_to || thread || cover_letter)
rev.ref_message_ids = xcalloc(1, sizeof(struct string_list));
if (in_reply_to || thread || cover_letter) {
rev.ref_message_ids = xmalloc(sizeof(*rev.ref_message_ids));
string_list_init_nodup(rev.ref_message_ids);
}
if (in_reply_to) {
const char *msgid = clean_message_id(in_reply_to);
string_list_append(rev.ref_message_ids, msgid);
@ -2294,8 +2303,11 @@ done:
strbuf_release(&rdiff1);
strbuf_release(&rdiff2);
strbuf_release(&rdiff_title);
UNLEAK(rev);
return 0;
free(to_free);
if (rev.ref_message_ids)
string_list_clear(rev.ref_message_ids, 0);
free(rev.ref_message_ids);
return cmd_log_deinit(0, &rev);
}
static int add_pending_commit(const char *arg, struct rev_info *revs, int flags)