unix,win: harmonize buffer checking
For any API that takes a buffer and size pointer, check both pointers
and the pointed-to size and return UV_EINVAL in case of error.
Example:
```
int uv_foo(char* buffer, size_t* size) {
if (buffer == NULL || size == NULL || *size == 0)
return UV_EINVAL;
...
}
```
In order to "peek" the necessary size for dynamic allocation, the
following pattern can be used:
```
char *buf;
char scratch[1];
size_t len = sizeof(scratch);
int r;
r = uv_foo(scratch, &len);
assert(r == UV_ENOBUFS);
buf = malloc(len);
r = uv_foo(buf, &len);
...
```
This commit is contained in:
parent
31ea3411cc
commit
c6d43bea09
@ -139,6 +139,9 @@ int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buffer, size_t* size) {
|
||||
struct poll_ctx* ctx;
|
||||
size_t required_len;
|
||||
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (!uv_is_active((uv_handle_t*)handle)) {
|
||||
*size = 0;
|
||||
return UV_EINVAL;
|
||||
|
||||
@ -751,7 +751,7 @@ ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) {
|
||||
int uv_cwd(char* buffer, size_t* size) {
|
||||
char scratch[1 + UV__PATH_MAX];
|
||||
|
||||
if (buffer == NULL || size == NULL)
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
/* Try to read directly into the user's buffer first... */
|
||||
|
||||
@ -644,6 +644,9 @@ int uv_send_buffer_size(uv_handle_t* handle, int *value) {
|
||||
int uv_fs_event_getpath(uv_fs_event_t* handle, char* buffer, size_t* size) {
|
||||
size_t required_len;
|
||||
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (!uv__is_active(handle)) {
|
||||
*size = 0;
|
||||
return UV_EINVAL;
|
||||
|
||||
@ -1161,9 +1161,9 @@ int uv__pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
|
||||
|
||||
err = uv__tcp_xfer_import(
|
||||
(uv_tcp_t*) client, item->xfer_type, &item->xfer_info);
|
||||
|
||||
|
||||
uv__free(item);
|
||||
|
||||
|
||||
if (err != 0)
|
||||
return err;
|
||||
|
||||
@ -1738,7 +1738,7 @@ static DWORD uv__pipe_get_ipc_remote_pid(uv_pipe_t* handle) {
|
||||
GetNamedPipeServerProcessId(handle->handle, pid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return *pid;
|
||||
}
|
||||
|
||||
@ -2602,6 +2602,9 @@ int uv_pipe_pending_count(uv_pipe_t* handle) {
|
||||
|
||||
|
||||
int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size) {
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (handle->flags & UV_HANDLE_BOUND)
|
||||
return uv__pipe_getname(handle, buffer, size);
|
||||
|
||||
@ -2616,6 +2619,9 @@ int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size) {
|
||||
|
||||
|
||||
int uv_pipe_getpeername(const uv_pipe_t* handle, char* buffer, size_t* size) {
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
/* emulate unix behaviour */
|
||||
if (handle->flags & UV_HANDLE_BOUND)
|
||||
return UV_ENOTCONN;
|
||||
|
||||
@ -191,7 +191,7 @@ int uv_cwd(char* buffer, size_t* size) {
|
||||
WCHAR *utf16_buffer;
|
||||
int r;
|
||||
|
||||
if (buffer == NULL || size == NULL) {
|
||||
if (buffer == NULL || size == NULL || *size == 0) {
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
@ -1589,7 +1589,7 @@ int uv_os_uname(uv_utsname_t* buffer) {
|
||||
version_size = sizeof(buffer->version) - version_size;
|
||||
r = uv__copy_utf16_to_utf8(os_info.szCSDVersion,
|
||||
-1,
|
||||
buffer->version +
|
||||
buffer->version +
|
||||
sizeof(buffer->version) - version_size,
|
||||
&version_size);
|
||||
if (r)
|
||||
|
||||
@ -1121,7 +1121,7 @@ TEST_IMPL(fs_event_getpath) {
|
||||
ASSERT_EQ(r, UV_EINVAL);
|
||||
r = uv_fs_event_start(&fs_event, fail_cb, watch_dir[i], 0);
|
||||
ASSERT_OK(r);
|
||||
len = 0;
|
||||
len = 1;
|
||||
r = uv_fs_event_getpath(&fs_event, buf, &len);
|
||||
ASSERT_EQ(r, UV_ENOBUFS);
|
||||
ASSERT_LT(len, sizeof buf); /* sanity check */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user