commit 091a130804282c9d40e639d68659d2ea2941259d
parent 50feb85b0c1e29583c6f6f928512e7b853a3ebf6
Author: zeertzjq <zeertzjq@outlook.com>
Date: Fri, 12 Jul 2024 06:39:17 +0800
vim-patch:9.1.0566: Stop dir in findfile() doesn't work properly w/o trailing slash
Problem: Stop directory in findfile() doesn't work properly without a
trailing slash.
Solution: Always use fnamencmp(), not fnamecmp().
related: vim/vim#15200
related: vim/vim#15202
https://github.com/vim/vim/commit/e6ab23bd4a41840860ae2904956c4d255a9dd528
Diffstat:
2 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c
@@ -892,11 +892,12 @@ char *vim_findfile(void *search_ctx_arg)
if (search_ctx->ffsc_start_dir
&& search_ctx->ffsc_stopdirs_v != NULL && !got_int) {
ff_stack_T *sptr;
+ // path_end may point to the NUL or the previous path separator
+ ptrdiff_t plen = (path_end - search_ctx->ffsc_start_dir) + (*path_end != NUL);
// is the last starting directory in the stop list?
if (ff_path_in_stoplist(search_ctx->ffsc_start_dir,
- (int)(path_end - search_ctx->ffsc_start_dir),
- search_ctx->ffsc_stopdirs_v)) {
+ (size_t)plen, search_ctx->ffsc_stopdirs_v)) {
break;
}
@@ -1231,7 +1232,7 @@ static void ff_clear(ff_search_ctx_T *search_ctx)
/// check if the given path is in the stopdirs
///
/// @return true if yes else false
-static bool ff_path_in_stoplist(char *path, int path_len, char **stopdirs_v)
+static bool ff_path_in_stoplist(char *path, size_t path_len, char **stopdirs_v)
{
// eat up trailing path separators, except the first
while (path_len > 1 && vim_ispathsep(path[path_len - 1])) {
@@ -1244,20 +1245,16 @@ static bool ff_path_in_stoplist(char *path, int path_len, char **stopdirs_v)
}
for (int i = 0; stopdirs_v[i] != NULL; i++) {
- if ((int)strlen(stopdirs_v[i]) > path_len) {
- // match for parent directory. So '/home' also matches
- // '/home/rks'. Check for PATHSEP in stopdirs_v[i], else
- // '/home/r' would also match '/home/rks'
- if (path_fnamencmp(stopdirs_v[i], path, (size_t)path_len) == 0
- && vim_ispathsep(stopdirs_v[i][path_len])) {
- return true;
- }
- } else {
- if (path_fnamecmp(stopdirs_v[i], path) == 0) {
- return true;
- }
+ // match for parent directory. So '/home' also matches
+ // '/home/rks'. Check for PATHSEP in stopdirs_v[i], else
+ // '/home/r' would also match '/home/rks'
+ if (path_fnamencmp(stopdirs_v[i], path, path_len) == 0
+ && (strlen(stopdirs_v[i]) <= path_len
+ || vim_ispathsep(stopdirs_v[i][path_len]))) {
+ return true;
}
}
+
return false;
}
diff --git a/test/old/testdir/test_findfile.vim b/test/old/testdir/test_findfile.vim
@@ -101,11 +101,18 @@ func Test_findfile()
let l = findfile('bar', ';' . save_dir . '/Xfinddir1/Xdir2/', -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)
+ call assert_equal(1, len(l))
+ call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
let l = findfile('bar', ';' . save_dir . '/Xfinddir1/', -1)
call assert_equal(2, len(l))
call assert_match('.*/Xfinddir1/Xdir2/Xdir3/bar', l[0])
call assert_match('.*/Xfinddir1/bar', l[1])
+ let l = findfile('bar', ';' . save_dir . '/Xfinddir1', -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/.
cd ../..