diff options
| author | Garrett D'Amore <garrett@damore.org> | 2023-11-25 22:43:34 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2023-11-25 22:52:31 -0800 |
| commit | 003f0556a61f3e7225f4f0d0087bdf08af5b632a (patch) | |
| tree | 49287eae1d85f80329dbca439f2e8b02bf67829b /src | |
| parent | fe692071ed2121ef693eaaaeacc1feb596c3e23b (diff) | |
| download | nng-003f0556a61f3e7225f4f0d0087bdf08af5b632a.tar.gz nng-003f0556a61f3e7225f4f0d0087bdf08af5b632a.tar.bz2 nng-003f0556a61f3e7225f4f0d0087bdf08af5b632a.zip | |
fixes #1701 compat: nn_reallocmsg is incorrect
Diffstat (limited to 'src')
| -rw-r--r-- | src/compat/nanomsg/CMakeLists.txt | 5 | ||||
| -rw-r--r-- | src/compat/nanomsg/compat_msg_test.c | 92 | ||||
| -rw-r--r-- | src/compat/nanomsg/nn.c | 37 |
3 files changed, 113 insertions, 21 deletions
diff --git a/src/compat/nanomsg/CMakeLists.txt b/src/compat/nanomsg/CMakeLists.txt index 953eabad..51679b34 100644 --- a/src/compat/nanomsg/CMakeLists.txt +++ b/src/compat/nanomsg/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2020 Staysail Systems, Inc. <info@staysail.tech> +# Copyright 2023 Staysail Systems, Inc. <info@staysail.tech> # # This software is supplied under the terms of the MIT License, a # copy of which should be located in the distribution where this @@ -11,4 +11,5 @@ nng_sources(nn.c) set(NNG_TEST_PREFIX ${NNG_TEST_PREFIX}.compat.nanomsg) -nng_test(compat_tcp_test)
\ No newline at end of file +nng_test(compat_msg_test) +nng_test(compat_tcp_test) diff --git a/src/compat/nanomsg/compat_msg_test.c b/src/compat/nanomsg/compat_msg_test.c new file mode 100644 index 00000000..d037a0b4 --- /dev/null +++ b/src/compat/nanomsg/compat_msg_test.c @@ -0,0 +1,92 @@ +// +// Copyright 2023 Staysail Systems, Inc. <info@staysail.tech> +// +// This software is supplied under the terms of the MIT License, a +// copy of which should be located in the distribution where this +// file was obtained (LICENSE.txt). A copy of the license may also be +// found online at https://opensource.org/licenses/MIT. +// + +#include <nng/compat/nanomsg/nn.h> +#include <nng/compat/nanomsg/pair.h> +#include <nng/compat/nanomsg/tcp.h> + +#include "nuts_compat.h" + +#include <nuts.h> + +void +test_msg_alloc(void) +{ + char *msg; + msg = nn_allocmsg(1, 0); + NUTS_TRUE(msg != NULL); + NUTS_NN_PASS(nn_freemsg(msg)); +} + +void +test_msg_zero_length(void) +{ + char *msg; + msg = nn_allocmsg(0, 0); // empty message is invalid + NUTS_TRUE(msg == NULL); + NUTS_TRUE(nn_errno() == EINVAL); +} + +void +test_msg_overflow(void) +{ + char *msg; + msg = nn_allocmsg((size_t)-1, 0); // this will overflow + NUTS_TRUE(msg == NULL); + NUTS_TRUE(nn_errno() == EINVAL); +} + +void +test_msg_bad_type(void) +{ + char *msg; + msg = nn_allocmsg(0, 1); // we only support message type 0 + NUTS_TRUE(msg == NULL); + NUTS_TRUE(nn_errno() == EINVAL); +} + +void +test_msg_realloc(void) +{ + char *msg0; + char *msg1; + char *msg2; + char *msg3; + + msg0 = nn_allocmsg(5, 0); + NUTS_TRUE(msg0 != NULL); + + memcpy(msg0, "this", 5); + + msg1 = nn_reallocmsg(msg0, 65536); + NUTS_TRUE(msg1 != NULL); + NUTS_TRUE(msg1 != msg0); + NUTS_MATCH(msg1, "this"); + + msg1[65000] = 'A'; + + msg2 = nn_reallocmsg(msg1, 5); + NUTS_TRUE(msg2 == msg1); + + // test for overflow + msg3 = nn_reallocmsg(msg2, (size_t)-1); + NUTS_TRUE(msg3 == NULL); + NUTS_TRUE(nn_errno() == EINVAL); + + nn_freemsg(msg2); +} + +TEST_LIST = { + { "alloc msg", test_msg_alloc }, + { "zero length", test_msg_zero_length }, + { "invalid type", test_msg_bad_type }, + { "overflow", test_msg_overflow }, + { "reallocate msg", test_msg_realloc }, + { NULL, NULL }, +}; diff --git a/src/compat/nanomsg/nn.c b/src/compat/nanomsg/nn.c index 7c5d2383..0f975b2d 100644 --- a/src/compat/nanomsg/nn.c +++ b/src/compat/nanomsg/nn.c @@ -1,5 +1,5 @@ // -// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> +// Copyright 2023 Staysail Systems, Inc. <info@staysail.tech> // Copyright 2018 Capitar IT Group BV <info@capitar.com> // // This software is supplied under the terms of the MIT License, a @@ -237,7 +237,7 @@ nn_socket(int domain, int protocol) return (-1); } - // Legacy sockets have nodelay disabled. + // Legacy sockets have Nagle disabled. (void) nng_socket_set_bool(sock, NNG_OPT_TCP_NODELAY, false); return ((int) sock.id); } @@ -298,7 +298,7 @@ nn_shutdown(int s, int ep) // Socket is wired into the endpoint... so passing a bad endpoint // ID can result in affecting the wrong socket. But this requires // a buggy application, and because we don't recycle endpoints - // until wrap, its unlikely to actually come up in practice. + // until wrap, it's unlikely to actually come up in practice. // Note that listeners and dialers share the same namespace // in the core, so we can close either one this way. @@ -326,13 +326,12 @@ nn_allocmsg(size_t size, int type) // So our "messages" from nn are really going to be nng messages // but to make this work, we use a bit of headroom in the message // to stash the message header. - if ((rv = nng_msg_alloc(&msg, size + (sizeof(msg)))) != 0) { + if ((rv = nng_msg_alloc(&msg, size)) != 0) { nn_seterror(rv); return (NULL); } - // This counts on message bodies being aligned sensibly. - *(nng_msg **) (nng_msg_body(msg)) = msg; + nng_msg_insert(msg, &msg, sizeof(msg)); // We are counting on the implementation of nn_msg_trim to not // reallocate the message but just to leave the prefix inplace. @@ -367,14 +366,14 @@ nn_reallocmsg(void *ptr, size_t len) msg = *(nng_msg **) (((char *) ptr) - sizeof(msg)); // We need to realloc the requested len, plus size for our header. - if ((rv = nng_msg_realloc(msg, len + sizeof(msg))) != 0) { + if ((rv = nng_msg_realloc(msg, len)) != 0) { // We don't free the old message. Code is free to cope // as it sees fit. nn_seterror(rv); return (NULL); } // Stash the msg header pointer - *(nng_msg **) (nng_msg_body(msg)) = msg; + nng_msg_insert(msg, &msg, sizeof(msg)); nng_msg_trim(msg, sizeof(msg)); return (nng_msg_body(msg)); } @@ -433,7 +432,7 @@ int nn_recvmsg(int s, struct nn_msghdr *mh, int flags) { int rv; - nng_msg * msg; + nng_msg *msg; size_t len; int keep = 0; nng_socket sid; @@ -498,7 +497,7 @@ nn_recvmsg(int s, struct nn_msghdr *mh, int flags) // If the caller has requested control information (header details), // we grab it. if (mh->msg_control != NULL) { - char * cdata; + char *cdata; size_t clen; size_t tlen; size_t spsz; @@ -552,10 +551,10 @@ nn_recvmsg(int s, struct nn_msghdr *mh, int flags) int nn_sendmsg(int s, const struct nn_msghdr *mh, int flags) { - nng_msg * msg = NULL; - nng_msg * cmsg = NULL; + nng_msg *msg = NULL; + nng_msg *cmsg = NULL; nng_socket sid; - char * cdata; + char *cdata; int keep = 0; size_t sz; int rv; @@ -1152,7 +1151,7 @@ struct nn_cmsghdr * nn_cmsg_next(struct nn_msghdr *mh, struct nn_cmsghdr *first) { size_t clen; - char * data; + char *data; // We only support SP headers, so there can be at most one header. if (first != NULL) { @@ -1201,8 +1200,8 @@ nn_device(int s1, int s2) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif -#include <windows.h> #include <mswsock.h> +#include <windows.h> #elif defined NNG_PLATFORM_POSIX #include <poll.h> #endif @@ -1234,8 +1233,8 @@ nn_poll(struct nn_pollfd *fds, int nfds, int timeout) if (fds[i].events & NN_POLLIN) { nng_socket s; s.id = fds[i].fd; - if ((rv = nng_socket_get_int(s, NNG_OPT_RECVFD, &fd)) != - 0) { + if ((rv = nng_socket_get_int( + s, NNG_OPT_RECVFD, &fd)) != 0) { nn_seterror(rv); NNI_FREE_STRUCTS(pfd, nfds * 2); return (-1); @@ -1251,8 +1250,8 @@ nn_poll(struct nn_pollfd *fds, int nfds, int timeout) if (fds[i].events & NN_POLLOUT) { nng_socket s; s.id = fds[i].fd; - if ((rv = nng_socket_get_int(s, NNG_OPT_SENDFD, &fd)) != - 0) { + if ((rv = nng_socket_get_int( + s, NNG_OPT_SENDFD, &fd)) != 0) { nn_seterror(rv); NNI_FREE_STRUCTS(pfd, nfds * 2); return (-1); |
