summaryrefslogtreecommitdiffstats
path: root/src/os_mswin.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-06-06 12:22:41 +0200
committerBram Moolenaar <Bram@vim.org>2019-06-06 12:22:41 +0200
commit4a792c87b9a643a949ee36106a2f7e971dc633f8 (patch)
tree4e7340e34cf10c2f17b1d80176211cf91a5b5bca /src/os_mswin.c
parent61da1bfa6c6b19dd670671a318ce9f9e2acc784c (diff)
patch 8.1.1473: new resolve() implementation causes problem for pluginsv8.1.1473
Problem: New resolve() implementation causes problem for plugins. Solution: Only resolve a resparse point after checking it is needed. (Ken Takata, closes #4492)
Diffstat (limited to 'src/os_mswin.c')
-rw-r--r--src/os_mswin.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/os_mswin.c b/src/os_mswin.c
index 2b878f77cf..ced065b0d3 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);