aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/os/fs.c
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-05-17 18:39:01 +0800
committerGitHub <noreply@github.com>2024-05-17 18:39:01 +0800
commit42aa69b076cb338e20b5b4656771f1873e8930d8 (patch)
treecc1b82eb2e91c93c78af88a9feb62889833848b8 /src/nvim/os/fs.c
parent10f917351906ca2d3c61a6b9bd8b8ae88a26ed8f (diff)
downloadrneovim-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/os/fs.c')
-rw-r--r--src/nvim/os/fs.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index 2eca906d4e..19bdf30311 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -1320,22 +1320,22 @@ bool os_fileid_equal_fileinfo(const FileID *file_id, const FileInfo *file_info)
/// Return the canonicalized absolute pathname.
///
/// @param[in] name Filename to be canonicalized.
-/// @param[out] buf Buffer to store the canonicalized values. A minimum length
-// of MAXPATHL+1 is required. If it is NULL, memory is
-// allocated. In that case, the caller should deallocate this
-// buffer.
+/// @param[out] buf Buffer to store the canonicalized values.
+/// If it is NULL, memory is allocated. In that case, the caller
+/// should deallocate this buffer.
+/// @param[in] len The length of the buffer.
///
/// @return pointer to the buf on success, or NULL.
-char *os_realpath(const char *name, char *buf)
+char *os_realpath(const char *name, char *buf, size_t len)
FUNC_ATTR_NONNULL_ARG(1)
{
uv_fs_t request;
int result = uv_fs_realpath(NULL, &request, name, NULL);
if (result == kLibuvSuccess) {
if (buf == NULL) {
- buf = xmallocz(MAXPATHL);
+ buf = xmalloc(len);
}
- xstrlcpy(buf, request.ptr, MAXPATHL + 1);
+ xstrlcpy(buf, request.ptr, len);
}
uv_fs_req_cleanup(&request);
return result == kLibuvSuccess ? buf : NULL;