1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-10-28 04:49:43 +01:00

Merge branch 'ps/leakfixes-part-7'

More leak-fixes.

* ps/leakfixes-part-7: (23 commits)
  diffcore-break: fix leaking filespecs when merging broken pairs
  revision: fix leaking parents when simplifying commits
  builtin/maintenance: fix leak in `get_schedule_cmd()`
  builtin/maintenance: fix leaking config string
  promisor-remote: fix leaking partial clone filter
  grep: fix leaking grep pattern
  submodule: fix leaking submodule ODB paths
  trace2: destroy context stored in thread-local storage
  builtin/difftool: plug several trivial memory leaks
  builtin/repack: fix leaking configuration
  diffcore-order: fix leaking buffer when parsing orderfiles
  parse-options: free previous value of `OPTION_FILENAME`
  diff: fix leaking orderfile option
  builtin/pull: fix leaking "ff" option
  dir: fix off by one errors for ignored and untracked entries
  builtin/submodule--helper: fix leaking remote ref on errors
  t/helper: fix leaking subrepo in nested submodule config helper
  builtin/submodule--helper: fix leaking error buffer
  builtin/submodule--helper: clear child process when not running it
  submodule: fix leaking update strategy
  ...
This commit is contained in:
Junio C Hamano 2024-10-02 07:46:25 -07:00
commit 365529e1ea
50 changed files with 279 additions and 124 deletions

View file

@ -662,6 +662,12 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
if (fp)
fclose(fp);
hashmap_clear_and_free(&working_tree_dups, struct working_tree_entry, entry);
hashmap_clear_and_free(&wt_modified, struct path_entry, entry);
hashmap_clear_and_free(&tmp_modified, struct path_entry, entry);
hashmap_clear_and_free(&submodules, struct pair_entry, entry);
hashmap_clear_and_free(&symlinks2, struct pair_entry, entry);
release_index(&wtindex);
free(lbase_dir);
free(rbase_dir);
strbuf_release(&info);

View file

