diff options
| author | Patrick Steinhardt <ps@pks.im> | 2019-06-21 08:13:31 +0200 |
|---|---|---|
| committer | Patrick Steinhardt <ps@pks.im> | 2019-07-11 22:34:34 +0200 |
| commit | 5ae22a6373d7a135accf550d12150e2b9bfa8739 (patch) | |
| tree | 036e7f18a6b7155fc942b519ff0910c7a68b46ae /src/fileops.c | |
| parent | a6ad9e8a4edc75a3bcf404be636329082f80d1bb (diff) | |
| download | libgit2-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.c | 4 |
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; } |
