diff --git a/sys/include/net/sock/util.h b/sys/include/net/sock/util.h index 5b1f443a3df6..fb5d828ea21c 100644 --- a/sys/include/net/sock/util.h +++ b/sys/include/net/sock/util.h @@ -54,12 +54,14 @@ int sock_udp_ep_fmt(const sock_udp_ep_t *endpoint, char *addr_str, uint16_t *por * * @note Caller has to make sure hostport and urlpath can hold the results! * Make sure to provide space for @ref SOCK_HOSTPORT_MAXLEN respectively - * @ref SOCK_URLPATH_MAXLEN bytes. + * @ref SOCK_URLPATH_MAXLEN bytes, if pointers are not NULL. * Scheme part of the URL is limited to @ref SOCK_SCHEME_MAXLEN length. * - * @param[in] url URL to split - * @param[out] hostport where to write host:port - * @param[out] urlpath where to write url path + * @pre `url != NULL` + * + * @param[in] url URL to split. Must not be NULL. + * @param[out] hostport where to write host:port. Can be NULL. + * @param[out] urlpath where to write url path. Can be NULL. * * @returns 0 on success * @returns <0 otherwise diff --git a/sys/net/sock/sock_util.c b/sys/net/sock/sock_util.c index 6f265716f9eb..4045bc055b35 100644 --- a/sys/net/sock/sock_util.c +++ b/sys/net/sock/sock_util.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "net/sock/udp.h" #include "net/sock/util.h" @@ -116,6 +117,7 @@ static char* _find_pathstart(const char *url) int sock_urlsplit(const char *url, char *hostport, char *urlpath) { + assert(url); char *hoststart = _find_hoststart(url); if (!hoststart) { return -EINVAL; @@ -123,23 +125,25 @@ int sock_urlsplit(const char *url, char *hostport, char *urlpath) char *pathstart = _find_pathstart(hoststart); - size_t hostlen = pathstart - hoststart; - /* hostlen must be smaller SOCK_HOSTPORT_MAXLEN to have space for the null - * terminator */ - if (hostlen > SOCK_HOSTPORT_MAXLEN - 1) { - return -EOVERFLOW; + if (hostport) { + size_t hostlen = pathstart - hoststart; + /* hostlen must be smaller SOCK_HOSTPORT_MAXLEN to have space for the null + * terminator */ + if (hostlen > SOCK_HOSTPORT_MAXLEN - 1) { + return -EOVERFLOW; + } + memcpy(hostport, hoststart, hostlen); + hostport[hostlen] = '\0'; } - memcpy(hostport, hoststart, hostlen); - *(hostport + hostlen) = '\0'; - size_t pathlen = strlen(pathstart); - if (pathlen) { + if (urlpath) { + size_t pathlen = strlen(pathstart); if (pathlen > SOCK_URLPATH_MAXLEN - 1) { return -EOVERFLOW; } memcpy(urlpath, pathstart, pathlen); + urlpath[pathlen] = '\0'; } - *(urlpath + pathlen) = '\0'; return 0; } diff --git a/tests/unittests/tests-sock_util/tests-sock_util.c b/tests/unittests/tests-sock_util/tests-sock_util.c index ea46e538cdd4..d0677046148a 100644 --- a/tests/unittests/tests-sock_util/tests-sock_util.c +++ b/tests/unittests/tests-sock_util/tests-sock_util.c @@ -152,6 +152,18 @@ static void test_sock_util_urlsplit__urlpath_too_long(void) sock_urlsplit(TEST_URL_LONG_URLPATH, addr, urlpath)); } +static void test_sock_util_urlsplit__null_addr_buffer(void) +{ + TEST_ASSERT_EQUAL_INT(0, sock_urlsplit(TEST_URL, addr, NULL)); + TEST_ASSERT_EQUAL_STRING(TEST_URL_HOSTPART, (char*)addr); +} + +static void test_sock_util_urlsplit__null_path_buffer(void) +{ + TEST_ASSERT_EQUAL_INT(0, sock_urlsplit(TEST_URL, NULL, urlpath)); + TEST_ASSERT_EQUAL_STRING(TEST_URL_LOCALPART, (char*)urlpath); +} + static void test_sock_util_str2ep__ipv6_noport(void) { sock_udp_ep_t ep; @@ -210,6 +222,8 @@ Test *tests_sock_util_all(void) new_TestFixture(test_sock_util_urlsplit__no_schema), new_TestFixture(test_sock_util_urlsplit__hostport_too_long), new_TestFixture(test_sock_util_urlsplit__urlpath_too_long), + new_TestFixture(test_sock_util_urlsplit__null_addr_buffer), + new_TestFixture(test_sock_util_urlsplit__null_path_buffer), new_TestFixture(test_sock_util_str2ep__ipv6_noport), new_TestFixture(test_sock_util_str2ep__ipv4_noport), new_TestFixture(test_sock_util_str2ep__ipv4_port),