parse-options: fix leaks for users of OPT_FILENAME
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@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
parent
56931c4d89
commit
14da26230a
1
apply.c
1
apply.c
|
@ -135,6 +135,7 @@ void clear_apply_state(struct apply_state *state)
|
||||||
strset_clear(&state->removed_symlinks);
|
strset_clear(&state->removed_symlinks);
|
||||||
strset_clear(&state->kept_symlinks);
|
strset_clear(&state->kept_symlinks);
|
||||||
strbuf_release(&state->root);
|
strbuf_release(&state->root);
|
||||||
|
FREE_AND_NULL(state->fake_ancestor);
|
||||||
|
|
||||||
/* &state->fn_table is cleared at the end of apply_patch() */
|
/* &state->fn_table is cleared at the end of apply_patch() */
|
||||||
}
|
}
|
||||||
|
|
2
apply.h
2
apply.h
|
@ -59,7 +59,7 @@ struct apply_state {
|
||||||
struct repository *repo;
|
struct repository *repo;
|
||||||
const char *index_file;
|
const char *index_file;
|
||||||
enum apply_verbosity apply_verbosity;
|
enum apply_verbosity apply_verbosity;
|
||||||
const char *fake_ancestor;
|
char *fake_ancestor;
|
||||||
const char *patch_input_file;
|
const char *patch_input_file;
|
||||||
int line_termination;
|
int line_termination;
|
||||||
struct strbuf root;
|
struct strbuf root;
|
||||||
|
|
|
@ -92,6 +92,7 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
|
||||||
N_("path to the remote git-upload-archive command")),
|
N_("path to the remote git-upload-archive command")),
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
|
int ret;
|
||||||
|
|
||||||
argc = parse_options(argc, argv, prefix, local_opts, NULL,
|
argc = parse_options(argc, argv, prefix, local_opts, NULL,
|
||||||
PARSE_OPT_KEEP_ALL);
|
PARSE_OPT_KEEP_ALL);
|
||||||
|
@ -106,6 +107,8 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
|
||||||
|
|
||||||
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
|
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
|
||||||
|
|
||||||
UNLEAK(output);
|
ret = write_archive(argc, argv, prefix, the_repository, output, 0);
|
||||||
return write_archive(argc, argv, prefix, the_repository, output, 0);
|
|
||||||
|
free(output);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,8 @@ static enum {
|
||||||
COMMIT_PARTIAL
|
COMMIT_PARTIAL
|
||||||
} commit_style;
|
} commit_style;
|
||||||
|
|
||||||
static const char *logfile, *force_author;
|
static const char *force_author;
|
||||||
|
static char *logfile;
|
||||||
static char *template_file;
|
static char *template_file;
|
||||||
/*
|
/*
|
||||||
* The _message variables are commit names from which to take
|
* 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",
|
!!use_message, "-C",
|
||||||
!!logfile, "-F");
|
!!logfile, "-F");
|
||||||
if (use_message || edit_message || logfile ||fixup_message || have_option_m)
|
if (use_message || edit_message || logfile ||fixup_message || have_option_m)
|
||||||
template_file = NULL;
|
FREE_AND_NULL(template_file);
|
||||||
if (edit_message)
|
if (edit_message)
|
||||||
use_message = edit_message;
|
use_message = edit_message;
|
||||||
if (amend && !use_message && !fixup_message)
|
if (amend && !use_message && !fixup_message)
|
||||||
|
@ -1892,5 +1893,7 @@ cleanup:
|
||||||
strbuf_release(&author_ident);
|
strbuf_release(&author_ident);
|
||||||
strbuf_release(&err);
|
strbuf_release(&err);
|
||||||
strbuf_release(&sb);
|
strbuf_release(&sb);
|
||||||
|
free(logfile);
|
||||||
|
free(template_file);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
const char *inpath = NULL;
|
char *inpath = NULL;
|
||||||
const char *message = NULL;
|
const char *message = NULL;
|
||||||
char *into_name = NULL;
|
char *into_name = NULL;
|
||||||
int shortlog_len = -1;
|
int shortlog_len = -1;
|
||||||
|
@ -66,5 +66,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
write_in_full(STDOUT_FILENO, output.buf, output.len);
|
write_in_full(STDOUT_FILENO, output.buf, output.len);
|
||||||
|
|
||||||
|
free(inpath);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2021,7 +2021,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
||||||
const char *rfc = NULL;
|
const char *rfc = NULL;
|
||||||
int creation_factor = -1;
|
int creation_factor = -1;
|
||||||
const char *signature = git_version_string;
|
const char *signature = git_version_string;
|
||||||
const char *signature_file_arg = NULL;
|
char *signature_file_arg = NULL;
|
||||||
struct keep_callback_data keep_callback_data = {
|
struct keep_callback_data keep_callback_data = {
|
||||||
.cfg = &cfg,
|
.cfg = &cfg,
|
||||||
.revs = &rev,
|
.revs = &rev,
|
||||||
|
@ -2559,6 +2559,8 @@ done:
|
||||||
strbuf_release(&rdiff1);
|
strbuf_release(&rdiff1);
|
||||||
strbuf_release(&rdiff2);
|
strbuf_release(&rdiff2);
|
||||||
strbuf_release(&rdiff_title);
|
strbuf_release(&rdiff_title);
|
||||||
|
free(description_file);
|
||||||
|
free(signature_file_arg);
|
||||||
free(to_free);
|
free(to_free);
|
||||||
free(rev.message_id);
|
free(rev.message_id);
|
||||||
if (rev.ref_message_ids)
|
if (rev.ref_message_ids)
|
||||||
|
|
|
@ -50,7 +50,7 @@ static char const * const builtin_multi_pack_index_usage[] = {
|
||||||
static struct opts_multi_pack_index {
|
static struct opts_multi_pack_index {
|
||||||
char *object_dir;
|
char *object_dir;
|
||||||
const char *preferred_pack;
|
const char *preferred_pack;
|
||||||
const char *refs_snapshot;
|
char *refs_snapshot;
|
||||||
unsigned long batch_size;
|
unsigned long batch_size;
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
int stdin_packs;
|
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")),
|
N_("refs snapshot for selecting bitmap commits")),
|
||||||
OPT_END(),
|
OPT_END(),
|
||||||
};
|
};
|
||||||
|
int ret;
|
||||||
|
|
||||||
opts.flags |= MIDX_WRITE_BITMAP_HASH_CACHE;
|
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) {
|
if (opts.stdin_packs) {
|
||||||
struct string_list packs = STRING_LIST_INIT_DUP;
|
struct string_list packs = STRING_LIST_INIT_DUP;
|
||||||
int ret;
|
|
||||||
|
|
||||||
read_packs_from_stdin(&packs);
|
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);
|
opts.refs_snapshot, opts.flags);
|
||||||
|
|
||||||
string_list_clear(&packs, 0);
|
string_list_clear(&packs, 0);
|
||||||
|
free(opts.refs_snapshot);
|
||||||
|
|
||||||
return ret;
|
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,
|
static int cmd_multi_pack_index_verify(int argc, const char **argv,
|
||||||
|
|
|
@ -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);
|
ret = check_rules(&pl, check_rules_opts.null_termination);
|
||||||
clear_pattern_list(&pl);
|
clear_pattern_list(&pl);
|
||||||
|
free(check_rules_opts.rules_file);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -207,6 +207,7 @@ int cmd__parse_options(int argc, const char **argv)
|
||||||
expect.strdup_strings = 1;
|
expect.strdup_strings = 1;
|
||||||
string_list_clear(&expect, 0);
|
string_list_clear(&expect, 0);
|
||||||
string_list_clear(&list, 0);
|
string_list_clear(&list, 0);
|
||||||
|
free(file);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ one tagged as v1.0.0. They all have one regular file each.
|
||||||
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
||||||
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||||
|
|
||||||
|
TEST_PASSES_SANITIZE_LEAK=true
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
test_cmp_failed_rev_parse () {
|
test_cmp_failed_rev_parse () {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
test_description='Test handling of overwriting untracked files'
|
test_description='Test handling of overwriting untracked files'
|
||||||
|
|
||||||
|
TEST_PASSES_SANITIZE_LEAK=true
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
test_setup_reset () {
|
test_setup_reset () {
|
||||||
|
|
|
@ -5,6 +5,7 @@ test_description='messages from rebase operation'
|
||||||
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
||||||
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||||
|
|
||||||
|
TEST_PASSES_SANITIZE_LEAK=true
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
test_expect_success 'setup' '
|
test_expect_success 'setup' '
|
||||||
|
|
|
@ -5,6 +5,7 @@ test_description='git rebase --abort tests'
|
||||||
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
||||||
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||||
|
|
||||||
|
TEST_PASSES_SANITIZE_LEAK=true
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
test_expect_success setup '
|
test_expect_success setup '
|
||||||
|
|
|
@ -5,6 +5,7 @@ test_description='git rebase --signoff
|
||||||
This test runs git rebase --signoff and make sure that it works.
|
This test runs git rebase --signoff and make sure that it works.
|
||||||
'
|
'
|
||||||
|
|
||||||
|
TEST_PASSES_SANITIZE_LEAK=true
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
. "$TEST_DIRECTORY"/lib-rebase.sh
|
. "$TEST_DIRECTORY"/lib-rebase.sh
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
test_description='git apply --build-fake-ancestor handling.'
|
test_description='git apply --build-fake-ancestor handling.'
|
||||||
|
|
||||||
|
TEST_PASSES_SANITIZE_LEAK=true
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
test_expect_success 'setup' '
|
test_expect_success 'setup' '
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
test_description='am --abort'
|
test_description='am --abort'
|
||||||
|
|
||||||
|
TEST_PASSES_SANITIZE_LEAK=true
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
test_expect_success setup '
|
test_expect_success setup '
|
||||||
|
|
|
@ -9,6 +9,7 @@ test_description='git-am mbox with dos line ending.
|
||||||
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
||||||
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||||
|
|
||||||
|
TEST_PASSES_SANITIZE_LEAK=true
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
# Three patches which will be added as files with dos line ending.
|
# Three patches which will be added as files with dos line ending.
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
test_description='git am handling submodules'
|
test_description='git am handling submodules'
|
||||||
|
|
||||||
|
TEST_PASSES_SANITIZE_LEAK=true
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
. "$TEST_DIRECTORY"/lib-submodule-update.sh
|
. "$TEST_DIRECTORY"/lib-submodule-update.sh
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ test_description='Test the post-rewrite hook.'
|
||||||
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
||||||
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||||
|
|
||||||
|
TEST_PASSES_SANITIZE_LEAK=true
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
test_expect_success 'setup' '
|
test_expect_success 'setup' '
|
||||||
|
|
|
@ -5,6 +5,7 @@ test_description='recursive merge diff3 style conflict markers'
|
||||||
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
||||||
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||||
|
|
||||||
|
TEST_PASSES_SANITIZE_LEAK=true
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
# Setup:
|
# Setup:
|
||||||
|
|
|
@ -10,6 +10,7 @@ test_description='git status advice'
|
||||||
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
||||||
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||||
|
|
||||||
|
TEST_PASSES_SANITIZE_LEAK=true
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
. "$TEST_DIRECTORY"/lib-rebase.sh
|
. "$TEST_DIRECTORY"/lib-rebase.sh
|
||||||
|
|
Loading…
Reference in New Issue