fix(fs): expand drive-relative paths on Windows #37084

Problem:
On windows, if a drive-relative path doesn't contain a slash,
`path_to_absolute` can't split out the relative component, causing
expansion to fails. e.g., `c:` `c:.` `c:..` `c:foo.md`

Solution:
For these cases, we can pass letter and colon to `path_full_dir_name`.
Notably, `..` is included as well.
if that relative path exists, it can be expanded correctly.
This commit is contained in:
tao
2026-03-19 07:54:19 +08:00
committed by GitHub
parent f4f1149292
commit 19715e6e8a
2 changed files with 22 additions and 2 deletions

View File

@@ -2380,20 +2380,23 @@ static int path_to_absolute(const char *fname, char *buf, size_t len, int force)
if (p == NULL) {
p = strrchr(fname, '\\');
}
if (p == NULL && ASCII_ISALPHA(fname[0]) && fname[1] == ':') {
p = fname + 1;
}
#endif
if (p == NULL && strcmp(fname, "..") == 0) {
// Handle ".." without path separators.
p = fname + 2;
}
if (p != NULL) {
if (vim_ispathsep_nocolon(*p) && strcmp(p + 1, "..") == 0) {
if (vim_ispathsep(*p) && strcmp(p + 1, "..") == 0) {
// For "/path/dir/.." include the "/..".
p += 3;
}
assert(p >= fname);
memcpy(relative_directory, fname, (size_t)(p - fname + 1));
relative_directory[p - fname + 1] = NUL;
end_of_path = (vim_ispathsep_nocolon(*p) ? p + 1 : p);
end_of_path = (vim_ispathsep(*p) ? p + 1 : p);
} else {
relative_directory[0] = NUL;
}