From 4a792c87b9a643a949ee36106a2f7e971dc633f8 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 6 Jun 2019 12:22:41 +0200 Subject: [PATCH] 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) --- src/os_mswin.c | 39 ++++++++++++++++++++++++++++++++++ src/testdir/test_functions.vim | 4 ++++ src/version.c | 2 ++ 3 files changed, 45 insertions(+) diff --git a/src/os_mswin.c b/src/os_mswin.c index 2b878f77c..ced065b0d 100644 --- a/src/os_mswin.c +++ b/src/os_mswin.c @@ -1753,6 +1753,39 @@ typedef BOOL (WINAPI *pfnGetVolumeInformationByHandleW)( 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 @@ resolve_reparse_point(char_u *fname) 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 cc1ee8b61..a2e4da6c7 100644 --- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -276,6 +276,7 @@ func Test_resolve_win32() " 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 @@ func Test_resolve_win32() " 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 ca2e17498..cd138ab9c 100644 --- a/src/version.c +++ b/src/version.c @@ -767,6 +767,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1473, /**/ 1472, /**/ -- 2.40.0