summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt4
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/core/endpt.c3
-rw-r--r--src/core/list.c2
-rw-r--r--src/core/nng_impl.h1
-rw-r--r--src/core/options.c6
-rw-r--r--src/core/strs.c98
-rw-r--r--src/core/strs.h21
-rw-r--r--src/core/transport.c11
-rw-r--r--src/platform/posix/posix_ipc.c7
-rw-r--r--src/platform/posix/posix_sockaddr.c5
-rw-r--r--src/transport/ipc/ipc.c20
-rw-r--r--src/transport/tcp/tcp.c9
13 files changed, 169 insertions, 20 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d7d05c56..87320843 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -239,6 +239,10 @@ else ()
nng_check_struct_member(msghdr msg_control sys/socket.h NNG_HAVE_MSG_CONTROL)
endif ()
+nng_check_sym (strdup string.h NNG_HAVE_STRDUP)
+nng_check_sym (strlcat string.h NNG_HAVE_STRLCAT)
+nng_check_sym (strlcpy string.h NNG_HAVE_STRLCPY)
+
add_subdirectory (src)
if (NNG_TESTS)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1510d633..1d616e95 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -66,6 +66,8 @@ set (NNG_SOURCES
core/random.h
core/socket.c
core/socket.h
+ core/strs.c
+ core/strs.h
core/taskq.c
core/taskq.h
core/thread.c
diff --git a/src/core/endpt.c b/src/core/endpt.c
index f6aaf629..9dc33867 100644
--- a/src/core/endpt.c
+++ b/src/core/endpt.c
@@ -146,8 +146,7 @@ nni_ep_create(nni_ep **epp, nni_sock *s, const char *addr, int mode)
// dereference on hot paths.
ep->ep_ops = *tran->tran_ep;
- // Could safely use strcpy here, but this avoids discussion.
- (void) snprintf(ep->ep_addr, sizeof(ep->ep_addr), "%s", addr);
+ (void) nni_strlcpy(ep->ep_addr, addr, sizeof(ep->ep_addr));
NNI_LIST_NODE_INIT(&ep->ep_node);
diff --git a/src/core/list.c b/src/core/list.c
index 97fe5c30..8b26b64a 100644
--- a/src/core/list.c
+++ b/src/core/list.c
@@ -1,5 +1,5 @@
//
-// Copyright 2017up Garrett D'Amore <garrett@damore.org>
+// Copyright 2017 Garrett D'Amore <garrett@damore.org>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
diff --git a/src/core/nng_impl.h b/src/core/nng_impl.h
index 8510dfb5..905411d7 100644
--- a/src/core/nng_impl.h
+++ b/src/core/nng_impl.h
@@ -38,6 +38,7 @@
#include "core/panic.h"
#include "core/protocol.h"
#include "core/random.h"
+#include "core/strs.h"
#include "core/taskq.h"
#include "core/thread.h"
#include "core/timer.h"
diff --git a/src/core/options.c b/src/core/options.c
index 03002d6c..4027564c 100644
--- a/src/core/options.c
+++ b/src/core/options.c
@@ -275,13 +275,11 @@ nni_option_set_id(const char *name, int id)
nni_mtx_unlock(&nni_option_lk);
return (NNG_ENOMEM);
}
- len = strlen(name) + 1;
- if ((opt->o_name = nni_alloc(len)) == NULL) {
+ if ((opt->o_name = nni_strdup(name)) == NULL) {
nni_mtx_unlock(&nni_option_lk);
NNI_FREE_STRUCT(opt);
return (NNG_ENOMEM);
}
- (void) snprintf(opt->o_name, len, "%s", name);
if (id < 0) {
id = nni_option_nextid++;
}
@@ -347,7 +345,7 @@ nni_option_sys_fini(void)
nni_option *opt;
while ((opt = nni_list_first(&nni_options)) != NULL) {
nni_list_remove(&nni_options, opt);
- nni_free(opt->o_name, strlen(opt->o_name) + 1);
+ nni_strfree(opt->o_name);
NNI_FREE_STRUCT(opt);
}
}
diff --git a/src/core/strs.c b/src/core/strs.c
new file mode 100644
index 00000000..7f236236
--- /dev/null
+++ b/src/core/strs.c
@@ -0,0 +1,98 @@
+//
+// Copyright 2017 Garrett D'Amore <garrett@damore.org>
+// Copyright 2017 Capitar IT Group BV <info@capitar.com>
+//
+// 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 <stdlib.h>
+#include <string.h>
+
+#include "core/nng_impl.h"
+
+// This file contains implementation of utility functions that are not
+// part of standard C99. (C11 has added some things here, but we cannot
+// count on them.)
+
+char *
+nni_strdup(const char *src)
+{
+#ifdef NNG_HAVE_STRDUP
+ return (strdup(src));
+#else
+ char * dst;
+ size_t len = strlen(src);
+
+ if ((dst = nni_alloc(len)) != NULL) {
+ memcpy(dst, src, len);
+ }
+ return (dst);
+#endif
+}
+
+void
+nni_strfree(char *s)
+{
+ if (s != NULL) {
+#ifdef NNG_HAVE_STRDUP
+ free(s);
+#else
+ nni_free(s, strlen(s) + 1);
+#endif
+ }
+}
+
+size_t
+nni_strlcpy(char *dst, const char *src, size_t len)
+{
+#ifdef NNG_HAVE_STRLCPY
+ return (strlcpy(dst, src, len));
+#else
+ size_t n;
+ char c;
+
+ n = 0;
+ do {
+ c = *src++;
+ n++;
+ if (n < len) {
+ *dst++ = c;
+ } else if (n == len) {
+ *dst = '\0';
+ }
+ } while (c);
+ return (n - 1);
+#endif
+}
+
+size_t
+nni_strlcat(char *dst, const char *src, size_t len)
+{
+#ifdef NNG_HAVE_STRLCAT
+ return (strlcat(dst, src, len));
+#else
+ size_t n;
+ char c;
+
+ n = 0;
+ while ((*dst != '\0') && (n < len)) {
+ n++;
+ dst++;
+ }
+
+ do {
+ c = *src++;
+ n++;
+ if (n < len) {
+ *dst++ = c;
+ } else if (n == len) {
+ *dst = '\0';
+ }
+ } while (c);
+
+ return (n - 1);
+#endif
+}
diff --git a/src/core/strs.h b/src/core/strs.h
new file mode 100644
index 00000000..741504cd
--- /dev/null
+++ b/src/core/strs.h
@@ -0,0 +1,21 @@
+//
+// Copyright 2017 Garrett D'Amore <garrett@damore.org>
+// Copyright 2017 Capitar IT Group BV <info@capitar.com>
+//
+// 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.
+//
+
+#ifndef CORE_STRS_H
+#define CORE_STRS_H
+
+// Safe string functions, in case the platform misses these.
+
+extern char * nni_strdup(const char *);
+extern void nni_strfree(char *);
+extern size_t nni_strlcpy(char *, const char *, size_t);
+extern size_t nni_strlcat(char *, const char *, size_t);
+
+#endif // CORE_STRS_H
diff --git a/src/core/transport.c b/src/core/transport.c
index 3130ae26..eead861b 100644
--- a/src/core/transport.c
+++ b/src/core/transport.c
@@ -34,6 +34,7 @@ nni_tran_register(const nni_tran *tran)
{
nni_transport *t;
int rv;
+ size_t sz;
// Its entirely possible that we are called before any sockets
// are opened. Make sure we are initialized. This has to be
@@ -56,12 +57,18 @@ nni_tran_register(const nni_tran *tran)
}
}
if ((t = NNI_ALLOC_STRUCT(t)) == NULL) {
+ nni_mtx_unlock(&nni_tran_lk);
return (NNG_ENOMEM);
}
t->t_tran = *tran;
- (void) snprintf(
- t->t_prefix, sizeof(t->t_prefix), "%s://", tran->tran_scheme);
+ sz = sizeof(t->t_prefix);
+ if ((nni_strlcpy(t->t_prefix, tran->tran_scheme, sz) >= sz) ||
+ (nni_strlcat(t->t_prefix, "://", sz) >= sz)) {
+ nni_mtx_unlock(&nni_tran_lk);
+ NNI_FREE_STRUCT(t);
+ return (NNG_EINVAL);
+ }
if ((rv = t->t_tran.tran_init()) != 0) {
nni_mtx_unlock(&nni_tran_lk);
NNI_FREE_STRUCT(t);
diff --git a/src/platform/posix/posix_ipc.c b/src/platform/posix/posix_ipc.c
index 2daec4ea..f0a9a973 100644
--- a/src/platform/posix/posix_ipc.c
+++ b/src/platform/posix/posix_ipc.c
@@ -98,9 +98,14 @@ nni_plat_ipc_remove_stale(const char *path)
int fd;
int rv;
struct sockaddr_un sun;
+ size_t sz;
sun.sun_family = AF_UNIX;
- snprintf(sun.sun_path, sizeof(sun.sun_path), "%s", path);
+ sz = sizeof(sun.sun_path);
+
+ if (nni_strlcpy(sun.sun_path, path, sz) >= sz) {
+ return (NNG_EADDRINVAL);
+ }
if ((fd = socket(AF_UNIX, NNI_STREAM_SOCKTYPE, 0)) < 0) {
return (nni_plat_errno(errno));
diff --git a/src/platform/posix/posix_sockaddr.c b/src/platform/posix/posix_sockaddr.c
index 21a2b863..ea630b01 100644
--- a/src/platform/posix/posix_sockaddr.c
+++ b/src/platform/posix/posix_sockaddr.c
@@ -31,6 +31,7 @@ nni_posix_nn2sockaddr(void *sa, const nni_sockaddr *na)
const nng_sockaddr_in * nsin;
const nng_sockaddr_in6 * nsin6;
const nng_sockaddr_path *nspath;
+ size_t sz;
switch (na->s_un.s_family) {
case NNG_AF_INET:
@@ -59,8 +60,8 @@ nni_posix_nn2sockaddr(void *sa, const nni_sockaddr *na)
nspath = &na->s_un.s_path;
memset(spath, 0, sizeof(*spath));
// Make sure that the path fits!
- if (snprintf(spath->sun_path, sizeof(spath->sun_path), "%s",
- nspath->sa_path) >= sizeof(spath->sun_path)) {
+ sz = sizeof(spath->sun_path);
+ if (nni_strlcpy(spath->sun_path, nspath->sa_path, sz) >= sz) {
return (-1);
}
spath->sun_family = PF_UNIX;
diff --git a/src/transport/ipc/ipc.c b/src/transport/ipc/ipc.c
index e5e19f36..b2c382fb 100644
--- a/src/transport/ipc/ipc.c
+++ b/src/transport/ipc/ipc.c
@@ -486,20 +486,29 @@ nni_ipc_ep_init(void **epp, const char *url, nni_sock *sock, int mode)
nni_ipc_ep * ep;
int rv;
nni_sockaddr sa;
+ size_t sz;
- if ((strlen(url) > NNG_MAXADDRLEN - 1) ||
- (strncmp(url, "ipc://", strlen("ipc://")) != 0)) {
+ if (strncmp(url, "ipc://", strlen("ipc://")) != 0) {
return (NNG_EADDRINVAL);
}
+ url += strlen("ipc://");
+ sz = sizeof(sa.s_un.s_path.sa_path);
sa.s_un.s_path.sa_family = NNG_AF_IPC;
- (void) snprintf(sa.s_un.s_path.sa_path, sizeof(sa.s_un.s_path.sa_path),
- "%s", url + strlen("ipc://"));
+
+ if (nni_strlcpy(sa.s_un.s_path.sa_path, url, sz) >= sz) {
+ return (NNG_EADDRINVAL);
+ }
if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) {
return (NNG_ENOMEM);
}
- url += strlen("ipc://");
+
+ if (nni_strlcpy(ep->addr, url, sizeof(ep->addr)) >= sizeof(ep->addr)) {
+ NNI_FREE_STRUCT(ep);
+ return (NNG_EADDRINVAL);
+ }
+
if ((rv = nni_plat_ipc_ep_init(&ep->iep, &sa, mode)) != 0) {
NNI_FREE_STRUCT(ep);
return (rv);
@@ -509,7 +518,6 @@ nni_ipc_ep_init(void **epp, const char *url, nni_sock *sock, int mode)
nni_aio_init(&ep->aio, nni_ipc_ep_cb, ep);
ep->proto = nni_sock_proto(sock);
- (void) snprintf(ep->addr, sizeof(ep->addr), "%s", url);
*epp = ep;
return (0);
diff --git a/src/transport/tcp/tcp.c b/src/transport/tcp/tcp.c
index de1bfa66..f0f07592 100644
--- a/src/transport/tcp/tcp.c
+++ b/src/transport/tcp/tcp.c
@@ -579,7 +579,9 @@ nni_tcp_ep_init(void **epp, const char *url, nni_sock *sock, int mode)
int passive;
// Make a copy of the url (to allow for destructive operations)
- snprintf(buf, sizeof(buf), "%s", url);
+ if (nni_strlcpy(buf, url, sizeof(buf)) >= sizeof(buf)) {
+ return (NNG_EADDRINVAL);
+ }
// Parse the URLs first.
rv = nni_tcp_parse_url(buf, &lhost, &lserv, &rhost, &rserv, mode);
@@ -620,6 +622,10 @@ nni_tcp_ep_init(void **epp, const char *url, nni_sock *sock, int mode)
if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) {
return (NNG_ENOMEM);
}
+ if (nni_strlcpy(ep->addr, url, sizeof(ep->addr)) >= sizeof(ep->addr)) {
+ NNI_FREE_STRUCT(ep);
+ return (NNG_EADDRINVAL);
+ }
if ((rv = nni_plat_tcp_ep_init(&ep->tep, &lsa, &rsa, mode)) != 0) {
NNI_FREE_STRUCT(ep);
@@ -630,7 +636,6 @@ nni_tcp_ep_init(void **epp, const char *url, nni_sock *sock, int mode)
nni_aio_init(&ep->aio, nni_tcp_ep_cb, ep);
ep->proto = nni_sock_proto(sock);
- (void) snprintf(ep->addr, sizeof(ep->addr), "%s", url);
*epp = ep;
return (0);