Skip to content

Commit 674e46f

Browse files
committed
Merge branch 'ps/leakfixes-part-7' into ps/leakfixes-part-8
* 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 ...
2 parents 3857aae + 12dfc24 commit 674e46f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+279
-124
lines changed

builtin/difftool.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,12 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
662662
if (fp)
663663
fclose(fp);
664664

665+
hashmap_clear_and_free(&working_tree_dups, struct working_tree_entry, entry);
666+
hashmap_clear_and_free(&wt_modified, struct path_entry, entry);
667+
hashmap_clear_and_free(&tmp_modified, struct path_entry, entry);
668+
hashmap_clear_and_free(&submodules, struct pair_entry, entry);
669+
hashmap_clear_and_free(&symlinks2, struct pair_entry, entry);
670+
release_index(&wtindex);
665671
free(lbase_dir);
666672
free(rbase_dir);
667673
strbuf_release(&info);

builtin/gc.c

Lines changed: 82 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,9 +1478,9 @@ static int maintenance_run_tasks(struct maintenance_run_opts *opts,
14781478

14791479
static void initialize_maintenance_strategy(void)
14801480
{
1481-
char *config_str;
1481+
const char *config_str;
14821482

1483-
if (git_config_get_string("maintenance.strategy", &config_str))
1483+
if (git_config_get_string_tmp("maintenance.strategy", &config_str))
14841484
return;
14851485

14861486
if (!strcasecmp(config_str, "incremental")) {
@@ -1782,32 +1782,33 @@ static const char *get_frequency(enum schedule_priority schedule)
17821782
* * If $GIT_TEST_MAINT_SCHEDULER is set, return true.
17831783
* In this case, the *cmd value is read as input.
17841784
*
1785-
* * if the input value *cmd is the key of one of the comma-separated list
1786-
* item, then *is_available is set to true and *cmd is modified and becomes
1785+
* * if the input value cmd is the key of one of the comma-separated list
1786+
* item, then *is_available is set to true and *out is set to
17871787
* the mock command.
17881788
*
17891789
* * if the input value *cmd isn’t the key of any of the comma-separated list
1790-
* item, then *is_available is set to false.
1790+
* item, then *is_available is set to false and *out is set to the original
1791+
* command.
17911792
*
17921793
* Ex.:
17931794
* GIT_TEST_MAINT_SCHEDULER not set
17941795
* +-------+-------------------------------------------------+
17951796
* | Input | Output |
1796-
* | *cmd | return code | *cmd | *is_available |
1797+
* | *cmd | return code | *out | *is_available |
17971798
* +-------+-------------+-------------------+---------------+
1798-
* | "foo" | false | "foo" (unchanged) | (unchanged) |
1799+
* | "foo" | false | NULL | (unchanged) |
17991800
* +-------+-------------+-------------------+---------------+
18001801
*
18011802
* GIT_TEST_MAINT_SCHEDULER set to “foo:./mock_foo.sh,bar:./mock_bar.sh”
18021803
* +-------+-------------------------------------------------+
18031804
* | Input | Output |
1804-
* | *cmd | return code | *cmd | *is_available |
1805+
* | *cmd | return code | *out | *is_available |
18051806
* +-------+-------------+-------------------+---------------+
18061807
* | "foo" | true | "./mock.foo.sh" | true |
1807-
* | "qux" | true | "qux" (unchanged) | false |
1808+
* | "qux" | true | "qux" (allocated) | false |
18081809
* +-------+-------------+-------------------+---------------+
18091810
*/
1810-
static int get_schedule_cmd(const char **cmd, int *is_available)
1811+
static int get_schedule_cmd(const char *cmd, int *is_available, char **out)
18111812
{
18121813
char *testing = xstrdup_or_null(getenv("GIT_TEST_MAINT_SCHEDULER"));
18131814
struct string_list_item *item;
@@ -1826,16 +1827,22 @@ static int get_schedule_cmd(const char **cmd, int *is_available)
18261827
if (string_list_split_in_place(&pair, item->string, ":", 2) != 2)
18271828
continue;
18281829

1829-
if (!strcmp(*cmd, pair.items[0].string)) {
1830-
*cmd = pair.items[1].string;
1830+
if (!strcmp(cmd, pair.items[0].string)) {
1831+
if (out)
1832+
*out = xstrdup(pair.items[1].string);
18311833
if (is_available)
18321834
*is_available = 1;
1833-
string_list_clear(&list, 0);
1834-
UNLEAK(testing);
1835-
return 1;
1835+
string_list_clear(&pair, 0);
1836+
goto out;
18361837
}
1838+
1839+
string_list_clear(&pair, 0);
18371840
}
18381841

1842+
if (out)
1843+
*out = xstrdup(cmd);
1844+
1845+
out:
18391846
string_list_clear(&list, 0);
18401847
free(testing);
18411848
return 1;
@@ -1852,9 +1859,8 @@ static int get_random_minute(void)
18521859

18531860
static int is_launchctl_available(void)
18541861
{
1855-
const char *cmd = "launchctl";
18561862
int is_available;
1857-
if (get_schedule_cmd(&cmd, &is_available))
1863+
if (get_schedule_cmd("launchctl", &is_available, NULL))
18581864
return is_available;
18591865

18601866
#ifdef __APPLE__
@@ -1892,12 +1898,12 @@ static char *launchctl_get_uid(void)
18921898

18931899
static int launchctl_boot_plist(int enable, const char *filename)
18941900
{
1895-
const char *cmd = "launchctl";
1901+
char *cmd;
18961902
int result;
18971903
struct child_process child = CHILD_PROCESS_INIT;
18981904
char *uid = launchctl_get_uid();
18991905

1900-
get_schedule_cmd(&cmd, NULL);
1906+
get_schedule_cmd("launchctl", NULL, &cmd);
19011907
strvec_split(&child.args, cmd);
19021908
strvec_pushl(&child.args, enable ? "bootstrap" : "bootout", uid,
19031909
filename, NULL);
@@ -1910,6 +1916,7 @@ static int launchctl_boot_plist(int enable, const char *filename)
19101916

19111917
result = finish_command(&child);
19121918

1919+
free(cmd);
19131920
free(uid);
19141921
return result;
19151922
}
@@ -1961,10 +1968,10 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
19611968
static unsigned long lock_file_timeout_ms = ULONG_MAX;
19621969
struct strbuf plist = STRBUF_INIT, plist2 = STRBUF_INIT;
19631970
struct stat st;
1964-
const char *cmd = "launchctl";
1971+
char *cmd;
19651972
int minute = get_random_minute();
19661973

1967-
get_schedule_cmd(&cmd, NULL);
1974+
get_schedule_cmd("launchctl", NULL, &cmd);
19681975
preamble = "<?xml version=\"1.0\"?>\n"
19691976
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
19701977
"<plist version=\"1.0\">"
@@ -2054,6 +2061,7 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
20542061

20552062
free(filename);
20562063
free(name);
2064+
free(cmd);
20572065
strbuf_release(&plist);
20582066
strbuf_release(&plist2);
20592067
return 0;
@@ -2078,9 +2086,8 @@ static int launchctl_update_schedule(int run_maintenance, int fd UNUSED)
20782086

20792087
static int is_schtasks_available(void)
20802088
{
2081-
const char *cmd = "schtasks";
20822089
int is_available;
2083-
if (get_schedule_cmd(&cmd, &is_available))
2090+
if (get_schedule_cmd("schtasks", &is_available, NULL))
20842091
return is_available;
20852092

20862093
#ifdef GIT_WINDOWS_NATIVE
@@ -2099,15 +2106,16 @@ static char *schtasks_task_name(const char *frequency)
20992106

21002107
static int schtasks_remove_task(enum schedule_priority schedule)
21012108
{
2102-
const char *cmd = "schtasks";
2109+
char *cmd;
21032110
struct child_process child = CHILD_PROCESS_INIT;
21042111
const char *frequency = get_frequency(schedule);
21052112
char *name = schtasks_task_name(frequency);
21062113

2107-
get_schedule_cmd(&cmd, NULL);
2114+
get_schedule_cmd("schtasks", NULL, &cmd);
21082115
strvec_split(&child.args, cmd);
21092116
strvec_pushl(&child.args, "/delete", "/tn", name, "/f", NULL);
21102117
free(name);
2118+
free(cmd);
21112119

21122120
return run_command(&child);
21132121
}
@@ -2121,7 +2129,7 @@ static int schtasks_remove_tasks(void)
21212129

21222130
static int schtasks_schedule_task(const char *exec_path, enum schedule_priority schedule)
21232131
{
2124-
const char *cmd = "schtasks";
2132+
char *cmd;
21252133
int result;
21262134
struct child_process child = CHILD_PROCESS_INIT;
21272135
const char *xml;
@@ -2131,7 +2139,7 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priority
21312139
struct strbuf tfilename = STRBUF_INIT;
21322140
int minute = get_random_minute();
21332141

2134-
get_schedule_cmd(&cmd, NULL);
2142+
get_schedule_cmd("schtasks", NULL, &cmd);
21352143

21362144
strbuf_addf(&tfilename, "%s/schedule_%s_XXXXXX",
21372145
repo_get_common_dir(the_repository), frequency);
@@ -2237,6 +2245,7 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priority
22372245

22382246
delete_tempfile(&tfile);
22392247
free(name);
2248+
free(cmd);
22402249
return result;
22412250
}
22422251

@@ -2278,29 +2287,36 @@ static int check_crontab_process(const char *cmd)
22782287

22792288
static int is_crontab_available(void)
22802289
{
2281-
const char *cmd = "crontab";
2290+
char *cmd;
22822291
int is_available;
2292+
int ret;
22832293

2284-
if (get_schedule_cmd(&cmd, &is_available))
2285-
return is_available;
2294+
if (get_schedule_cmd("crontab", &is_available, &cmd)) {
2295+
ret = is_available;
2296+
goto out;
2297+
}
22862298

22872299
#ifdef __APPLE__
22882300
/*
22892301
* macOS has cron, but it requires special permissions and will
22902302
* create a UI alert when attempting to run this command.
22912303
*/
2292-
return 0;
2304+
ret = 0;
22932305
#else
2294-
return check_crontab_process(cmd);
2306+
ret = check_crontab_process(cmd);
22952307
#endif
2308+
2309+
out:
2310+
free(cmd);
2311+
return ret;
22962312
}
22972313

22982314
#define BEGIN_LINE "# BEGIN GIT MAINTENANCE SCHEDULE"
22992315
#define END_LINE "# END GIT MAINTENANCE SCHEDULE"
23002316

23012317
static int crontab_update_schedule(int run_maintenance, int fd)
23022318
{
2303-
const char *cmd = "crontab";
2319+
char *cmd;
23042320
int result = 0;
23052321
int in_old_region = 0;
23062322
struct child_process crontab_list = CHILD_PROCESS_INIT;
@@ -2310,15 +2326,17 @@ static int crontab_update_schedule(int run_maintenance, int fd)
23102326
struct tempfile *tmpedit = NULL;
23112327
int minute = get_random_minute();
23122328

2313-
get_schedule_cmd(&cmd, NULL);
2329+
get_schedule_cmd("crontab", NULL, &cmd);
23142330
strvec_split(&crontab_list.args, cmd);
23152331
strvec_push(&crontab_list.args, "-l");
23162332
crontab_list.in = -1;
23172333
crontab_list.out = dup(fd);
23182334
crontab_list.git_cmd = 0;
23192335

2320-
if (start_command(&crontab_list))
2321-
return error(_("failed to run 'crontab -l'; your system might not support 'cron'"));
2336+
if (start_command(&crontab_list)) {
2337+
result = error(_("failed to run 'crontab -l'; your system might not support 'cron'"));
2338+
goto out;
2339+
}
23222340

23232341
/* Ignore exit code, as an empty crontab will return error. */
23242342
finish_command(&crontab_list);
@@ -2388,8 +2406,10 @@ static int crontab_update_schedule(int run_maintenance, int fd)
23882406
result = error(_("'crontab' died"));
23892407
else
23902408
fclose(cron_list);
2409+
23912410
out:
23922411
delete_tempfile(&tmpedit);
2412+
free(cmd);
23932413
return result;
23942414
}
23952415

@@ -2412,10 +2432,9 @@ static int real_is_systemd_timer_available(void)
24122432

24132433
static int is_systemd_timer_available(void)
24142434
{
2415-
const char *cmd = "systemctl";
24162435
int is_available;
24172436

2418-
if (get_schedule_cmd(&cmd, &is_available))
2437+
if (get_schedule_cmd("systemctl", &is_available, NULL))
24192438
return is_available;
24202439

24212440
return real_is_systemd_timer_available();
@@ -2596,9 +2615,10 @@ static int systemd_timer_enable_unit(int enable,
25962615
enum schedule_priority schedule,
25972616
int minute)
25982617
{
2599-
const char *cmd = "systemctl";
2618+
char *cmd = NULL;
26002619
struct child_process child = CHILD_PROCESS_INIT;
26012620
const char *frequency = get_frequency(schedule);
2621+
int ret;
26022622

26032623
/*
26042624
* Disabling the systemd unit while it is already disabled makes
@@ -2609,30 +2629,43 @@ static int systemd_timer_enable_unit(int enable,
26092629
* On the other hand, enabling a systemd unit which is already enabled
26102630
* produces no error.
26112631
*/
2612-
if (!enable)
2632+
if (!enable) {
26132633
child.no_stderr = 1;
2614-
else if (systemd_timer_write_timer_file(schedule, minute))
2615-
return -1;
2634+
} else if (systemd_timer_write_timer_file(schedule, minute)) {
2635+
ret = -1;
2636+
goto out;
2637+
}
26162638

2617-
get_schedule_cmd(&cmd, NULL);
2639+
get_schedule_cmd("systemctl", NULL, &cmd);
26182640
strvec_split(&child.args, cmd);
26192641
strvec_pushl(&child.args, "--user", enable ? "enable" : "disable",
26202642
"--now", NULL);
26212643
strvec_pushf(&child.args, SYSTEMD_UNIT_FORMAT, frequency, "timer");
26222644

2623-
if (start_command(&child))
2624-
return error(_("failed to start systemctl"));
2625-
if (finish_command(&child))
2645+
if (start_command(&child)) {
2646+
ret = error(_("failed to start systemctl"));
2647+
goto out;
2648+
}
2649+
2650+
if (finish_command(&child)) {
26262651
/*
26272652
* Disabling an already disabled systemd unit makes
26282653
* systemctl fail.
26292654
* Let's ignore this failure.
26302655
*
26312656
* Enabling an enabled systemd unit doesn't fail.
26322657
*/
2633-
if (enable)
2634-
return error(_("failed to run systemctl"));
2635-
return 0;
2658+
if (enable) {
2659+
ret = error(_("failed to run systemctl"));
2660+
goto out;
2661+
}
2662+
}
2663+
2664+
ret = 0;
2665+
2666+
out:
2667+
free(cmd);
2668+
return ret;
26362669
}
26372670

26382671
/*

0 commit comments

Comments
 (0)