diff options
author | Max Kellermann <max@duempel.org> | 2015-02-10 22:46:57 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2015-02-10 22:47:26 +0100 |
commit | 6e66a5b77b1c3317f7fbdd3614b20ffda2649d7a (patch) | |
tree | ddd6212189546c2f5dff99b15ec34ac6cc8d7eed /src/net | |
parent | cf5c10bbe60be6dde40f2a5e9244b3e6ee77c298 (diff) |
net/Resolver: relax size check in LocalAddressToString()
Handles abstract sockets on Linux.
Diffstat (limited to 'src/net')
-rw-r--r-- | src/net/Resolver.cxx | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/src/net/Resolver.cxx b/src/net/Resolver.cxx index c7a684263..19df84096 100644 --- a/src/net/Resolver.cxx +++ b/src/net/Resolver.cxx @@ -23,6 +23,8 @@ #include "util/Error.hxx" #include "util/Domain.hxx" +#include <algorithm> + #ifndef WIN32 #include <sys/socket.h> #include <netdb.h> @@ -48,10 +50,26 @@ const Domain resolver_domain("resolver"); static std::string LocalAddressToString(const struct sockaddr_un &s_un, size_t size) { - if (size < sizeof(s_un) || s_un.sun_path[0] == 0) + const size_t prefix_size = (size_t) + ((struct sockaddr_un *)nullptr)->sun_path; + assert(size >= prefix_size); + + size_t result_length = size - prefix_size; + + /* remove the trailing null terminator */ + if (result_length > 0 && s_un.sun_path[result_length - 1] == 0) + --result_length; + + if (result_length == 0) return "local"; - return s_un.sun_path; + std::string result(s_un.sun_path, result_length); + + /* replace all null bytes with '@'; this also handles abstract + addresses (Linux specific) */ + std::replace(result.begin(), result.end(), '\0', '@'); + + return result; } #endif |