0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

patch 8.1.1473: new resolve() implementation causes problem for plugins

Problem:    New resolve() implementation causes problem for plugins.
Solution:   Only resolve a resparse point after checking it is needed. (Ken
            Takata, closes #4492)
This commit is contained in:
Bram Moolenaar
2019-06-06 12:22:41 +02:00
parent 61da1bfa6c
commit 4a792c87b9
3 changed files with 45 additions and 0 deletions

View File

@@ -1753,6 +1753,39 @@ typedef BOOL (WINAPI *pfnGetVolumeInformationByHandleW)(
DWORD nFileSystemNameSize); DWORD nFileSystemNameSize);
static pfnGetVolumeInformationByHandleW pGetVolumeInformationByHandleW = NULL; static pfnGetVolumeInformationByHandleW pGetVolumeInformationByHandleW = NULL;
# define is_path_sep(c) ((c) == L'\\' || (c) == L'/')
static int
is_reparse_point_included(LPCWSTR fname)
{
LPCWSTR p = fname, q;
WCHAR buf[MAX_PATH];
DWORD attr;
if (isalpha(p[0]) && p[1] == L':' && is_path_sep(p[2]))
p += 3;
else if (is_path_sep(p[0]) && is_path_sep(p[1]))
p += 2;
while (*p != L'\0')
{
q = wcspbrk(p, L"\\/");
if (q == NULL)
p = q = fname + wcslen(fname);
else
p = q + 1;
if (q - fname >= MAX_PATH)
return FALSE;
wcsncpy(buf, fname, q - fname);
buf[q - fname] = L'\0';
attr = GetFileAttributesW(buf);
if (attr != INVALID_FILE_ATTRIBUTES
&& (attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0)
return TRUE;
}
return FALSE;
}
static char_u * static char_u *
resolve_reparse_point(char_u *fname) resolve_reparse_point(char_u *fname)
{ {
@@ -1787,6 +1820,12 @@ resolve_reparse_point(char_u *fname)
if (p == NULL) if (p == NULL)
goto fail; goto fail;
if (!is_reparse_point_included(p))
{
vim_free(p);
goto fail;
}
h = CreateFileW(p, 0, 0, NULL, OPEN_EXISTING, h = CreateFileW(p, 0, 0, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL); FILE_FLAG_BACKUP_SEMANTICS, NULL);
vim_free(p); vim_free(p);

View File

@@ -276,6 +276,7 @@ func Test_resolve_win32()
" test for symbolic link to a file " test for symbolic link to a file
new Xfile new Xfile
wq wq
call assert_equal('Xfile', resolve('Xfile'))
silent !mklink Xlink Xfile silent !mklink Xlink Xfile
if !v:shell_error if !v:shell_error
call assert_equal(s:normalize_fname(getcwd() . '\Xfile'), s:normalize_fname(resolve('./Xlink'))) call assert_equal(s:normalize_fname(getcwd() . '\Xfile'), s:normalize_fname(resolve('./Xlink')))
@@ -333,11 +334,14 @@ func Test_resolve_win32()
" test for reparse point " test for reparse point
call mkdir('Xdir') call mkdir('Xdir')
call assert_equal('Xdir', resolve('Xdir'))
silent !mklink /D Xdirlink Xdir silent !mklink /D Xdirlink Xdir
if !v:shell_error if !v:shell_error
w Xdir/text.txt w Xdir/text.txt
call assert_equal('Xdir/text.txt', resolve('Xdir/text.txt'))
call assert_equal(s:normalize_fname(getcwd() . '\Xdir\text.txt'), s:normalize_fname(resolve('Xdirlink\text.txt'))) call assert_equal(s:normalize_fname(getcwd() . '\Xdir\text.txt'), s:normalize_fname(resolve('Xdirlink\text.txt')))
call assert_equal(s:normalize_fname(getcwd() . '\Xdir'), s:normalize_fname(resolve('Xdirlink'))) call assert_equal(s:normalize_fname(getcwd() . '\Xdir'), s:normalize_fname(resolve('Xdirlink')))
call delete('Xdirlink')
else else
echomsg 'skipped test for reparse point' echomsg 'skipped test for reparse point'
endif endif

View File

@@ -767,6 +767,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1473,
/**/ /**/
1472, 1472,
/**/ /**/