From 4338eea269157a260b53c06a560540174f06aa7f Mon Sep 17 00:00:00 2001 From: Vlad <52591095+MeanderingProgrammer@users.noreply.github.com> Date: Thu, 9 Oct 2025 18:04:02 -0700 Subject: [PATCH] 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`. (cherry picked from commit abd0c882b37acbd26ec6805f3a8b68c4335c0584) --- src/nvim/channel.c | 6 +----- src/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 index 899add944e..4b5b282063 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -39,7 +39,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 index b2c6d0d007..bd4dbf093b 100644 --- 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 @@ -137,15 +138,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.