diff options
| author | Junio C Hamano <gitster@pobox.com> | 2022-06-07 14:10:56 -0700 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2022-06-07 14:10:56 -0700 |
| commit | 2da81d1efb0166e1cec7a8582b837994dde6225b (patch) | |
| tree | 43763a6b702eb4244724f3c7bedd3537f1f4406a /builtin/log.c | |
| parent | Merge branch 'yw/cmake-updates' (diff) | |
| parent | revisions API: add a TODO for diff_free(&revs->diffopt) (diff) | |
| download | git-2da81d1efb0166e1cec7a8582b837994dde6225b.tar.gz git-2da81d1efb0166e1cec7a8582b837994dde6225b.zip | |
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"
...
Diffstat (limited to 'builtin/log.c')
| -rw-r--r-- | builtin/log.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/builtin/log.c b/builtin/log.c index 2eb0063cc1..88a5e98875 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -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) |
