diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-05-17 18:39:01 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-17 18:39:01 +0800 |
commit | 42aa69b076cb338e20b5b4656771f1873e8930d8 (patch) | |
tree | cc1b82eb2e91c93c78af88a9feb62889833848b8 /src/nvim/eval/funcs.c | |
parent | 10f917351906ca2d3c61a6b9bd8b8ae88a26ed8f (diff) | |
download | rneovim-42aa69b076cb338e20b5b4656771f1873e8930d8.tar.gz rneovim-42aa69b076cb338e20b5b4656771f1873e8930d8.tar.bz2 rneovim-42aa69b076cb338e20b5b4656771f1873e8930d8.zip |
fix(path): avoid chdir() when resolving path (#28799)
Use uv_fs_realpath() instead.
It seems that uv_fs_realpath() has some problems on non-Linux platforms:
- macOS and other BSDs: this function will fail with UV_ELOOP if more
than 32 symlinks are found while resolving the given path. This limit
is hardcoded and cannot be sidestepped.
- Windows: while this function works in the common case, there are a
number of corner cases where it doesn't:
- Paths in ramdisk volumes created by tools which sidestep the Volume
Manager (such as ImDisk) cannot be resolved.
- Inconsistent casing when using drive letters.
- Resolved path bypasses subst'd drives.
Ref: https://docs.libuv.org/en/v1.x/fs.html#c.uv_fs_realpath
I don't know if the old implementation that uses uv_chdir() and uv_cwd()
also suffers from the same problems.
- For the ELOOP case, chdir() seems to have the same limitations.
- On Windows, Vim doesn't use anything like chdir() either. It uses
_wfullpath(), while libuv uses GetFinalPathNameByHandleW().
Diffstat (limited to 'src/nvim/eval/funcs.c')
-rw-r--r-- | src/nvim/eval/funcs.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index b1ee33929c..1fc80e88c4 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -6479,7 +6479,7 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) char *v = os_resolve_shortcut(fname); if (v == NULL) { if (os_is_reparse_point_include(fname)) { - v = os_realpath(fname, v); + v = os_realpath(fname, NULL, MAXPATHL + 1); } } rettv->vval.v_string = (v == NULL ? xstrdup(fname) : v); @@ -6631,7 +6631,7 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) xfree(buf); } # else - char *v = os_realpath(fname, NULL); + char *v = os_realpath(fname, NULL, MAXPATHL + 1); rettv->vval.v_string = v == NULL ? xstrdup(fname) : v; # endif #endif |