From d7cf771072b3153e7641a9cef61160974cee8a39 Mon Sep 17 00:00:00 2001 From: jBarz Date: Fri, 27 Jan 2017 09:49:41 -0500 Subject: [PATCH] unix: use union to follow strict aliasing rules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With strict-aliasing rules, a char* type can be cast to any other pointer type. However, that does not necessarily mean char array type. So instead of de-referencing a char array, use a union with an additional char member for aliasing. PR-URL: https://github.com/libuv/libuv/pull/1211 Reviewed-By: Ben Noordhuis Reviewed-By: Saúl Ibarra Corretgé --- src/unix/stream.c | 9 +++++++-- src/unix/udp.c | 12 ++++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/unix/stream.c b/src/unix/stream.c index 7059df16..dbd04f2b 100644 --- a/src/unix/stream.c +++ b/src/unix/stream.c @@ -785,7 +785,12 @@ start: struct msghdr msg; struct cmsghdr *cmsg; int fd_to_send = uv__handle_fd((uv_handle_t*) req->send_handle); - char scratch[64] = {0}; + union { + char data[64]; + struct cmsghdr alias; + } scratch; + + memset(&scratch, 0, sizeof(scratch)); assert(fd_to_send >= 0); @@ -795,7 +800,7 @@ start: msg.msg_iovlen = iovcnt; msg.msg_flags = 0; - msg.msg_control = (void*) scratch; + msg.msg_control = &scratch.alias; msg.msg_controllen = CMSG_SPACE(sizeof(fd_to_send)); cmsg = CMSG_FIRSTHDR(&msg); diff --git a/src/unix/udp.c b/src/unix/udp.c index 1cd49257..f9630c85 100644 --- a/src/unix/udp.c +++ b/src/unix/udp.c @@ -349,7 +349,11 @@ out: static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, int domain, unsigned int flags) { - unsigned char taddr[sizeof(struct sockaddr_in6)]; + union { + struct sockaddr_in6 in6; + struct sockaddr_in in; + struct sockaddr addr; + } taddr; socklen_t addrlen; if (handle->io_watcher.fd != -1) @@ -358,7 +362,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, switch (domain) { case AF_INET: { - struct sockaddr_in* addr = (void*)&taddr; + struct sockaddr_in* addr = &taddr.in; memset(addr, 0, sizeof *addr); addr->sin_family = AF_INET; addr->sin_addr.s_addr = INADDR_ANY; @@ -367,7 +371,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, } case AF_INET6: { - struct sockaddr_in6* addr = (void*)&taddr; + struct sockaddr_in6* addr = &taddr.in6; memset(addr, 0, sizeof *addr); addr->sin6_family = AF_INET6; addr->sin6_addr = in6addr_any; @@ -379,7 +383,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, abort(); } - return uv__udp_bind(handle, (const struct sockaddr*) &taddr, addrlen, flags); + return uv__udp_bind(handle, &taddr.addr, addrlen, flags); }