unix,win: add UV_PIPE_NO_TRUNCATE flag (#4040)
Libuv's default behavior is to truncate long Unix socket paths. The flag tells it to return an error instead. Fixes: https://github.com/libuv/libuv/issues/4036
This commit is contained in:
parent
b9b6db052b
commit
2f1614b128
@ -68,15 +68,18 @@ API
|
|||||||
|
|
||||||
Bind the pipe to a file path (Unix) or a name (Windows).
|
Bind the pipe to a file path (Unix) or a name (Windows).
|
||||||
|
|
||||||
``flags`` must be zero. Returns ``UV_EINVAL`` for unsupported flags
|
``flags`` must be zero or ``UV_PIPE_NO_TRUNCATE``. Returns ``UV_EINVAL``
|
||||||
without performing the bind operation.
|
for unsupported flags without performing the bind operation.
|
||||||
|
|
||||||
Supports Linux abstract namespace sockets. ``namelen`` must include
|
Supports Linux abstract namespace sockets. ``namelen`` must include
|
||||||
the leading nul byte but not the trailing nul byte.
|
the leading nul byte but not the trailing nul byte.
|
||||||
|
|
||||||
|
.. versionadded:: 1.46.0
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes,
|
Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes,
|
||||||
typically between 92 and 108 bytes.
|
typically between 92 and 108 bytes, unless the ``UV_PIPE_NO_TRUNCATE``
|
||||||
|
flag is specified, in which case an ``UV_EINVAL`` error is returned.
|
||||||
|
|
||||||
.. c:function:: void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, const char* name, uv_connect_cb cb)
|
.. c:function:: void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, const char* name, uv_connect_cb cb)
|
||||||
|
|
||||||
@ -95,15 +98,18 @@ API
|
|||||||
|
|
||||||
Connect to the Unix domain socket or the Windows named pipe.
|
Connect to the Unix domain socket or the Windows named pipe.
|
||||||
|
|
||||||
``flags`` must be zero. Returns ``UV_EINVAL`` for unsupported flags
|
``flags`` must be zero or ``UV_PIPE_NO_TRUNCATE``. Returns ``UV_EINVAL``
|
||||||
without performing the connect operation.
|
for unsupported flags without performing the connect operation.
|
||||||
|
|
||||||
Supports Linux abstract namespace sockets. ``namelen`` must include
|
Supports Linux abstract namespace sockets. ``namelen`` must include
|
||||||
the leading nul byte but not the trailing nul byte.
|
the leading nul byte but not the trailing nul byte.
|
||||||
|
|
||||||
|
.. versionadded:: 1.46.0
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes,
|
Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes,
|
||||||
typically between 92 and 108 bytes.
|
typically between 92 and 108 bytes, unless the ``UV_PIPE_NO_TRUNCATE``
|
||||||
|
flag is specified, in which case an ``UV_EINVAL`` error is returned.
|
||||||
|
|
||||||
.. c:function:: int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size)
|
.. c:function:: int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size)
|
||||||
|
|
||||||
|
|||||||
@ -807,6 +807,10 @@ inline int uv_tty_set_mode(uv_tty_t* handle, int mode) {
|
|||||||
|
|
||||||
UV_EXTERN uv_handle_type uv_guess_handle(uv_file file);
|
UV_EXTERN uv_handle_type uv_guess_handle(uv_file file);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
UV_PIPE_NO_TRUNCATE = 1u << 0
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* uv_pipe_t is a subclass of uv_stream_t.
|
* uv_pipe_t is a subclass of uv_stream_t.
|
||||||
*
|
*
|
||||||
|
|||||||
@ -56,7 +56,7 @@ int uv_pipe_bind2(uv_pipe_t* handle,
|
|||||||
|
|
||||||
pipe_fname = NULL;
|
pipe_fname = NULL;
|
||||||
|
|
||||||
if (flags != 0)
|
if (flags & ~UV_PIPE_NO_TRUNCATE)
|
||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
|
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
@ -71,6 +71,10 @@ int uv_pipe_bind2(uv_pipe_t* handle,
|
|||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (flags & UV_PIPE_NO_TRUNCATE)
|
||||||
|
if (namelen > sizeof(saddr.sun_path))
|
||||||
|
return UV_EINVAL;
|
||||||
|
|
||||||
/* Truncate long paths. Documented behavior. */
|
/* Truncate long paths. Documented behavior. */
|
||||||
if (namelen > sizeof(saddr.sun_path))
|
if (namelen > sizeof(saddr.sun_path))
|
||||||
namelen = sizeof(saddr.sun_path);
|
namelen = sizeof(saddr.sun_path);
|
||||||
@ -221,7 +225,7 @@ int uv_pipe_connect2(uv_connect_t* req,
|
|||||||
int err;
|
int err;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (flags != 0)
|
if (flags & ~UV_PIPE_NO_TRUNCATE)
|
||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
|
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
@ -236,6 +240,10 @@ int uv_pipe_connect2(uv_connect_t* req,
|
|||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (flags & UV_PIPE_NO_TRUNCATE)
|
||||||
|
if (namelen > sizeof(saddr.sun_path))
|
||||||
|
return UV_EINVAL;
|
||||||
|
|
||||||
/* Truncate long paths. Documented behavior. */
|
/* Truncate long paths. Documented behavior. */
|
||||||
if (namelen > sizeof(saddr.sun_path))
|
if (namelen > sizeof(saddr.sun_path))
|
||||||
namelen = sizeof(saddr.sun_path);
|
namelen = sizeof(saddr.sun_path);
|
||||||
|
|||||||
@ -706,7 +706,7 @@ int uv_pipe_bind2(uv_pipe_t* handle,
|
|||||||
int i, err, nameSize;
|
int i, err, nameSize;
|
||||||
uv_pipe_accept_t* req;
|
uv_pipe_accept_t* req;
|
||||||
|
|
||||||
if (flags != 0) {
|
if (flags & ~UV_PIPE_NO_TRUNCATE) {
|
||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -722,6 +722,12 @@ int uv_pipe_bind2(uv_pipe_t* handle,
|
|||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags & UV_PIPE_NO_TRUNCATE) {
|
||||||
|
if (namelen > 256) {
|
||||||
|
return UV_EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (handle->flags & UV_HANDLE_BOUND) {
|
if (handle->flags & UV_HANDLE_BOUND) {
|
||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
}
|
}
|
||||||
@ -859,7 +865,7 @@ int uv_pipe_connect2(uv_connect_t* req,
|
|||||||
HANDLE pipeHandle = INVALID_HANDLE_VALUE;
|
HANDLE pipeHandle = INVALID_HANDLE_VALUE;
|
||||||
DWORD duplex_flags;
|
DWORD duplex_flags;
|
||||||
|
|
||||||
if (flags != 0) {
|
if (flags & ~UV_PIPE_NO_TRUNCATE) {
|
||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -875,6 +881,12 @@ int uv_pipe_connect2(uv_connect_t* req,
|
|||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags & UV_PIPE_NO_TRUNCATE) {
|
||||||
|
if (namelen > 256) {
|
||||||
|
return UV_EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UV_REQ_INIT(req, UV_CONNECT);
|
UV_REQ_INIT(req, UV_CONNECT);
|
||||||
req->handle = (uv_stream_t*) handle;
|
req->handle = (uv_stream_t*) handle;
|
||||||
req->cb = cb;
|
req->cb = cb;
|
||||||
|
|||||||
@ -198,6 +198,7 @@ TEST_DECLARE (pipe_connect_close_multiple)
|
|||||||
TEST_DECLARE (pipe_connect_multiple)
|
TEST_DECLARE (pipe_connect_multiple)
|
||||||
TEST_DECLARE (pipe_listen_without_bind)
|
TEST_DECLARE (pipe_listen_without_bind)
|
||||||
TEST_DECLARE (pipe_bind_or_listen_error_after_close)
|
TEST_DECLARE (pipe_bind_or_listen_error_after_close)
|
||||||
|
TEST_DECLARE (pipe_overlong_path)
|
||||||
TEST_DECLARE (pipe_connect_bad_name)
|
TEST_DECLARE (pipe_connect_bad_name)
|
||||||
TEST_DECLARE (pipe_connect_to_file)
|
TEST_DECLARE (pipe_connect_to_file)
|
||||||
TEST_DECLARE (pipe_connect_on_prepare)
|
TEST_DECLARE (pipe_connect_on_prepare)
|
||||||
@ -799,6 +800,7 @@ TASK_LIST_START
|
|||||||
TEST_ENTRY (pipe_connect_multiple)
|
TEST_ENTRY (pipe_connect_multiple)
|
||||||
TEST_ENTRY (pipe_listen_without_bind)
|
TEST_ENTRY (pipe_listen_without_bind)
|
||||||
TEST_ENTRY (pipe_bind_or_listen_error_after_close)
|
TEST_ENTRY (pipe_bind_or_listen_error_after_close)
|
||||||
|
TEST_ENTRY (pipe_overlong_path)
|
||||||
TEST_ENTRY (pipe_getsockname)
|
TEST_ENTRY (pipe_getsockname)
|
||||||
TEST_ENTRY (pipe_getsockname_abstract)
|
TEST_ENTRY (pipe_getsockname_abstract)
|
||||||
TEST_ENTRY (pipe_getsockname_blocking)
|
TEST_ENTRY (pipe_getsockname_blocking)
|
||||||
|
|||||||
@ -153,3 +153,27 @@ TEST_IMPL(pipe_bind_or_listen_error_after_close) {
|
|||||||
MAKE_VALGRIND_HAPPY(uv_default_loop());
|
MAKE_VALGRIND_HAPPY(uv_default_loop());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_IMPL(pipe_overlong_path) {
|
||||||
|
char path[512];
|
||||||
|
uv_pipe_t pipe;
|
||||||
|
uv_connect_t req;
|
||||||
|
|
||||||
|
memset(path, '@', sizeof(path));
|
||||||
|
ASSERT_OK(uv_pipe_init(uv_default_loop(), &pipe, 0));
|
||||||
|
ASSERT_EQ(UV_EINVAL,
|
||||||
|
uv_pipe_bind2(&pipe, path, sizeof(path), UV_PIPE_NO_TRUNCATE));
|
||||||
|
ASSERT_EQ(UV_EINVAL,
|
||||||
|
uv_pipe_connect2(&req,
|
||||||
|
&pipe,
|
||||||
|
path,
|
||||||
|
sizeof(path),
|
||||||
|
UV_PIPE_NO_TRUNCATE,
|
||||||
|
(uv_connect_cb) abort));
|
||||||
|
uv_close((uv_handle_t*) &pipe, NULL);
|
||||||
|
ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
|
||||||
|
|
||||||
|
MAKE_VALGRIND_HAPPY(uv_default_loop());
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user