aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2023-11-25 22:43:34 -0800
committerGarrett D'Amore <garrett@damore.org>2023-11-25 22:52:31 -0800
commit003f0556a61f3e7225f4f0d0087bdf08af5b632a (patch)
tree49287eae1d85f80329dbca439f2e8b02bf67829b /src
parentfe692071ed2121ef693eaaaeacc1feb596c3e23b (diff)
downloadnng-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.txt5
-rw-r--r--src/compat/nanomsg/compat_msg_test.c92
-rw-r--r--src/compat/nanomsg/nn.c37
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);