Skip to content

Commit

Permalink
fixes #1701 compat: nn_reallocmsg is incorrect
Browse files Browse the repository at this point in the history
  • Loading branch information
gdamore committed Nov 26, 2023
1 parent fe69207 commit 003f055
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 21 deletions.
5 changes: 3 additions & 2 deletions src/compat/nanomsg/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright 2020 Staysail Systems, Inc. <[email protected]>
# Copyright 2023 Staysail Systems, Inc. <[email protected]>
#
# This software is supplied under the terms of the MIT License, a
# copy of which should be located in the distribution where this
Expand All @@ -11,4 +11,5 @@ nng_sources(nn.c)

set(NNG_TEST_PREFIX ${NNG_TEST_PREFIX}.compat.nanomsg)

nng_test(compat_tcp_test)
nng_test(compat_msg_test)
nng_test(compat_tcp_test)
92 changes: 92 additions & 0 deletions src/compat/nanomsg/compat_msg_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
//
// Copyright 2023 Staysail Systems, Inc. <[email protected]>
//
// 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 },
};
37 changes: 18 additions & 19 deletions src/compat/nanomsg/nn.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2018 Staysail Systems, Inc. <[email protected]>
// Copyright 2023 Staysail Systems, Inc. <[email protected]>
// Copyright 2018 Capitar IT Group BV <[email protected]>
//
// This software is supplied under the terms of the MIT License, a
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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.

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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));
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down

0 comments on commit 003f055

Please sign in to comment.