mirror of
https://github.com/neovim/neovim.git
synced 2026-11-06 05:16:52 +00:00
fix(path): path_shorten_fname() treats "c:x" as a root #42657
Problem:
On Windows, path_shorten_fname() treats "c:x" as a root ("c:\"), so it
shortens "c:xyz\foo" to "yz\foo".
Solution:
Only "c:\" (drive and separator) is a root, not "c:x". Also simplify
path_to_absolute().
This commit is contained in:
1 parent
54eac81f8f
commit
9213ffc7da
3 files changed
+28
-36
No files matched your search
+18
-18
@@ -2035,7 +2035,7 @@ char *path_shorten_fname(char *full_path, char *dir_name)
|
||||
}
|
||||
|
||||
// If dir_name is a path head, full_path can always be made relative.
|
||||
if (len == (size_t)path_head_length() && is_path_head(dir_name)) {
|
||||
if (len == (size_t)path_head_length() && get_past_head(dir_name) == dir_name + len) {
|
||||
return full_path + len;
|
||||
}
|
||||
|
||||
@@ -2288,28 +2288,28 @@ int append_path(char *path, const char *to_append, size_t max_len)
|
||||
static int path_to_absolute(const char *fname, char *buf, size_t len, int force)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
const char *p = fname;
|
||||
*buf = NUL;
|
||||
|
||||
// expand it if forced or not an absolute path
|
||||
if (force || !path_is_absolute(p)
|
||||
#ifdef MSWIN // enforce drive letter on Windows paths
|
||||
|| vim_ispathsep_nocolon(p[0])
|
||||
if (!force && path_is_absolute(fname)
|
||||
#ifdef MSWIN // Enforce drive letter on Windows paths.
|
||||
&& !vim_ispathsep_nocolon(fname[0])
|
||||
#endif
|
||||
) {
|
||||
p = path_tail(p);
|
||||
if (strcmp(p, "..") == 0) {
|
||||
p += 2;
|
||||
}
|
||||
|
||||
char *relative_directory = xmemdupz(fname, (size_t)(p - fname));
|
||||
int ret = path_full_dir_name(relative_directory, buf, len);
|
||||
xfree(relative_directory);
|
||||
if (ret == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
return append_path(buf, fname, len);
|
||||
}
|
||||
return append_path(buf, p, len);
|
||||
|
||||
const char *tail = path_tail(fname);
|
||||
// "dir/.." => realpath("dir/.."), because append_path() doesn't resolve "..".
|
||||
if (strcmp(tail, "..") == 0) {
|
||||
tail += 2;
|
||||
}
|
||||
char *dir = xmemdupz(fname, (size_t)(tail - fname));
|
||||
int ret = path_full_dir_name(dir, buf, len);
|
||||
xfree(dir);
|
||||
if (ret == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
return append_path(buf, tail, len);
|
||||
}
|
||||
|
||||
/// Check if file `fname` is a full (absolute) path.
|
||||
|
||||
@@ -390,6 +390,7 @@ describe('vim._watch', function()
|
||||
end)
|
||||
|
||||
it('watch() reports an error once when the parent directory is deleted #41851', function()
|
||||
skip(is_os('mac'), 'flaky test on mac')
|
||||
local root_dir = t.tmpname(false)
|
||||
t.finally(function()
|
||||
n.rmdir(root_dir)
|
||||
|
||||
+9
-18
@@ -513,7 +513,7 @@ describe('path.c', function()
|
||||
eq(OK, result)
|
||||
end)
|
||||
|
||||
itp('produces absolute path for .. without a slash', function()
|
||||
itp('produces absolute path for .. without a slash, and dir/..', function()
|
||||
local old_dir = uv.cwd()
|
||||
uv.chdir('..')
|
||||
local expected = uv.cwd()
|
||||
@@ -524,15 +524,10 @@ describe('path.c', function()
|
||||
local buf, result = vim_FullName(filename, buflen, do_expand)
|
||||
eq(expected, ffi.string(buf))
|
||||
eq(OK, result)
|
||||
end)
|
||||
|
||||
itp('produces absolute path for "dir/.."', function()
|
||||
local expected = uv.cwd()
|
||||
local filename = 'unit-test-directory/..'
|
||||
local buflen = get_buf_len(expected, filename)
|
||||
local do_expand = 1
|
||||
local buf, result = vim_FullName(filename, buflen, do_expand)
|
||||
eq(expected, ffi.string(buf))
|
||||
-- Also "dir/..".
|
||||
filename = 'unit-test-directory/..'
|
||||
buf, result = vim_FullName(filename, get_buf_len(old_dir, filename), do_expand)
|
||||
eq(old_dir, ffi.string(buf))
|
||||
eq(OK, result)
|
||||
end)
|
||||
|
||||
@@ -609,14 +604,10 @@ describe('path.c', function()
|
||||
local buf, result = vim_FullName(filename, buflen, do_expand)
|
||||
eq(expected, ffi.string(buf))
|
||||
eq(OK, result)
|
||||
end)
|
||||
|
||||
itp('removes trailing slash from an existing relative directory', function()
|
||||
local expected = uv.cwd() .. '/unit-test-directory'
|
||||
local filename = 'unit-test-directory/'
|
||||
local buflen = get_buf_len(expected, filename)
|
||||
local do_expand = 1
|
||||
local buf, result = vim_FullName(filename, buflen, do_expand)
|
||||
-- But removes it from an existing directory.
|
||||
expected = uv.cwd() .. '/unit-test-directory'
|
||||
filename = 'unit-test-directory/'
|
||||
buf, result = vim_FullName(filename, get_buf_len(expected, filename), do_expand)
|
||||
eq(expected, ffi.string(buf))
|
||||
eq(OK, result)
|
||||
end)
|
||||
|
||||
Reference in new issue
Block a user