Skip to content

Commit 43cbe6b

Browse files
committed
config: fix adding files if their parent directory is a file
When we try to add a configuration file with `git_config_add_file_ondisk`, we treat nonexisting files as empty. We do this by performing a stat call, ignoring ENOENT errors. This works just fine in case the file or any of its parents simply does not exist, but there is also the case where any of the parent directories is not a directory, but a file. So e.g. trying to add a configuration file "/dev/null/.gitconfig" will fail, as `errno` will be ENOTDIR instead of ENOENT. Catch ENOTDIR in addition to ENOENT to fix the issue. Add a test that verifies we are able to add configuration files with such an invalid path file just fine.
1 parent c3b427b commit 43cbe6b

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

src/config.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ int git_config_add_file_ondisk(
109109
assert(cfg && path);
110110

111111
res = p_stat(path, &st);
112-
if (res < 0 && errno != ENOENT) {
112+
if (res < 0 && errno != ENOENT && errno != ENOTDIR) {
113113
giterr_set(GITERR_CONFIG, "failed to stat '%s'", path);
114114
return -1;
115115
}

tests/config/read.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,26 @@ void test_config_read__fallback_from_local_to_global_and_from_global_to_system(v
534534
git_config_free(cfg);
535535
}
536536

537+
void test_config_read__parent_dir_is_file(void)
538+
{
539+
git_config *cfg;
540+
int count;
541+
542+
cl_git_pass(git_config_new(&cfg));
543+
/*
544+
* Verify we can add non-existing files when the parent directory is not
545+
* a directory.
546+
*/
547+
cl_git_pass(git_config_add_file_ondisk(cfg, "/dev/null/.gitconfig",
548+
GIT_CONFIG_LEVEL_SYSTEM, NULL, 0));
549+
550+
count = 0;
551+
cl_git_pass(git_config_foreach(cfg, count_cfg_entries_and_compare_levels, &count));
552+
cl_assert_equal_i(0, count);
553+
554+
git_config_free(cfg);
555+
}
556+
537557
/*
538558
* At the beginning of the test, config18 has:
539559
* int32global = 28

0 commit comments

Comments
 (0)