@ -1478,9 +1478,9 @@ static int maintenance_run_tasks(struct maintenance_run_opts *opts,
static void initialize_maintenance_strategy(void)
{
char *config_str;
const char *config_str;
if (git_config_get_string("maintenance.strategy", &config_str))
if (git_config_get_string_tmp("maintenance.strategy", &config_str))
return;
if (!strcasecmp(config_str, "incremental")) {
@ -1818,32 +1818,33 @@ static const char *get_extra_launchctl_strings(void) {
* * If $GIT_TEST_MAINT_SCHEDULER is set, return true.
* In this case, the *cmd value is read as input.
*
* * if the input value *cmd is the key of one of the comma-separated list
* item, then *is_available is set to true and *cmd is modified and becomes
* * if the input value cmd is the key of one of the comma-separated list
* item, then *is_available is set to true and *out is set to
* the mock command.
*
* * if the input value *cmd isnt the key of any of the comma-separated list
* item, then *is_available is set to false.
* item, then *is_available is set to false and *out is set to the original
* command.
*
* Ex.:
* GIT_TEST_MAINT_SCHEDULER not set
* +-------+-------------------------------------------------+
* | Input | Output |
* | *cmd | return code | *cmd | *is_available |
* | *cmd | return code | *out | *is_available |
* +-------+-------------+-------------------+---------------+
* | "foo" | false | "foo" (unchanged) | (unchanged) |
* | "foo" | false | NULL | (unchanged) |
* +-------+-------------+-------------------+---------------+
*
* GIT_TEST_MAINT_SCHEDULER set to foo:./mock_foo.sh,bar:./mock_bar.sh
* +-------+-------------------------------------------------+
* | Input | Output |
* | *cmd | return code | *cmd | *is_available |
* | *cmd | return code | *out | *is_available |
* +-------+-------------+-------------------+---------------+
* | "foo" | true | "./mock.foo.sh" | true |
* | "qux" | true | "qux" (unchanged) | false |
* | "qux" | true | "qux" (allocated) | false |
* +-------+-------------+-------------------+---------------+
*/
static int get_schedule_cmd(const char **cmd, int *is_available)
static int get_schedule_cmd(const char *cmd, int *is_available, char **out)
{
char *testing = xstrdup_or_null(getenv("GIT_TEST_MAINT_SCHEDULER"));
struct string_list_item *item;
@ -1862,16 +1863,22 @@ static int get_schedule_cmd(const char **cmd, int *is_available)
if (string_list_split_in_place(&pair, item->string, ":", 2) != 2)
continue;
if (!strcmp(*cmd, pair.items[0].string)) {
*cmd = pair.items[1].string;
if (!strcmp(cmd, pair.items[0].string)) {
if (out)
*out = xstrdup(pair.items[1].string);
if (is_available)
*is_available = 1;
string_list_clear(&list, 0);
UNLEAK(testing);
return 1;
string_list_clear(&pair, 0);
goto out;
}
string_list_clear(&pair, 0);
}
if (out)
*out = xstrdup(cmd);
out:
string_list_clear(&list, 0);
free(testing);
return 1;
@ -1888,9 +1895,8 @@ static int get_random_minute(void)
static int is_launchctl_available(void)
{
const char *cmd = "launchctl";
int is_available;
if (get_schedule_cmd(&cmd, &is_available))
if (get_schedule_cmd("launchctl", &is_available, NULL))
return is_available;
#ifdef __APPLE__
@ -1928,12 +1934,12 @@ static char *launchctl_get_uid(void)
static int launchctl_boot_plist(int enable, const char *filename)
{
const char *cmd = "launchctl";
char *cmd;
int result;
struct child_process child = CHILD_PROCESS_INIT;
char *uid = launchctl_get_uid();
get_schedule_cmd(&cmd, NULL);
get_schedule_cmd("launchctl", NULL, &cmd);
strvec_split(&child.args, cmd);
strvec_pushl(&child.args, enable ? "bootstrap" : "bootout", uid,
filename, NULL);
@ -1946,6 +1952,7 @@ static int launchctl_boot_plist(int enable, const char *filename)
result = finish_command(&child);
free(cmd);
free(uid);
return result;
}
@ -1997,10 +2004,10 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
static unsigned long lock_file_timeout_ms = ULONG_MAX;
struct strbuf plist = STRBUF_INIT, plist2 = STRBUF_INIT;
struct stat st;
const char *cmd = "launchctl";
char *cmd;
int minute = get_random_minute();
get_schedule_cmd(&cmd, NULL);
get_schedule_cmd("launchctl", NULL, &cmd);
preamble = "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
"<plist version=\"1.0\">"
@ -2092,6 +2099,7 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
free(filename);
free(name);
free(cmd);
strbuf_release(&plist);
strbuf_release(&plist2);
return 0;
@ -2116,9 +2124,8 @@ static int launchctl_update_schedule(int run_maintenance, int fd UNUSED)
static int is_schtasks_available(void)
{
const char *cmd = "schtasks";
int is_available;
if (get_schedule_cmd(&cmd, &is_available))
if (get_schedule_cmd("schtasks", &is_available, NULL))
return is_available;
#ifdef GIT_WINDOWS_NATIVE
@ -2137,15 +2144,16 @@ static char *schtasks_task_name(const char *frequency)
static int schtasks_remove_task(enum schedule_priority schedule)
{
const char *cmd = "schtasks";
char *cmd;
struct child_process child = CHILD_PROCESS_INIT;
const char *frequency = get_frequency(schedule);
char *name = schtasks_task_name(frequency);
get_schedule_cmd(&cmd, NULL);
get_schedule_cmd("schtasks", NULL, &cmd);
strvec_split(&child.args, cmd);
strvec_pushl(&child.args, "/delete", "/tn", name, "/f", NULL);
free(name);
free(cmd);
return run_command(&child);
}
@ -2159,7 +2167,7 @@ static int schtasks_remove_tasks(void)
static int schtasks_schedule_task(const char *exec_path, enum schedule_priority schedule)
{
const char *cmd = "schtasks";
char *cmd;
int result;
struct child_process child = CHILD_PROCESS_INIT;
const char *xml;
@ -2169,7 +2177,7 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priority
struct strbuf tfilename = STRBUF_INIT;
int minute = get_random_minute();
get_schedule_cmd(&cmd, NULL);
get_schedule_cmd("schtasks", NULL, &cmd);
strbuf_addf(&tfilename, "%s/schedule_%s_XXXXXX",
repo_get_common_dir(the_repository), frequency);
@ -2276,6 +2284,7 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priority
delete_tempfile(&tfile);
free(name);
free(cmd);
return result;
}
@ -2317,21 +2326,28 @@ static int check_crontab_process(const char *cmd)
static int is_crontab_available(void)
{
const char *cmd = "crontab";
char *cmd;
int is_available;
int ret;
if (get_schedule_cmd(&cmd, &is_available))
return is_available;
if (get_schedule_cmd("crontab", &is_available, &cmd)) {
ret = is_available;
goto out;
}
#ifdef __APPLE__
/*
* macOS has cron, but it requires special permissions and will
* create a UI alert when attempting to run this command.
*/
return 0;
ret = 0;
#else
return check_crontab_process(cmd);
ret = check_crontab_process(cmd);
#endif
out:
free(cmd);
return ret;
}
#define BEGIN_LINE "# BEGIN GIT MAINTENANCE SCHEDULE"
@ -2339,7 +2355,7 @@ static int is_crontab_available(void)
static int crontab_update_schedule(int run_maintenance, int fd)
{
const char *cmd = "crontab";
char *cmd;
int result = 0;
int in_old_region = 0;
struct child_process crontab_list = CHILD_PROCESS_INIT;
@ -2349,15 +2365,17 @@ static int crontab_update_schedule(int run_maintenance, int fd)
struct tempfile *tmpedit = NULL;
int minute = get_random_minute();
get_schedule_cmd(&cmd, NULL);
get_schedule_cmd("crontab", NULL, &cmd);
strvec_split(&crontab_list.args, cmd);
strvec_push(&crontab_list.args, "-l");
crontab_list.in = -1;
crontab_list.out = dup(fd);
crontab_list.git_cmd = 0;
if (start_command(&crontab_list))
return error(_("failed to run 'crontab -l'; your system might not support 'cron'"));
if (start_command(&crontab_list)) {
result = error(_("failed to run 'crontab -l'; your system might not support 'cron'"));
goto out;
}
/* Ignore exit code, as an empty crontab will return error. */
finish_command(&crontab_list);
@ -2427,8 +2445,10 @@ static int crontab_update_schedule(int run_maintenance, int fd)
result = error(_("'crontab' died"));
else
fclose(cron_list);
out:
delete_tempfile(&tmpedit);
free(cmd);
return result;
}
@ -2451,10 +2471,9 @@ static int real_is_systemd_timer_available(void)
static int is_systemd_timer_available(void)
{
const char *cmd = "systemctl";
int is_available;
if (get_schedule_cmd(&cmd, &is_available))
if (get_schedule_cmd("systemctl", &is_available, NULL))
return is_available;
return real_is_systemd_timer_available();
@ -2635,9 +2654,10 @@ static int systemd_timer_enable_unit(int enable,
enum schedule_priority schedule,
int minute)
{
const char *cmd = "systemctl";
char *cmd = NULL;
struct child_process child = CHILD_PROCESS_INIT;
const char *frequency = get_frequency(schedule);
int ret;
/*
* Disabling the systemd unit while it is already disabled makes
@ -2648,20 +2668,25 @@ static int systemd_timer_enable_unit(int enable,
* On the other hand, enabling a systemd unit which is already enabled
* produces no error.
*/
if (!enable)
if (!enable) {
child.no_stderr = 1;
else if (systemd_timer_write_timer_file(schedule, minute))
return -1;
} else if (systemd_timer_write_timer_file(schedule, minute)) {
ret = -1;
goto out;
}
get_schedule_cmd(&cmd, NULL);
get_schedule_cmd("systemctl", NULL, &cmd);
strvec_split(&child.args, cmd);
strvec_pushl(&child.args, "--user", enable ? "enable" : "disable",
"--now", NULL);
strvec_pushf(&child.args, SYSTEMD_UNIT_FORMAT, frequency, "timer");
if (start_command(&child))
return error(_("failed to start systemctl"));
if (finish_command(&child))
if (start_command(&child)) {
ret = error(_("failed to start systemctl"));
goto out;
}
if (finish_command(&child)) {
/*
* Disabling an already disabled systemd unit makes
* systemctl fail.
@ -2669,9 +2694,17 @@ static int systemd_timer_enable_unit(int enable,
*
* Enabling an enabled systemd unit doesn't fail.
*/
if (enable)
return error(_("failed to run systemctl"));
return 0;
if (enable) {
ret = error(_("failed to run systemctl"));
goto out;
}
}
ret = 0;
out:
free(cmd);
return ret;
}
/*

View file

@ -54,7 +54,7 @@ static enum help_action {
HELP_ACTION_CONFIG_SECTIONS_FOR_COMPLETION,
} cmd_mode;
static const char *html_path;
static char *html_path;
static int verbose = 1;
static enum help_format help_format = HELP_FORMAT_NONE;
static int exclude_guides;
@ -411,6 +411,7 @@ static int git_help_config(const char *var, const char *value,
if (!strcmp(var, "help.htmlpath")) {
if (!value)
return config_error_nonbool(var);
free(html_path);
html_path = xstrdup(value);
return 0;
}
@ -515,23 +516,24 @@ static void show_info_page(const char *page)
static void get_html_page_path(struct strbuf *page_path, const char *page)
{
struct stat st;
const char *path = html_path;
char *to_free = NULL;
if (!html_path)
html_path = to_free = system_path(GIT_HTML_PATH);
if (!path)
path = to_free = system_path(GIT_HTML_PATH);
/*
* Check that the page we're looking for exists.
*/
if (!strstr(html_path, "://")) {
if (stat(mkpath("%s/%s.html", html_path, page), &st)
if (!strstr(path, "://")) {
if (stat(mkpath("%s/%s.html", path, page), &st)
|| !S_ISREG(st.st_mode))
die("'%s/%s.html': documentation file not found.",
html_path, page);
path, page);
}
strbuf_init(page_path, 0);
strbuf_addf(page_path, "%s/%s.html", html_path, page);
strbuf_addf(page_path, "%s/%s.html", path, page);
free(to_free);
}

View file

@ -85,7 +85,7 @@ static const char *opt_squash;
static const char *opt_commit;
static const char *opt_edit;
static const char *cleanup_arg;
static const char *opt_ff;
static char *opt_ff;
static const char *opt_verify_signatures;
static const char *opt_verify;
static int opt_autostash = -1;
@ -1028,8 +1028,10 @@ int cmd_pull(int argc,
* "--rebase" can override a config setting of
* pull.ff=only.
*/
if (opt_rebase >= 0 && opt_ff && !strcmp(opt_ff, "--ff-only"))
opt_ff = "--ff";
if (opt_rebase >= 0 && opt_ff && !strcmp(opt_ff, "--ff-only")) {
free(opt_ff);
opt_ff = xstrdup("--ff");
}
}
if (opt_rebase < 0)
@ -1139,7 +1141,8 @@ int cmd_pull(int argc,
if (can_ff) {
/* we can fast-forward this without invoking rebase */
opt_ff = "--ff-only";
free(opt_ff);
opt_ff = xstrdup("--ff-only");
ret = run_merge();
} else {
ret = run_rebase(&newbase, &upstream);

View file

@ -86,17 +86,34 @@ static int repack_config(const char *var, const char *value,
run_update_server_info = git_config_bool(var, value);
return 0;
}
if (!strcmp(var, "repack.cruftwindow"))
if (!strcmp(var, "repack.cruftwindow")) {
free(cruft_po_args->window);
return git_config_string(&cruft_po_args->window, var, value);
if (!strcmp(var, "repack.cruftwindowmemory"))
}
if (!strcmp(var, "repack.cruftwindowmemory")) {
free(cruft_po_args->window_memory);
return git_config_string(&cruft_po_args->window_memory, var, value);
if (!strcmp(var, "repack.cruftdepth"))
}
if (!strcmp(var, "repack.cruftdepth")) {
free(cruft_po_args->depth);
return git_config_string(&cruft_po_args->depth, var, value);
if (!strcmp(var, "repack.cruftthreads"))
}
if (!strcmp(var, "repack.cruftthreads")) {
free(cruft_po_args->threads);
return git_config_string(&cruft_po_args->threads, var, value);
}
return git_default_config(var, value, ctx, cb);
}
static void pack_objects_args_release(struct pack_objects_args *args)
{
free(args->window);
free(args->window_memory);
free(args->depth);
free(args->threads);
list_objects_filter_release(&args->filter_options);
}
struct existing_packs {
struct string_list kept_packs;
struct string_list non_kept_packs;
@ -1156,12 +1173,16 @@ int cmd_repack(int argc,
const char *unpack_unreachable = NULL;
int keep_unreachable = 0;
struct string_list keep_pack_list = STRING_LIST_INIT_NODUP;
struct pack_objects_args po_args = {NULL};
struct pack_objects_args cruft_po_args = {NULL};
struct pack_objects_args po_args = { 0 };
struct pack_objects_args cruft_po_args = { 0 };
int write_midx = 0;
const char *cruft_expiration = NULL;
const char *expire_to = NULL;
const char *filter_to = NULL;
const char *opt_window = NULL;
const char *opt_window_memory = NULL;
const char *opt_depth = NULL;
const char *opt_threads = NULL;
struct option builtin_repack_options[] = {
OPT_BIT('a', NULL, &pack_everything,
@ -1195,13 +1216,13 @@ int cmd_repack(int argc,
N_("with -A, do not loosen objects older than this")),
OPT_BOOL('k', "keep-unreachable", &keep_unreachable,
N_("with -a, repack unreachable objects")),
OPT_STRING(0, "window", &po_args.window, N_("n"),
OPT_STRING(0, "window", &opt_window, N_("n"),
N_("size of the window used for delta compression")),
OPT_STRING(0, "window-memory", &po_args.window_memory, N_("bytes"),
OPT_STRING(0, "window-memory", &opt_window_memory, N_("bytes"),
N_("same as the above, but limit memory size instead of entries count")),
OPT_STRING(0, "depth", &po_args.depth, N_("n"),
OPT_STRING(0, "depth", &opt_depth, N_("n"),
N_("limits the maximum delta depth")),
OPT_STRING(0, "threads", &po_args.threads, N_("n"),
OPT_STRING(0, "threads", &opt_threads, N_("n"),
N_("limits the maximum number of threads")),
OPT_MAGNITUDE(0, "max-pack-size", &po_args.max_pack_size,
N_("maximum size of each packfile")),
@ -1228,6 +1249,11 @@ int cmd_repack(int argc,
argc = parse_options(argc, argv, prefix, builtin_repack_options,
git_repack_usage, 0);
po_args.window = xstrdup_or_null(opt_window);
po_args.window_memory = xstrdup_or_null(opt_window_memory);
po_args.depth = xstrdup_or_null(opt_depth);
po_args.threads = xstrdup_or_null(opt_threads);
if (delete_redundant && repository_format_precious_objects)
die(_("cannot delete packs in a precious-objects repo"));
@ -1393,13 +1419,13 @@ int cmd_repack(int argc,
const char *pack_prefix = find_pack_prefix(packdir, packtmp);
if (!cruft_po_args.window)
cruft_po_args.window = po_args.window;
cruft_po_args.window = xstrdup_or_null(po_args.window);
if (!cruft_po_args.window_memory)
cruft_po_args.window_memory = po_args.window_memory;
cruft_po_args.window_memory = xstrdup_or_null(po_args.window_memory);
if (!cruft_po_args.depth)
cruft_po_args.depth = po_args.depth;
cruft_po_args.depth = xstrdup_or_null(po_args.depth);
if (!cruft_po_args.threads)
cruft_po_args.threads = po_args.threads;
cruft_po_args.threads = xstrdup_or_null(po_args.threads);
if (!cruft_po_args.max_pack_size)
cruft_po_args.max_pack_size = po_args.max_pack_size;
@ -1552,7 +1578,8 @@ int cmd_repack(int argc,
string_list_clear(&names, 1);
existing_packs_release(&existing);
free_pack_geometry(&geometry);
list_objects_filter_release(&po_args.filter_options);
pack_objects_args_release(&po_args);
pack_objects_args_release(&cruft_po_args);
return ret;
}

View file

@ -364,9 +364,13 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
if (!info->quiet)
printf(_("Entering '%s'\n"), displaypath);
if (info->argv[0] && run_command(&cp))
die(_("run_command returned non-zero status for %s\n."),
displaypath);
if (info->argv[0]) {
if (run_command(&cp))
die(_("run_command returned non-zero status for %s\n."),
displaypath);
} else {
child_process_clear(&cp);
}
if (info->recursive) {
struct child_process cpr = CHILD_PROCESS_INIT;
@ -1622,6 +1626,8 @@ static int add_possible_reference_from_superproject(
; /* nothing */
}
}
strbuf_release(&err);
strbuf_release(&sb);
}
@ -2026,6 +2032,7 @@ struct update_data {
static void update_data_release(struct update_data *ud)
{
free(ud->displaypath);
submodule_update_strategy_release(&ud->update_strategy);
module_list_release(&ud->list);
}
@ -2646,15 +2653,20 @@ static int update_submodule(struct update_data *update_data)
if (!update_data->nofetch) {
if (fetch_in_submodule(update_data->sm_path, update_data->depth,
0, NULL))
0, NULL)) {
free(remote_ref);
return die_message(_("Unable to fetch in submodule path '%s'"),
update_data->sm_path);
}
}
if (repo_resolve_gitlink_ref(the_repository, update_data->sm_path,
remote_ref, &update_data->oid))
return die_message(_("Unable to find %s revision in submodule path '%s'"),
remote_ref, update_data->sm_path);
remote_ref, &update_data->oid)) {
ret = die_message(_("Unable to find %s revision in submodule path '%s'"),
remote_ref, update_data->sm_path);
free(remote_ref);
return ret;
}
free(remote_ref);
}

View file

@ -1393,9 +1393,8 @@ static struct combine_diff_path *find_paths_generic(const struct object_id *oid,
{
struct combine_diff_path *paths = NULL;
int i, num_parent = parents->nr;
int output_format = opt->output_format;
const char *orderfile = opt->orderfile;
char *orderfile = opt->orderfile;
opt->output_format = DIFF_FORMAT_NO_OUTPUT;
/* tell diff_tree to emit paths in sorted (=tree) order */

7
diff.c
View file

@ -443,8 +443,10 @@ int git_diff_ui_config(const char *var, const char *value,
}
if (!strcmp(var, "diff.wordregex"))
return git_config_string(&diff_word_regex_cfg, var, value);
if (!strcmp(var, "diff.orderfile"))
if (!strcmp(var, "diff.orderfile")) {
FREE_AND_NULL(diff_order_file_cfg);
return git_config_pathname(&diff_order_file_cfg, var, value);
}
if (!strcmp(var, "diff.ignoresubmodules")) {
if (!value)
@ -4778,7 +4780,7 @@ void repo_diff_setup(struct repository *r, struct diff_options *options)
if (diff_indent_heuristic)
DIFF_XDL_SET(options, INDENT_HEURISTIC);
options->orderfile = diff_order_file_cfg;
options->orderfile = xstrdup_or_null(diff_order_file_cfg);
if (!options->flags.ignore_submodule_set)
options->flags.ignore_untracked_in_submodules = 1;
@ -6730,6 +6732,7 @@ void diff_free(struct diff_options *options)
FREE_AND_NULL(options->objfind);
}
FREE_AND_NULL(options->orderfile);
for (size_t i = 0; i < options->anchors_nr; i++)
free(options->anchors[i]);
FREE_AND_NULL(options->anchors);

2
diff.h
View file

@ -235,7 +235,7 @@ enum diff_submodule_format {
* diffcore library with.
*/
struct diff_options {
const char *orderfile;
char *orderfile;
/*
* "--rotate-to=<file>" would start showing at <file> and when

View file

@ -266,8 +266,8 @@ static void merge_broken(struct diff_filepair *p,
* in the resulting tree.
*/
d->one->rename_used++;
diff_free_filespec_data(d->two);
diff_free_filespec_data(c->one);
free_filespec(d->two);
free_filespec(c->one);
free(d);
free(c);
}

View file

@ -14,8 +14,7 @@ static void prepare_order(const char *orderfile)
{
int cnt, pass;
struct strbuf sb = STRBUF_INIT;
void *map;
char *cp, *endp;
const char *cp, *endp;
ssize_t sz;
if (order)
@ -24,14 +23,13 @@ static void prepare_order(const char *orderfile)
sz = strbuf_read_file(&sb, orderfile, 0);
if (sz < 0)
die_errno(_("failed to read orderfile '%s'"), orderfile);
map = strbuf_detach(&sb, NULL);
endp = (char *) map + sz;
endp = sb.buf + sz;
for (pass = 0; pass < 2; pass++) {
cnt = 0;
cp = map;
cp = sb.buf;
while (cp < endp) {
char *ep;
const char *ep;
for (ep = cp; ep < endp && *ep != '\n'; ep++)
;
/* cp to ep has one line */
@ -40,12 +38,7 @@ static void prepare_order(const char *orderfile)
else if (pass == 0)
cnt++;
else {
if (*ep == '\n') {
*ep = 0;
order[cnt] = cp;
} else {
order[cnt] = xmemdupz(cp, ep - cp);
}
order[cnt] = xmemdupz(cp, ep - cp);
cnt++;
}
if (ep < endp)
@ -57,6 +50,8 @@ static void prepare_order(const char *orderfile)
ALLOC_ARRAY(order, cnt);
}
}
strbuf_release(&sb);
}
static int match_order(const char *path)

6
dir.c
View file

@ -2136,8 +2136,7 @@ static enum path_treatment treat_directory(struct dir_struct *dir,
*/
state = path_none;
} else {
int i;
for (i = old_ignored_nr + 1; i<dir->ignored_nr; ++i)
for (int i = old_ignored_nr; i < dir->ignored_nr; i++)
FREE_AND_NULL(dir->ignored[i]);
dir->ignored_nr = old_ignored_nr;
}
@ -2149,8 +2148,7 @@ static enum path_treatment treat_directory(struct dir_struct *dir,
*/
if ((dir->flags & DIR_SHOW_IGNORED_TOO) &&
!(dir->flags & DIR_KEEP_UNTRACKED_CONTENTS)) {
int i;
for (i = old_untracked_nr + 1; i<dir->nr; ++i)
for (int i = old_untracked_nr; i < dir->nr; i++)
FREE_AND_NULL(dir->entries[i]);
dir->nr = old_untracked_nr;
}

22
git.c
View file

@ -711,6 +711,7 @@ static void strip_extension(const char **argv)
static void handle_builtin(int argc, const char **argv)
{
struct strvec args = STRVEC_INIT;
const char **argv_copy = NULL;
const char *cmd;
struct cmd_struct *builtin;
@ -731,13 +732,28 @@ static void handle_builtin(int argc, const char **argv)
}
argc++;
argv = args.v;
/*
* `run_builtin()` will modify the argv array, so we need to
* create a shallow copy such that we can free all of its
* strings.
*/
CALLOC_ARRAY(argv_copy, argc + 1);
COPY_ARRAY(argv_copy, args.v, argc);
argv = argv_copy;
}
builtin = get_builtin(cmd);
if (builtin)
exit(run_builtin(builtin, argc, argv, the_repository));
if (builtin) {
int ret = run_builtin(builtin, argc, argv, the_repository);
strvec_clear(&args);
free(argv_copy);
exit(ret);
}
strvec_clear(&args);
free(argv_copy);
}
static void execv_dashed_external(const char **argv)

2
grep.c
View file

@ -843,11 +843,11 @@ static void free_grep_pat(struct grep_pat *pattern)
free_pcre2_pattern(p);
else
regfree(&p->regexp);
free(p->pattern);
break;
default:
break;
}
free(p->pattern);
free(p);
}
}

View file

@ -60,12 +60,12 @@ static enum parse_opt_result get_arg(struct parse_opt_ctx_t *p,
return 0;
}
static void fix_filename(const char *prefix, char **file)
static char *fix_filename(const char *prefix, const char *file)
{
if (!file || !*file)
; /* leave as NULL */
return NULL;
else
*file = prefix_filename_except_for_dash(prefix, *file);
return prefix_filename_except_for_dash(prefix, file);
}
static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
@ -129,18 +129,24 @@ static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
return 0;
case OPTION_FILENAME:
{
const char *value;
FREE_AND_NULL(*(char **)opt->value);
err = 0;
if (unset)
*(const char **)opt->value = NULL;
value = NULL;
else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
*(const char **)opt->value = (const char *)opt->defval;
value = (const char *) opt->defval;
else
err = get_arg(p, opt, flags, (const char **)opt->value);
err = get_arg(p, opt, flags, &value);
if (!err)
fix_filename(p->prefix, (char **)opt->value);
*(char **)opt->value = fix_filename(p->prefix, value);
return err;
}
case OPTION_CALLBACK:
{
const char *p_arg = NULL;

View file

@ -154,6 +154,7 @@ static int promisor_remote_config(const char *var, const char *value,
if (!r)
return 0;
FREE_AND_NULL(r->partial_clone_filter);
return git_config_string(&r->partial_clone_filter, var, value);
}
@ -189,6 +190,7 @@ void promisor_remote_clear(struct promisor_remote_config *config)
{
while (config->promisors) {
struct promisor_remote *r = config->promisors;
free(r->partial_clone_filter);
config->promisors = config->promisors->next;
free(r);
}

View file

@ -1071,7 +1071,11 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
ts->treesame[nth_parent] = 1;
continue;
}
free_commit_list(parent->next);
parent->next = NULL;
while (commit->parents != parent)
pop_commit(&commit->parents);
commit->parents = parent;
/*
@ -1103,6 +1107,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
die("cannot simplify commit %s (invalid %s)",
oid_to_hex(&commit->object.oid),
oid_to_hex(&p->object.oid));
free_commit_list(p->parents);
p->parents = NULL;
}
/* fallthrough */

View file

@ -95,7 +95,7 @@ static void free_one_config(struct submodule_entry *entry)
free((void *) entry->config->branch);
free((void *) entry->config->url);
free((void *) entry->config->ignore);
free((void *) entry->config->update_strategy.command);
submodule_update_strategy_release(&entry->config->update_strategy);
free(entry->config);
}

View file

@ -175,11 +175,11 @@ void stage_updated_gitmodules(struct index_state *istate)
die(_("staging updated .gitmodules failed"));
}
static struct string_list added_submodule_odb_paths = STRING_LIST_INIT_NODUP;
static struct string_list added_submodule_odb_paths = STRING_LIST_INIT_DUP;
void add_submodule_odb_by_path(const char *path)
{
string_list_insert(&added_submodule_odb_paths, xstrdup(path));
string_list_insert(&added_submodule_odb_paths, path);
}
int register_all_submodule_odb_as_alternates(void)
@ -424,6 +424,11 @@ int parse_submodule_update_strategy(const char *value,
return 0;
}
void submodule_update_strategy_release(struct submodule_update_strategy *strategy)
{
free((char *) strategy->command);
}
const char *submodule_update_type_to_string(enum submodule_update_type type)
{
switch (type) {

View file

@ -41,6 +41,10 @@ struct submodule_update_strategy {
.type = SM_UPDATE_UNSPECIFIED, \
}
int parse_submodule_update_strategy(const char *value,
struct submodule_update_strategy *dst);
void submodule_update_strategy_release(struct submodule_update_strategy *strategy);
int is_gitmodules_unmerged(struct index_state *istate);
int is_writing_gitmodules_ok(void);
int is_staging_gitmodules_ok(struct index_state *istate);
@ -70,8 +74,6 @@ void die_in_unpopulated_submodule(struct index_state *istate,
void die_path_inside_submodule(struct index_state *istate,
const struct pathspec *ps);
enum submodule_update_type parse_submodule_update_type(const char *value);
int parse_submodule_update_strategy(const char *value,
struct submodule_update_strategy *dst);
const char *submodule_update_type_to_string(enum submodule_update_type type);
void handle_ignore_submodules_arg(struct diff_options *, const char *);
void show_submodule_diff_summary(struct diff_options *o, const char *path,

View file

@ -29,6 +29,6 @@ int cmd__submodule_nested_repo_config(int argc, const char **argv)
print_config_from_gitmodules(&subrepo, argv[2]);
submodule_free(the_repository);
repo_clear(&subrepo);
return 0;
}

View file

@ -2,6 +2,7 @@
test_description='help'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
configure_help () {

View file

@ -4,6 +4,7 @@ test_description='various tests of reflog walk (log -g) behavior'
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 'set up some reflog entries' '

View file

@ -2,6 +2,7 @@
test_description='directory traversal handling, especially with common prefixes'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '

View file

@ -21,6 +21,8 @@ With -B, this should be detected as two complete rewrites.
Further, with -B and -M together, these should turn into two renames.
'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-diff.sh ;# test-lib chdir's into trash

View file

@ -2,6 +2,7 @@
test_description='rewrite diff'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-diff-data.sh

View file

@ -2,6 +2,7 @@
test_description='typechange rename detection'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-diff.sh

View file

@ -2,6 +2,7 @@
test_description='rewrite diff on binary file'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# We must be large enough to meet the MINIMUM_BREAK_SIZE

View file

@ -5,6 +5,7 @@ test_description='diff order & rotate'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
create_files () {

View file

@ -5,6 +5,7 @@ test_description='git patch-id'
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' '

View file

@ -2,6 +2,7 @@
test_description='exercise basic bitmap functionality'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-bitmap.sh

View file

@ -1,6 +1,8 @@
#!/bin/sh
test_description='exercise basic multi-pack bitmap functionality'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "${TEST_DIRECTORY}/lib-bitmap.sh"

View file

@ -1,6 +1,8 @@
#!/bin/sh
test_description='cruft pack related pack-objects tests'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
objdir=.git/objects

View file

@ -16,6 +16,7 @@ test_description='git rev-list trivial path optimization test
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 '

View file

@ -29,6 +29,7 @@ test_description='--ancestry-path'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_merge () {

View file

@ -16,6 +16,7 @@ test_description='TREESAME and limiting'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
note () {

View file

@ -2,6 +2,7 @@
test_description='git-status ignored files'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
cat >expected <<\EOF

View file

@ -12,6 +12,7 @@ submodule and "git submodule update --rebase/--merge" does not detach the HEAD.
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh

View file

@ -12,6 +12,7 @@ that are currently checked out.
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh

View file

@ -4,6 +4,8 @@
#
test_description='test clone --reference'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
base_dir=$(pwd)

View file

@ -10,6 +10,7 @@ from the database and from the worktree works.
'
TEST_NO_CREATE_REPO=1
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '

View file

@ -10,6 +10,7 @@ as expected.
'
TEST_NO_CREATE_REPO=1
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '

View file

@ -2,6 +2,7 @@
test_description='git status ignored modes'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup initial commit and ignore file' '

View file

@ -1,6 +1,8 @@
#!/bin/sh
test_description='git commit summary'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '

View file

@ -4,6 +4,7 @@ test_description='git merge
Testing pull.* configuration parsing and other things.'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '

View file

@ -2,6 +2,7 @@
test_description='git repack works correctly'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "${TEST_DIRECTORY}/lib-bitmap.sh"
. "${TEST_DIRECTORY}/lib-midx.sh"

View file

@ -11,6 +11,7 @@ Testing basic diff tool invocation
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
difftool_test_setup ()

View file

@ -7,6 +7,7 @@ submodules.
'
TEST_CREATE_REPO_NO_TEMPLATE=1
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1

View file

@ -2,6 +2,7 @@
test_description='git maintenance builtin'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
GIT_TEST_COMMIT_GRAPH=0

View file

@ -152,11 +152,19 @@ uint64_t tr2tls_absolute_elapsed(uint64_t us)
return us - tr2tls_us_start_process;
}
static void tr2tls_key_destructor(void *payload)
{
struct tr2tls_thread_ctx *ctx = payload;
free((char *)ctx->thread_name);
free(ctx->array_us_start);
free(ctx);
}
void tr2tls_init(void)
{
tr2tls_start_process_clock();
pthread_key_create(&tr2tls_key, NULL);
pthread_key_create(&tr2tls_key, tr2tls_key_destructor);
init_recursive_mutex(&tr2tls_mutex);
tr2tls_thread_main =