diff options
| author | Junio C Hamano <gitster@pobox.com> | 2024-07-08 14:53:10 -0700 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2024-07-08 14:53:10 -0700 |
| commit | 3997614c249b4b475d07c00556446d8b698d1a49 (patch) | |
| tree | fc0d71d047b303ec2b25fd0711069e9ba4751dd9 /revision.c | |
| parent | ecf7fc600a5218c9ee3863ee70d5a6e312164f30 (diff) | |
| parent | fbf7a46d881429ef5495af7bbf3a6c3dacbf80b3 (diff) | |
| download | git-3997614c249b4b475d07c00556446d8b698d1a49.tar.gz | |
Merge branch 'ps/leakfixes-more'
More memory leaks have been plugged.
* ps/leakfixes-more: (29 commits)
builtin/blame: fix leaking ignore revs files
builtin/blame: fix leaking prefixed paths
blame: fix leaking data for blame scoreboards
line-range: plug leaking find functions
merge: fix leaking merge bases
builtin/merge: fix leaking `struct cmdnames` in `get_strategy()`
sequencer: fix memory leaks in `make_script_with_merges()`
builtin/clone: plug leaking HEAD ref in `wanted_peer_refs()`
apply: fix leaking string in `match_fragment()`
sequencer: fix leaking string buffer in `commit_staged_changes()`
commit: fix leaking parents when calling `commit_tree_extended()`
config: fix leaking "core.notesref" variable
rerere: fix various trivial leaks
builtin/stash: fix leak in `show_stash()`
revision: free diff options
builtin/log: fix leaking commit list in git-cherry(1)
merge-recursive: fix memory leak when finalizing merge
builtin/merge-recursive: fix leaking object ID bases
builtin/difftool: plug memory leaks in `run_dir_diff()`
object-name: free leaking object contexts
...
Diffstat (limited to 'revision.c')
| -rw-r--r-- | revision.c | 59 |
1 files changed, 37 insertions, 22 deletions
diff --git a/revision.c b/revision.c index c0c4e8c3b6..1c0192f522 100644 --- a/revision.c +++ b/revision.c @@ -2151,30 +2151,26 @@ static int handle_dotdot(const char *arg, struct rev_info *revs, int flags, int cant_be_filename) { - struct object_context a_oc, b_oc; + struct object_context a_oc = {0}, b_oc = {0}; char *dotdot = strstr(arg, ".."); int ret; if (!dotdot) return -1; - memset(&a_oc, 0, sizeof(a_oc)); - memset(&b_oc, 0, sizeof(b_oc)); - *dotdot = '\0'; ret = handle_dotdot_1(arg, dotdot, revs, flags, cant_be_filename, &a_oc, &b_oc); *dotdot = '.'; - free(a_oc.path); - free(b_oc.path); - + object_context_release(&a_oc); + object_context_release(&b_oc); return ret; } static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int flags, unsigned revarg_opt) { - struct object_context oc; + struct object_context oc = {0}; char *mark; struct object *object; struct object_id oid; @@ -2182,6 +2178,7 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl const char *arg = arg_; int cant_be_filename = revarg_opt & REVARG_CANNOT_BE_FILENAME; unsigned get_sha1_flags = GET_OID_RECORD_PATH; + int ret; flags = flags & UNINTERESTING ? flags | BOTTOM : flags & ~BOTTOM; @@ -2190,17 +2187,22 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl * Just ".."? That is not a range but the * pathspec for the parent directory. */ - return -1; + ret = -1; + goto out; } - if (!handle_dotdot(arg, revs, flags, revarg_opt)) - return 0; + if (!handle_dotdot(arg, revs, flags, revarg_opt)) { + ret = 0; + goto out; + } mark = strstr(arg, "^@"); if (mark && !mark[2]) { *mark = 0; - if (add_parents_only(revs, arg, flags, 0)) - return 0; + if (add_parents_only(revs, arg, flags, 0)) { + ret = 0; + goto out; + } *mark = '^'; } mark = strstr(arg, "^!"); @@ -2215,8 +2217,10 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl if (mark[2]) { if (strtol_i(mark + 2, 10, &exclude_parent) || - exclude_parent < 1) - return -1; + exclude_parent < 1) { + ret = -1; + goto out; + } } *mark = 0; @@ -2238,17 +2242,25 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl * should error out if we can't even get an oid, as * `--missing=print` should be able to report missing oids. */ - if (get_oid_with_context(revs->repo, arg, get_sha1_flags, &oid, &oc)) - return revs->ignore_missing ? 0 : -1; + if (get_oid_with_context(revs->repo, arg, get_sha1_flags, &oid, &oc)) { + ret = revs->ignore_missing ? 0 : -1; + goto out; + } if (!cant_be_filename) verify_non_filename(revs->prefix, arg); object = get_reference(revs, arg, &oid, flags ^ local_flags); - if (!object) - return (revs->ignore_missing || revs->do_not_die_on_missing_objects) ? 0 : -1; + if (!object) { + ret = (revs->ignore_missing || revs->do_not_die_on_missing_objects) ? 0 : -1; + goto out; + } add_rev_cmdline(revs, object, arg_, REV_CMD_REV, flags ^ local_flags); add_pending_object_with_path(revs, object, arg, oc.mode, oc.path); - free(oc.path); - return 0; + + ret = 0; + +out: + object_context_release(&oc); + return ret; } int handle_revision_arg(const char *arg, struct rev_info *revs, int flags, unsigned revarg_opt) @@ -3084,6 +3096,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s diagnose_missing_default(revs->def); object = get_reference(revs, revs->def, &oid, 0); add_pending_object_with_mode(revs, object, revs->def, oc.mode); + object_context_release(&oc); } /* Did the user ask for any diff output? Run the diff! */ @@ -3190,6 +3203,7 @@ void release_revisions(struct rev_info *revs) { free_commit_list(revs->commits); free_commit_list(revs->ancestry_path_bottoms); + release_display_notes(&revs->notes_opt); object_array_clear(&revs->pending); object_array_clear(&revs->boundary_commits); release_revisions_cmdline(&revs->cmdline); @@ -3199,7 +3213,7 @@ void release_revisions(struct rev_info *revs) release_revisions_mailmap(revs->mailmap); free_grep_patterns(&revs->grep_filter); graph_clear(revs->graph); - /* TODO (need to handle "no_free"): diff_free(&revs->diffopt) */ + diff_free(&revs->diffopt); diff_free(&revs->pruning); reflog_walk_info_release(revs->reflog_info); release_revisions_topo_walk_info(revs->topo_walk_info); @@ -4452,6 +4466,7 @@ struct commit *get_revision(struct rev_info *revs) reversed = NULL; while ((c = get_revision_internal(revs))) commit_list_insert(c, &reversed); + free_commit_list(revs->commits); revs->commits = reversed; revs->reverse = 0; revs->reverse_output_stage = 1; |
