aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2015-02-10 22:46:57 +0100
committerMax Kellermann <max@duempel.org>2015-02-10 22:47:26 +0100
commit6e66a5b77b1c3317f7fbdd3614b20ffda2649d7a (patch)
treeddd6212189546c2f5dff99b15ec34ac6cc8d7eed
parentcf5c10bbe60be6dde40f2a5e9244b3e6ee77c298 (diff)
downloadmpd-6e66a5b77b1c3317f7fbdd3614b20ffda2649d7a.tar.gz
mpd-6e66a5b77b1c3317f7fbdd3614b20ffda2649d7a.tar.xz
mpd-6e66a5b77b1c3317f7fbdd3614b20ffda2649d7a.zip
net/Resolver: relax size check in LocalAddressToString()
Handles abstract sockets on Linux.
Diffstat (limited to '')
-rw-r--r--src/net/Resolver.cxx22
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