diff --git a/toolbox/net/Endpoint.hpp b/toolbox/net/Endpoint.hpp index 5d177154..cb7fe2f8 100644 --- a/toolbox/net/Endpoint.hpp +++ b/toolbox/net/Endpoint.hpp @@ -70,11 +70,17 @@ template StreamT& print_unix_endpoint(StreamT& os, const T& ep) { constexpr const char* scheme = "unix://"; - // abstract unix socket's path starts with '\0' and not null-terminated + const size_t family_size = sizeof(std::declval().sun_family); + if (ep.size() <= family_size) { + // No path + os << scheme; + return os; + } const auto* path = reinterpret_cast(ep.data())->sun_path; if (path[0] == '\0') { - size_t size = ep.size() - sizeof(std::declval().sun_family) - 1; - os << scheme << '|' << std::string_view{path + 1, size}; + // abstract unix socket's path starts with '\0' and not null-terminated + const size_t path_size = ep.size() - family_size; + os << scheme << '|' << std::string_view{path + 1, path_size - 1}; return os; } os << scheme << *ep.data(); diff --git a/toolbox/net/Endpoint.ut.cpp b/toolbox/net/Endpoint.ut.cpp index 4e2e599e..cc1339a7 100644 --- a/toolbox/net/Endpoint.ut.cpp +++ b/toolbox/net/Endpoint.ut.cpp @@ -179,6 +179,28 @@ BOOST_AUTO_TEST_CASE(ParseStreamUnixAbstractCase) BOOST_CHECK_EQUAL(to_string(ep), uri); } +BOOST_AUTO_TEST_CASE(ParseStreamUnixAbstractEmptyCase) +{ + const auto uri = "unix://|"s; + const auto ep = parse_stream_endpoint(uri); + BOOST_CHECK_EQUAL(ep.protocol().family(), AF_UNIX); + BOOST_CHECK_EQUAL(ep.protocol().type(), SOCK_STREAM); + BOOST_CHECK_EQUAL(ep.protocol().protocol(), 0); + BOOST_CHECK_EQUAL(to_string(ep), uri); +} + +BOOST_AUTO_TEST_CASE(ParseStreamUnixEmptyCase) +{ + auto sock = os::socket(net::UnixStreamProtocol{}); + StreamEndpoint ep; + get_sock_name(sock.get(), ep); + + BOOST_CHECK_EQUAL(ep.protocol().family(), AF_UNIX); + BOOST_CHECK_EQUAL(ep.protocol().type(), SOCK_STREAM); + BOOST_CHECK_EQUAL(ep.protocol().protocol(), 0); + BOOST_CHECK_EQUAL(to_string(ep), "unix://"); +} + BOOST_AUTO_TEST_CASE(ParseStreamBindCase) { const auto ep = parse_stream_endpoint("tcp4://:80");