The `OPT_FILENAME()` option will, if set, put an allocated string into the user-provided variable. Consequently, that variable thus needs to be free'd by the caller of `parse_options()`. Some callsites don't though and thus leak memory. Fix those. Signed-off-by: Patrick Steinhardt <ps@xxxxxx> --- apply.c | 1 + apply.h | 2 +- builtin/archive.c | 7 +++++-- builtin/commit.c | 7 +++++-- builtin/fmt-merge-msg.c | 4 +++- builtin/log.c | 4 +++- builtin/multi-pack-index.c | 13 +++++++++---- builtin/sparse-checkout.c | 1 + t/helper/test-parse-options.c | 1 + t/t1512-rev-parse-disambiguation.sh | 1 + t/t2500-untracked-overwriting.sh | 1 + t/t3406-rebase-message.sh | 1 + t/t3407-rebase-abort.sh | 1 + t/t3428-rebase-signoff.sh | 1 + t/t4131-apply-fake-ancestor.sh | 1 + t/t4151-am-abort.sh | 1 + t/t4253-am-keep-cr-dos.sh | 1 + t/t4255-am-submodule.sh | 1 + t/t5407-post-rewrite-hook.sh | 1 + t/t6427-diff3-conflict-markers.sh | 1 + t/t7512-status-help.sh | 1 + 21 files changed, 41 insertions(+), 11 deletions(-) diff --git a/apply.c b/apply.c index 901b67e625..d8d26a48f1 100644 --- a/apply.c +++ b/apply.c @@ -135,6 +135,7 @@ void clear_apply_state(struct apply_state *state) strset_clear(&state->removed_symlinks); strset_clear(&state->kept_symlinks); strbuf_release(&state->root); + FREE_AND_NULL(state->fake_ancestor); /* &state->fn_table is cleared at the end of apply_patch() */ } diff --git a/apply.h b/apply.h index 7cd38b1443..36d7c3f70b 100644 --- a/apply.h +++ b/apply.h @@ -59,7 +59,7 @@ struct apply_state { struct repository *repo; const char *index_file; enum apply_verbosity apply_verbosity; - const char *fake_ancestor; + char *fake_ancestor; const char *patch_input_file; int line_termination; struct strbuf root; diff --git a/builtin/archive.c b/builtin/archive.c index 15ee1ec7bb..f29c0ef6ad 100644 --- a/builtin/archive.c +++ b/builtin/archive.c @@ -92,6 +92,7 @@ int cmd_archive(int argc, const char **argv, const char *prefix) N_("path to the remote git-upload-archive command")), OPT_END() }; + int ret; argc = parse_options(argc, argv, prefix, local_opts, NULL, PARSE_OPT_KEEP_ALL); @@ -106,6 +107,8 @@ int cmd_archive(int argc, const char **argv, const char *prefix) setvbuf(stderr, NULL, _IOLBF, BUFSIZ); - UNLEAK(output); - return write_archive(argc, argv, prefix, the_repository, output, 0); + ret = write_archive(argc, argv, prefix, the_repository, output, 0); + + free(output); + return ret; } diff --git a/builtin/commit.c b/builtin/commit.c index f53e7e86ff..dcaf4efa03 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -106,7 +106,8 @@ static enum { COMMIT_PARTIAL } commit_style; -static const char *logfile, *force_author; +static const char *force_author; +static char *logfile; static char *template_file; /* * The _message variables are commit names from which to take @@ -1309,7 +1310,7 @@ static int parse_and_validate_options(int argc, const char *argv[], !!use_message, "-C", !!logfile, "-F"); if (use_message || edit_message || logfile ||fixup_message || have_option_m) - template_file = NULL; + FREE_AND_NULL(template_file); if (edit_message) use_message = edit_message; if (amend && !use_message && !fixup_message) @@ -1892,5 +1893,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) strbuf_release(&author_ident); strbuf_release(&err); strbuf_release(&sb); + free(logfile); + free(template_file); return ret; } diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c index 0f9855b680..957786d1b3 100644 --- a/builtin/fmt-merge-msg.c +++ b/builtin/fmt-merge-msg.c @@ -11,7 +11,7 @@ static const char * const fmt_merge_msg_usage[] = { int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) { - const char *inpath = NULL; + char *inpath = NULL; const char *message = NULL; char *into_name = NULL; int shortlog_len = -1; @@ -66,5 +66,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) if (ret) return ret; write_in_full(STDOUT_FILENO, output.buf, output.len); + + free(inpath); return 0; } diff --git a/builtin/log.c b/builtin/log.c index 78a247d8a9..4e4b645a21 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -2021,7 +2021,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) const char *rfc = NULL; int creation_factor = -1; const char *signature = git_version_string; - const char *signature_file_arg = NULL; + char *signature_file_arg = NULL; struct keep_callback_data keep_callback_data = { .cfg = &cfg, .revs = &rev, @@ -2559,6 +2559,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) strbuf_release(&rdiff1); strbuf_release(&rdiff2); strbuf_release(&rdiff_title); + free(description_file); + free(signature_file_arg); free(to_free); free(rev.message_id); if (rev.ref_message_ids) diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c index 8360932d2e..9cf1a32d65 100644 --- a/builtin/multi-pack-index.c +++ b/builtin/multi-pack-index.c @@ -50,7 +50,7 @@ static char const * const builtin_multi_pack_index_usage[] = { static struct opts_multi_pack_index { char *object_dir; const char *preferred_pack; - const char *refs_snapshot; + char *refs_snapshot; unsigned long batch_size; unsigned flags; int stdin_packs; @@ -135,6 +135,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv, N_("refs snapshot for selecting bitmap commits")), OPT_END(), }; + int ret; opts.flags |= MIDX_WRITE_BITMAP_HASH_CACHE; @@ -157,7 +158,6 @@ static int cmd_multi_pack_index_write(int argc, const char **argv, if (opts.stdin_packs) { struct string_list packs = STRING_LIST_INIT_DUP; - int ret; read_packs_from_stdin(&packs); @@ -166,12 +166,17 @@ static int cmd_multi_pack_index_write(int argc, const char **argv, opts.refs_snapshot, opts.flags); string_list_clear(&packs, 0); + free(opts.refs_snapshot); return ret; } - return write_midx_file(opts.object_dir, opts.preferred_pack, - opts.refs_snapshot, opts.flags); + + ret = write_midx_file(opts.object_dir, opts.preferred_pack, + opts.refs_snapshot, opts.flags); + + free(opts.refs_snapshot); + return ret; } static int cmd_multi_pack_index_verify(int argc, const char **argv, diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c index 0f52e25249..84a6adf681 100644 --- a/builtin/sparse-checkout.c +++ b/builtin/sparse-checkout.c @@ -1011,6 +1011,7 @@ static int sparse_checkout_check_rules(int argc, const char **argv, const char * ret = check_rules(&pl, check_rules_opts.null_termination); clear_pattern_list(&pl); + free(check_rules_opts.rules_file); return ret; } diff --git a/t/helper/test-parse-options.c b/t/helper/test-parse-options.c index ded8116cc5..5250913d99 100644 --- a/t/helper/test-parse-options.c +++ b/t/helper/test-parse-options.c @@ -207,6 +207,7 @@ int cmd__parse_options(int argc, const char **argv) expect.strdup_strings = 1; string_list_clear(&expect, 0); string_list_clear(&list, 0); + free(file); return ret; } diff --git a/t/t1512-rev-parse-disambiguation.sh b/t/t1512-rev-parse-disambiguation.sh index 70f1e0a998..f9d68ce74e 100755 --- a/t/t1512-rev-parse-disambiguation.sh +++ b/t/t1512-rev-parse-disambiguation.sh @@ -23,6 +23,7 @@ one tagged as v1.0.0. They all have one regular file each. GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_cmp_failed_rev_parse () { diff --git a/t/t2500-untracked-overwriting.sh b/t/t2500-untracked-overwriting.sh index 5c0bf4d21f..714feb83be 100755 --- a/t/t2500-untracked-overwriting.sh +++ b/t/t2500-untracked-overwriting.sh @@ -2,6 +2,7 @@ test_description='Test handling of overwriting untracked files' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_setup_reset () { diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh index a1d7fa7f7c..82108b67e6 100755 --- a/t/t3406-rebase-message.sh +++ b/t/t3406-rebase-message.sh @@ -5,6 +5,7 @@ test_description='messages from rebase operation' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3407-rebase-abort.sh b/t/t3407-rebase-abort.sh index 9f49c4228b..2c3f38d45a 100755 --- a/t/t3407-rebase-abort.sh +++ b/t/t3407-rebase-abort.sh @@ -5,6 +5,7 @@ test_description='git rebase --abort tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t3428-rebase-signoff.sh b/t/t3428-rebase-signoff.sh index 6f57aed9fa..365436ebfc 100755 --- a/t/t3428-rebase-signoff.sh +++ b/t/t3428-rebase-signoff.sh @@ -5,6 +5,7 @@ test_description='git rebase --signoff This test runs git rebase --signoff and make sure that it works. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh diff --git a/t/t4131-apply-fake-ancestor.sh b/t/t4131-apply-fake-ancestor.sh index b1361ce546..40c92115a6 100755 --- a/t/t4131-apply-fake-ancestor.sh +++ b/t/t4131-apply-fake-ancestor.sh @@ -5,6 +5,7 @@ test_description='git apply --build-fake-ancestor handling.' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4151-am-abort.sh b/t/t4151-am-abort.sh index edb38da701..1825a89d6a 100755 --- a/t/t4151-am-abort.sh +++ b/t/t4151-am-abort.sh @@ -2,6 +2,7 @@ test_description='am --abort' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4253-am-keep-cr-dos.sh b/t/t4253-am-keep-cr-dos.sh index 0ee69d2a0c..2bcdd9f34f 100755 --- a/t/t4253-am-keep-cr-dos.sh +++ b/t/t4253-am-keep-cr-dos.sh @@ -9,6 +9,7 @@ test_description='git-am mbox with dos line ending. GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Three patches which will be added as files with dos line ending. diff --git a/t/t4255-am-submodule.sh b/t/t4255-am-submodule.sh index a7ba08f728..04f3ccfc41 100755 --- a/t/t4255-am-submodule.sh +++ b/t/t4255-am-submodule.sh @@ -2,6 +2,7 @@ test_description='git am handling submodules' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh diff --git a/t/t5407-post-rewrite-hook.sh b/t/t5407-post-rewrite-hook.sh index ad7f8c6f00..e99e728236 100755 --- a/t/t5407-post-rewrite-hook.sh +++ b/t/t5407-post-rewrite-hook.sh @@ -7,6 +7,7 @@ test_description='Test the post-rewrite hook.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t6427-diff3-conflict-markers.sh b/t/t6427-diff3-conflict-markers.sh index dd5fe6a402..a13271b349 100755 --- a/t/t6427-diff3-conflict-markers.sh +++ b/t/t6427-diff3-conflict-markers.sh @@ -5,6 +5,7 @@ test_description='recursive merge diff3 style conflict markers' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Setup: diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh index 802f8f704c..cdd5f2c697 100755 --- a/t/t7512-status-help.sh +++ b/t/t7512-status-help.sh @@ -10,6 +10,7 @@ test_description='git status advice' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh -- 2.45.2.436.gcd77e87115.dirty
Attachment:
signature.asc
Description: PGP signature