mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 03:18:16 +00:00
vim-patch:9.1.0569: fnamemodify() treats ".." and "../" differently (#29673)
Problem: fnamemodify() treats ".." and "../" differently. Solution: Expand ".." properly like how "/.." is treated in 8.2.3388. (zeertzjq) closes: vim/vim#152181ee7420460
(cherry picked from commit028dd3c5c4
)
This commit is contained in:

committed by
github-actions[bot]
![github-actions[bot]](/assets/img/avatar_default.png)
parent
bddbbd874c
commit
ceb82a9396
@@ -2384,9 +2384,13 @@ static int path_to_absolute(const char *fname, char *buf, size_t len, int force)
|
|||||||
p = strrchr(fname, '\\');
|
p = strrchr(fname, '\\');
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (p == NULL && strcmp(fname, "..") == 0) {
|
||||||
|
// Handle ".." without path separators.
|
||||||
|
p = fname + 2;
|
||||||
|
}
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
if (strcmp(p + 1, "..") == 0) {
|
if (vim_ispathsep_nocolon(*p) && strcmp(p + 1, "..") == 0) {
|
||||||
// for "/path/dir/.." include the "/.."
|
// For "/path/dir/.." include the "/..".
|
||||||
p += 3;
|
p += 3;
|
||||||
}
|
}
|
||||||
assert(p >= fname);
|
assert(p >= fname);
|
||||||
|
@@ -107,6 +107,9 @@ func Test_findfile()
|
|||||||
let l = findfile('bar', ';../', -1)
|
let l = findfile('bar', ';../', -1)
|
||||||
call assert_equal(1, len(l))
|
call assert_equal(1, len(l))
|
||||||
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
|
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
|
||||||
|
let l = findfile('bar', ';..', -1)
|
||||||
|
call assert_equal(1, len(l))
|
||||||
|
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
|
||||||
|
|
||||||
let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2/', -1)
|
let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2/', -1)
|
||||||
call assert_equal(1, len(l))
|
call assert_equal(1, len(l))
|
||||||
@@ -117,6 +120,9 @@ func Test_findfile()
|
|||||||
let l = findfile('bar', ';../../', -1)
|
let l = findfile('bar', ';../../', -1)
|
||||||
call assert_equal(1, len(l))
|
call assert_equal(1, len(l))
|
||||||
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
|
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
|
||||||
|
let l = findfile('bar', ';../..', -1)
|
||||||
|
call assert_equal(1, len(l))
|
||||||
|
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
|
||||||
|
|
||||||
let l = findfile('bar', ';' . save_dir . '/Xfinddir1/', -1)
|
let l = findfile('bar', ';' . save_dir . '/Xfinddir1/', -1)
|
||||||
call assert_equal(2, len(l))
|
call assert_equal(2, len(l))
|
||||||
@@ -130,6 +136,10 @@ func Test_findfile()
|
|||||||
call assert_equal(2, len(l))
|
call assert_equal(2, len(l))
|
||||||
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
|
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
|
||||||
call assert_match('.*/Xfinddir1/bar', l[1])
|
call assert_match('.*/Xfinddir1/bar', l[1])
|
||||||
|
let l = findfile('bar', ';../../..', -1)
|
||||||
|
call assert_equal(2, len(l))
|
||||||
|
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
|
||||||
|
call assert_match('.*/Xfinddir1/bar', l[1])
|
||||||
|
|
||||||
" Test combined downwards and upwards search from Xdir2/.
|
" Test combined downwards and upwards search from Xdir2/.
|
||||||
cd ../..
|
cd ../..
|
||||||
|
@@ -14,6 +14,8 @@ func Test_fnamemodify()
|
|||||||
call assert_equal($HOME .. "/foo" , fnamemodify('~/foo', ':p'))
|
call assert_equal($HOME .. "/foo" , fnamemodify('~/foo', ':p'))
|
||||||
call assert_equal(fnamemodify('.', ':p:h:h:h') .. '/', fnamemodify($HOME .. '/../', ':p'))
|
call assert_equal(fnamemodify('.', ':p:h:h:h') .. '/', fnamemodify($HOME .. '/../', ':p'))
|
||||||
call assert_equal(fnamemodify('.', ':p:h:h:h') .. '/', fnamemodify($HOME .. '/..', ':p'))
|
call assert_equal(fnamemodify('.', ':p:h:h:h') .. '/', fnamemodify($HOME .. '/..', ':p'))
|
||||||
|
call assert_equal(fnamemodify('.', ':p:h:h') .. '/', fnamemodify('../', ':p'))
|
||||||
|
call assert_equal(fnamemodify('.', ':p:h:h') .. '/', fnamemodify('..', ':p'))
|
||||||
call assert_equal('test.out', fnamemodify('test.out', ':.'))
|
call assert_equal('test.out', fnamemodify('test.out', ':.'))
|
||||||
call assert_equal('a', fnamemodify('../testdir/a', ':.'))
|
call assert_equal('a', fnamemodify('../testdir/a', ':.'))
|
||||||
call assert_equal('~/testdir/test.out', fnamemodify('test.out', ':~'))
|
call assert_equal('~/testdir/test.out', fnamemodify('test.out', ':~'))
|
||||||
|
@@ -143,15 +143,15 @@ func Test_tagfiles_stopdir()
|
|||||||
call writefile([], 'Xtagsdir1/Xtags', 'D')
|
call writefile([], 'Xtagsdir1/Xtags', 'D')
|
||||||
|
|
||||||
cd Xtagsdir1/
|
cd Xtagsdir1/
|
||||||
let &tags = './Xtags;' .. fnamemodify('./..', ':p')
|
let &tags = './Xtags;' .. fnamemodify('..', ':p')
|
||||||
call assert_equal(1, len(tagfiles()))
|
call assert_equal(1, len(tagfiles()))
|
||||||
|
|
||||||
cd Xtagsdir2/
|
cd Xtagsdir2/
|
||||||
let &tags = './Xtags;' .. fnamemodify('./..', ':p')
|
let &tags = './Xtags;' .. fnamemodify('..', ':p')
|
||||||
call assert_equal(1, len(tagfiles()))
|
call assert_equal(1, len(tagfiles()))
|
||||||
|
|
||||||
cd Xtagsdir3/
|
cd Xtagsdir3/
|
||||||
let &tags = './Xtags;' .. fnamemodify('./..', ':p')
|
let &tags = './Xtags;' .. fnamemodify('..', ':p')
|
||||||
call assert_equal(0, len(tagfiles()))
|
call assert_equal(0, len(tagfiles()))
|
||||||
|
|
||||||
let &tags = './Xtags;../'
|
let &tags = './Xtags;../'
|
||||||
@@ -163,6 +163,15 @@ func Test_tagfiles_stopdir()
|
|||||||
cd ..
|
cd ..
|
||||||
call assert_equal(1, len(tagfiles()))
|
call assert_equal(1, len(tagfiles()))
|
||||||
|
|
||||||
|
let &tags = './Xtags;..'
|
||||||
|
call assert_equal(1, len(tagfiles()))
|
||||||
|
|
||||||
|
cd Xtagsdir2/
|
||||||
|
call assert_equal(1, len(tagfiles()))
|
||||||
|
|
||||||
|
cd Xtagsdir3/
|
||||||
|
call assert_equal(0, len(tagfiles()))
|
||||||
|
|
||||||
set tags&
|
set tags&
|
||||||
call chdir(save_cwd)
|
call chdir(save_cwd)
|
||||||
endfunc
|
endfunc
|
||||||
|
@@ -468,8 +468,11 @@ describe('path.c', function()
|
|||||||
eq(OK, result)
|
eq(OK, result)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
itp('concatenates directory name if it does not contain a slash', function()
|
itp('produces absolute path for .. without a slash', function()
|
||||||
local expected = uv.cwd() .. '/..'
|
local old_dir = uv.cwd()
|
||||||
|
uv.chdir('..')
|
||||||
|
local expected = uv.cwd()
|
||||||
|
uv.chdir(old_dir)
|
||||||
local filename = '..'
|
local filename = '..'
|
||||||
local buflen = get_buf_len(expected, filename)
|
local buflen = get_buf_len(expected, filename)
|
||||||
local do_expand = 1
|
local do_expand = 1
|
||||||
@@ -478,21 +481,18 @@ describe('path.c', function()
|
|||||||
eq(OK, result)
|
eq(OK, result)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
itp(
|
itp('produces absolute path if possible and if path contains a slash', function()
|
||||||
'enters given directory (instead of just concatenating the strings) if possible and if path contains a slash',
|
local old_dir = uv.cwd()
|
||||||
function()
|
uv.chdir('..')
|
||||||
local old_dir = uv.cwd()
|
local expected = uv.cwd() .. '/test.file'
|
||||||
uv.chdir('..')
|
uv.chdir(old_dir)
|
||||||
local expected = uv.cwd() .. '/test.file'
|
local filename = '../test.file'
|
||||||
uv.chdir(old_dir)
|
local buflen = get_buf_len(expected, filename)
|
||||||
local filename = '../test.file'
|
local do_expand = 1
|
||||||
local buflen = get_buf_len(expected, filename)
|
local buf, result = vim_FullName(filename, buflen, do_expand)
|
||||||
local do_expand = 1
|
eq(expected, ffi.string(buf))
|
||||||
local buf, result = vim_FullName(filename, buflen, do_expand)
|
eq(OK, result)
|
||||||
eq(expected, ffi.string(buf))
|
end)
|
||||||
eq(OK, result)
|
|
||||||
end
|
|
||||||
)
|
|
||||||
|
|
||||||
itp('just copies the path if it is already absolute and force=0', function()
|
itp('just copies the path if it is already absolute and force=0', function()
|
||||||
local absolute_path = '/absolute/path'
|
local absolute_path = '/absolute/path'
|
||||||
|
Reference in New Issue
Block a user