diff options
author | erw7 <erw7.github@gmail.com> | 2020-03-27 16:07:39 +0900 |
---|---|---|
committer | erw7 <erw7.github@gmail.com> | 2020-04-02 21:13:18 +0900 |
commit | b687a6c2b2c096a68b46141947aef29c616f7a1f (patch) | |
tree | e8427fb1521b4fd03a246a6e5e6be48801cc7610 /src | |
parent | f61331e184d8db6d8dc965856eba1db321a2d8f3 (diff) | |
download | rneovim-b687a6c2b2c096a68b46141947aef29c616f7a1f.tar.gz rneovim-b687a6c2b2c096a68b46141947aef29c616f7a1f.tar.bz2 rneovim-b687a6c2b2c096a68b46141947aef29c616f7a1f.zip |
Change to canonicalize only when reparse point in included
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/eval/funcs.c | 4 | ||||
-rw-r--r-- | src/nvim/os/fs.c | 45 |
2 files changed, 48 insertions, 1 deletions
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index b4a3e29156..68eca56235 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -6711,7 +6711,9 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr) #ifdef WIN32 char *v = os_resolve_shortcut(fname); if (v == NULL) { - v = os_realpath(fname, v); + if (os_is_reparse_point_include(fname)) { + v = os_realpath(fname, v); + } } rettv->vval.v_string = (char_u *)(v == NULL ? xstrdup(fname) : v); #else diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index e06762383f..873b611151 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -1257,4 +1257,49 @@ shortcut_end: return rfname; } +#define is_path_sep(c) ((c) == L'\\' || (c) == L'/') +/// Returns true if the path contains a reparse point (junction or symbolic +/// link). Otherwise false in returned. +bool os_is_reparse_point_include(const char *path) +{ + wchar_t *p, *q, *utf16_path; + wchar_t buf[MAX_PATH]; + DWORD attr; + bool result = false; + + const int r = utf8_to_utf16(path, -1, &utf16_path); + if (r != 0) { + EMSG2("utf8_to_utf16 failed: %d", r); + return false; + } + + p = utf16_path; + 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 = utf16_path + wcslen(utf16_path); + } else { + p = q + 1; + } + if (q - utf16_path >= MAX_PATH) { + break; + } + wcsncpy(buf, utf16_path, (size_t)(q - utf16_path)); + buf[q - utf16_path] = L'\0'; + attr = GetFileAttributesW(buf); + if (attr != INVALID_FILE_ATTRIBUTES + && (attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { + result = true; + break; + } + } + xfree(utf16_path); + return result; +} #endif |