summaryrefslogtreecommitdiff
path: root/src/fileops.c
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2019-06-21 08:13:31 +0200
committerPatrick Steinhardt <ps@pks.im>2019-07-11 22:34:34 +0200
commit5ae22a6373d7a135accf550d12150e2b9bfa8739 (patch)
tree036e7f18a6b7155fc942b519ff0910c7a68b46ae /src/fileops.c
parenta6ad9e8a4edc75a3bcf404be636329082f80d1bb (diff)
downloadlibgit2-5ae22a6373d7a135accf550d12150e2b9bfa8739.tar.gz
fileops: fix creation of directory in filesystem root
In commit 45f24e787 (git_repository_init: stop traversing at windows root, 2019-04-12), we have fixed `git_futils_mkdir` to correctly handle the case where we create a directory in Windows-style filesystem roots like "C:\repo". The problem here is an off-by-one: previously, to that commit, we've been checking wether the parent directory's length is equal to the root directory's length incremented by one. When we call the function with "/example", then the parent directory's length ("/") is 1, but the root directory offset is 0 as the path is directly rooted without a drive prefix. This resulted in `1 == 0 + 1`, which was true. With the change, we've stopped incrementing the root directory length, and thus now compare `1 <= 0`, which is false. The previous way of doing it was kind of finicky any non-obvious, which is also why the error was introduced. So instead of just re-adding the increment, let's explicitly add a condition that aborts finding the parent if the current parent path is "/". Making this change causes Azure Pipelines to fail the testcase repo::init::nonexistent_paths on Unix-based systems. This is because we have just fixed creating directories in the filesystem root, which previously didn't work. As Docker-based tests are running as root user, we are thus able to create the non-existing path and will now succeed to create the repository that was expected to actually fail. Let's split this up into three different tests: - A test to verify that we do not create repos in a non-existing parent directoy if the flag `GIT_REPOSITORY_INIT_MKPATH` is not set. - A test to verify that we fail if the root directory does not exist. As there is a common root directory on Unix-based systems that always exist, we can only test for this on Windows-based systems. - A test to verify that we fail if trying to create a repository in an unwriteable parent directory. We can only test this if not running tests as root user, as CAP_DAC_OVERRIDE will cause us to ignore permissions when creating files.
Diffstat (limited to 'src/fileops.c')
-rw-r--r--src/fileops.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/src/fileops.c b/src/fileops.c
index 0b732aabe..648ffbe5d 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -495,7 +495,9 @@ int git_futils_mkdir(
* equal to length of the root path). The path may be less than the
* root path length on Windows, where `C:` == `C:/`.
*/
- if ((len == 1 && parent_path.ptr[0] == '.') || len <= root_len) {
+ if ((len == 1 && parent_path.ptr[0] == '.') ||
+ (len == 1 && parent_path.ptr[0] == '/') ||
+ len <= root_len) {
relative = make_path.ptr;
break;
}