stat: don't remove trailing '/' from root on win32 `p_stat` calls `git_win32_path_from_utf8`, which canonicalizes the path. Do not further try to modify the path, else we trim the trailing slash from a root directory and try to access `C:` instead of `C:/`.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index e446cca..346f537 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -448,12 +448,8 @@ int p_stat(const char* path, struct stat* buf)
git_win32_path path_w;
int len;
- if ((len = git_win32_path_from_utf8(path_w, path)) < 0)
- return -1;
-
- git_win32__path_trim_end(path_w, len);
-
- if (lstat_w(path_w, buf, false) < 0)
+ if ((len = git_win32_path_from_utf8(path_w, path)) < 0 ||
+ lstat_w(path_w, buf, false) < 0)
return -1;
/* The item is a symbolic link or mount point. No need to iterate
diff --git a/tests/core/stat.c b/tests/core/stat.c
index 2e4abfb..bd9b990 100644
--- a/tests/core/stat.c
+++ b/tests/core/stat.c
@@ -95,3 +95,20 @@ void test_core_stat__0(void)
cl_assert_error(ENOTDIR);
}
+void test_core_stat__root(void)
+{
+ const char *sandbox = clar_sandbox_path();
+ git_buf root = GIT_BUF_INIT;
+ int root_len;
+ struct stat st;
+
+ root_len = git_path_root(sandbox);
+ cl_assert(root_len >= 0);
+
+ git_buf_set(&root, sandbox, root_len+1);
+
+ cl_must_pass(p_stat(root.ptr, &st));
+ cl_assert(S_ISDIR(st.st_mode));
+
+ git_buf_free(&root);
+}