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)
diff --git a/src/os_mswin.c b/src/os_mswin.c
index 2b878f7..ced065b 100644
--- a/src/os_mswin.c
+++ b/src/os_mswin.c
@@ -1753,6 +1753,39 @@
DWORD nFileSystemNameSize);
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 *
resolve_reparse_point(char_u *fname)
{
@@ -1787,6 +1820,12 @@
if (p == NULL)
goto fail;
+ if (!is_reparse_point_included(p))
+ {
+ vim_free(p);
+ goto fail;
+ }
+
h = CreateFileW(p, 0, 0, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL);
vim_free(p);
diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim
index cc1ee8b..a2e4da6 100644
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -276,6 +276,7 @@
" test for symbolic link to a file
new Xfile
wq
+ call assert_equal('Xfile', resolve('Xfile'))
silent !mklink Xlink Xfile
if !v:shell_error
call assert_equal(s:normalize_fname(getcwd() . '\Xfile'), s:normalize_fname(resolve('./Xlink')))
@@ -333,11 +334,14 @@
" test for reparse point
call mkdir('Xdir')
+ call assert_equal('Xdir', resolve('Xdir'))
silent !mklink /D Xdirlink Xdir
if !v:shell_error
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'), s:normalize_fname(resolve('Xdirlink')))
+ call delete('Xdirlink')
else
echomsg 'skipped test for reparse point'
endif
diff --git a/src/version.c b/src/version.c
index ca2e174..cd138ab 100644
--- a/src/version.c
+++ b/src/version.c
@@ -768,6 +768,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1473,
+/**/
1472,
/**/
1471,