summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2019-04-12 08:54:06 +0100
committerPatrick Steinhardt <ps@pks.im>2019-05-02 10:22:13 +0200
commit9b6989789de603fa25a752def6f984cea4958944 (patch)
treef7d006f486e07780a67cc25b89ee6e38cadfd1f9
parent21baf7abe7c41f9a96c9dad7a226b2d0877d309d (diff)
downloadlibgit2-9b6989789de603fa25a752def6f984cea4958944.tar.gz
git_repository_init: stop traversing at windows root
Stop traversing the filesystem at the Windows directory root. We were calculating the filesystem root for the given directory to create, and walking up the filesystem hierarchy. We intended to stop when the traversal path length is equal to the root path length (ie, stopping at the root, since no path may be shorter than the root path). However, on Windows, the root path may be specified in two different ways, as either `Z:` or `Z:\`, where `Z:` is the current drive letter. `git_path_dirname_r` returns the path _without_ a trailing slash, even for the Windows root. As a result, during traversal, we need to test that the traversal path is _less than or equal to_ the root path length to determine if we've hit the root to ensure that we stop when our traversal path is `Z:` and our calculated root path was `Z:\`.
-rw-r--r--src/fileops.c9
-rw-r--r--tests/repo/init.c12
2 files changed, 18 insertions, 3 deletions
diff --git a/src/fileops.c b/src/fileops.c
index 988ea0f08..877e9cdc5 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -489,10 +489,13 @@ int git_futils_mkdir(
assert(len);
- /* we've walked all the given path's parents and it's either relative
- * or rooted. either way, give up and make the entire path.
+ /*
+ * We've walked all the given path's parents and it's either relative
+ * (the parent is simply '.') or rooted (the length is less than or
+ * 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+1) {
+ if ((len == 1 && parent_path.ptr[0] == '.') || len <= root_len) {
relative = make_path.ptr;
break;
}
diff --git a/tests/repo/init.c b/tests/repo/init.c
index 91b25a5f1..6e6e65297 100644
--- a/tests/repo/init.c
+++ b/tests/repo/init.c
@@ -877,3 +877,15 @@ void test_repo_init__at_filesystem_root(void)
git_buf_dispose(&root);
git_repository_free(repo);
}
+
+void test_repo_init__nonexistent_paths(void)
+{
+ git_repository *repo;
+
+#ifdef GIT_WIN32
+ cl_git_fail(git_repository_init(&repo, "Q:/non/existent/path", 0));
+ cl_git_fail(git_repository_init(&repo, "Q:\\non\\existent\\path", 0));
+#else
+ cl_git_fail(git_repository_init(&repo, "/non/existent/path", 0));
+#endif
+}