config: plug various memory leaks

Now that memory ownership rules around `git_config_string()` and `git_config_pathname()` are clearer, it also got easier to spot that the returned memory needs to be free'd. Plug a subset of those cases and mark now-passing tests as leak free. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed May 27, 2024 at 13:46 UTC 49eb597ce08de7fc4837155fa7910dace92b9ae6
13 files changed +40 -12
alias.c
+3 -1
@@ -21,9 +21,11 @@ static int config_alias_cb(const char *key, const char *value,
21 return 0;
22
23 if (data->alias) {
24 - if (!strcasecmp(p, data->alias))
24 + if (!strcasecmp(p, data->alias)) {
25 + FREE_AND_NULL(data->v);
26 return git_config_string(&data->v,
27 key, value);
28 + }
29 } else if (data->list) {
30 string_list_append(data->list, p);
31 }
config.c
+27 -9
@@ -1414,8 +1414,10 @@ static int git_default_core_config(const char *var, const char *value,
1414 return 0;
1415 }
1416
1417 - if (!strcmp(var, "core.attributesfile"))
1417 + if (!strcmp(var, "core.attributesfile")) {
1418 + FREE_AND_NULL(git_attributes_file);
1419 return git_config_pathname(&git_attributes_file, var, value);
1420 + }
1421
1422 if (!strcmp(var, "core.hookspath")) {
1423 if (ctx->kvi && ctx->kvi->scope == CONFIG_SCOPE_LOCAL &&
@@ -1428,6 +1430,7 @@ static int git_default_core_config(const char *var, const char *value,
1430 "again with "
1431 "`GIT_CLONE_PROTECTION_ACTIVE=false`"),
1432 value);
1433 + FREE_AND_NULL(git_hooks_path);
1434 return git_config_pathname(&git_hooks_path, var, value);
1435 }
1436
@@ -1576,8 +1579,10 @@ static int git_default_core_config(const char *var, const char *value,
1579 return 0;
1580 }
1581
1579 - if (!strcmp(var, "core.editor"))
1582 + if (!strcmp(var, "core.editor")) {
1583 + FREE_AND_NULL(editor_program);
1584 return git_config_string(&editor_program, var, value);
1585 + }
1586
1587 if (!strcmp(var, "core.commentchar") ||
1588 !strcmp(var, "core.commentstring")) {
@@ -1595,11 +1600,13 @@ static int git_default_core_config(const char *var, const char *value,
1600 return 0;
1601 }
1602
1598 - if (!strcmp(var, "core.askpass"))
1603 + if (!strcmp(var, "core.askpass")) {
1604 + FREE_AND_NULL(askpass_program);
1605 return git_config_string(&askpass_program, var, value);
1606 + }
1607
1608 if (!strcmp(var, "core.excludesfile")) {
1602 - free(excludes_file);
1609 + FREE_AND_NULL(excludes_file);
1610 return git_config_pathname(&excludes_file, var, value);
1611 }
1612
@@ -1702,11 +1709,15 @@ static int git_default_sparse_config(const char *var, const char *value)
1709
1710 static int git_default_i18n_config(const char *var, const char *value)
1711 {
1705 - if (!strcmp(var, "i18n.commitencoding"))
1712 + if (!strcmp(var, "i18n.commitencoding")) {
1713 + FREE_AND_NULL(git_commit_encoding);
1714 return git_config_string(&git_commit_encoding, var, value);
1715 + }
1716
1708 - if (!strcmp(var, "i18n.logoutputencoding"))
1717 + if (!strcmp(var, "i18n.logoutputencoding")) {
1718 + FREE_AND_NULL(git_log_output_encoding);
1719 return git_config_string(&git_log_output_encoding, var, value);
1720 + }
1721
1722 /* Add other config variables here and to Documentation/config.txt. */
1723 return 0;
@@ -1779,10 +1790,15 @@ static int git_default_push_config(const char *var, const char *value)
1790
1791 static int git_default_mailmap_config(const char *var, const char *value)
1792 {
1782 - if (!strcmp(var, "mailmap.file"))
1793 + if (!strcmp(var, "mailmap.file")) {
1794 + FREE_AND_NULL(git_mailmap_file);
1795 return git_config_pathname(&git_mailmap_file, var, value);
1784 - if (!strcmp(var, "mailmap.blob"))
1796 + }
1797 +
1798 + if (!strcmp(var, "mailmap.blob")) {
1799 + FREE_AND_NULL(git_mailmap_blob);
1800 return git_config_string(&git_mailmap_blob, var, value);
1801 + }
1802
1803 /* Add other config variables here and to Documentation/config.txt. */
1804 return 0;
@@ -1790,8 +1806,10 @@ static int git_default_mailmap_config(const char *var, const char *value)
1806
1807 static int git_default_attr_config(const char *var, const char *value)
1808 {
1793 - if (!strcmp(var, "attr.tree"))
1809 + if (!strcmp(var, "attr.tree")) {
1810 + FREE_AND_NULL(git_attr_tree);
1811 return git_config_string(&git_attr_tree, var, value);
1812 + }
1813
1814 /*
1815 * Add other attribute related config variables here and to
t/t1306-xdg-files.sh
+1
@@ -7,6 +7,7 @@
7
8 test_description='Compatibility with $XDG_CONFIG_HOME/git/ files'
9
10 +TEST_PASSES_SANITIZE_LEAK=true
11 . ./test-lib.sh
12
13 test_expect_success 'read config: xdg file exists and ~/.gitconfig doesn'\''t' '
t/t1350-config-hooks-path.sh
+1
@@ -2,6 +2,7 @@
2
3 test_description='Test the core.hooksPath configuration variable'
4
5 +TEST_PASSES_SANITIZE_LEAK=true
6 . ./test-lib.sh
7
8 test_expect_success 'set up a pre-commit hook in core.hooksPath' '
t/t3415-rebase-autosquash.sh
+1
@@ -5,6 +5,7 @@ test_description='auto squash'
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7
8 +TEST_PASSES_SANITIZE_LEAK=true
9 . ./test-lib.sh
10
11 . "$TEST_DIRECTORY"/lib-rebase.sh
t/t4041-diff-submodule-option.sh
+1
@@ -12,6 +12,7 @@ This test tries to verify the sanity of the --submodule option of git diff.
12 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
13 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
14
15 +TEST_PASSES_SANITIZE_LEAK=true
16 . ./test-lib.sh
17
18 # Tested non-UTF-8 encoding
t/t4060-diff-submodule-option-diff-format.sh
+1
@@ -10,6 +10,7 @@ test_description='Support for diff format verbose submodule difference in git di
10 This test tries to verify the sanity of --submodule=diff option of git diff.
11 '
12
13 +TEST_PASSES_SANITIZE_LEAK=true
14 . ./test-lib.sh
15
16 # Tested non-UTF-8 encoding
t/t4210-log-i18n.sh
+2
@@ -1,6 +1,8 @@
1 #!/bin/sh
2
3 test_description='test log with i18n features'
4 +
5 +TEST_PASSES_SANITIZE_LEAK=true
6 . ./lib-gettext.sh
7
8 # two forms of é
t/t6006-rev-list-format.sh
+1
@@ -8,6 +8,7 @@ test_description='git rev-list --pretty=format test'
8 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
9 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
10
11 +TEST_PASSES_SANITIZE_LEAK=true
12 . ./test-lib.sh
13 . "$TEST_DIRECTORY"/lib-terminal.sh
14
t/t7005-editor.sh
+1
@@ -2,6 +2,7 @@
2
3 test_description='GIT_EDITOR, core.editor, and stuff'
4
5 +TEST_PASSES_SANITIZE_LEAK=true
6 . ./test-lib.sh
7
8 unset EDITOR VISUAL GIT_EDITOR
t/t7102-reset.sh
+1
@@ -10,6 +10,7 @@ Documented tests for git reset'
10 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
11 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
12
13 +TEST_PASSES_SANITIZE_LEAK=true
14 . ./test-lib.sh
15
16 commit_msg () {
t/t9129-git-svn-i18n-commitencoding.sh
-1
@@ -4,7 +4,6 @@
4
5 test_description='git svn honors i18n.commitEncoding in config'
6
7 -TEST_FAILS_SANITIZE_LEAK=true
7 . ./lib-git-svn.sh
8
9 compare_git_head_with () {
t/t9139-git-svn-non-utf8-commitencoding.sh
-1
@@ -4,7 +4,6 @@
4
5 test_description='git svn refuses to dcommit non-UTF8 messages'
6
7 -TEST_FAILS_SANITIZE_LEAK=true
7 . ./lib-git-svn.sh
8
9 # ISO-2022-JP can pass for valid UTF-8, so skipping that in this test