neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit abd0c882b37acbd26ec6805f3a8b68c4335c0584
parent b1c41a332d183c4cb003329f7c2a3f310f48273c
Author: Vlad <52591095+MeanderingProgrammer@users.noreply.github.com>
Date:   Thu,  9 Oct 2025 18:04:02 -0700

fix(rpc): handle more cases when identifying loopback #36100

Problem:

On MacOS it is a relatively common pattern to set XDG_RUNTIME_DIR under
`/tmp` or `/var`. Both of these are symlinks to `/private/tmp` and
`/private/var`. When checking for loopback the input address is
normalized using `fix_fname`, however this is not applied to the
addresses of the sockets. As a result of one address being normalized
and the other not the comparison would fail.

Solution:

Normalize both sides of the comparison using `fix_fname`.
Diffstat:
Msrc/nvim/channel.c | 6+-----
Msrc/nvim/msgpack_rpc/server.c | 16+++++++++++-----
2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/src/nvim/channel.c b/src/nvim/channel.c @@ -41,7 +41,6 @@ #include "nvim/os/fs.h" #include "nvim/os/os_defs.h" #include "nvim/os/shell.h" -#include "nvim/path.h" #include "nvim/terminal.h" #include "nvim/types_defs.h" @@ -461,10 +460,7 @@ uint64_t channel_connect(bool tcp, const char *address, bool rpc, CallbackReader Channel *channel; if (!tcp && rpc) { - char *path = fix_fname(address); - bool loopback = server_owns_pipe_address(path); - xfree(path); - if (loopback) { + if (server_owns_pipe_address(address)) { // Create a loopback channel. This avoids deadlock if nvim connects to // its own named pipe. channel = channel_alloc(kChannelStreamInternal); diff --git a/src/nvim/msgpack_rpc/server.c b/src/nvim/msgpack_rpc/server.c @@ -19,6 +19,7 @@ #include "nvim/os/os.h" #include "nvim/os/os_defs.h" #include "nvim/os/stdpaths_defs.h" +#include "nvim/path.h" #include "nvim/types_defs.h" #define MAX_CONNECTIONS 32 @@ -135,15 +136,20 @@ char *server_address_new(const char *name) } /// Check if this instance owns a pipe address. -/// The argument must already be resolved to an absolute path! -bool server_owns_pipe_address(const char *path) +bool server_owns_pipe_address(const char *address) { + bool result = false; + char *path = fix_fname(address); for (int i = 0; i < watchers.ga_len; i++) { - if (!strcmp(path, ((SocketWatcher **)watchers.ga_data)[i]->addr)) { - return true; + char *addr = fix_fname(((SocketWatcher **)watchers.ga_data)[i]->addr); + result = strequal(path, addr); + xfree(addr); + if (result) { + break; } } - return false; + xfree(path); + return result; } /// Starts listening for RPC calls.