Resolve strict-aliasing problems in ip6_ntop.

addr-util.c:191:3: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
This commit is contained in:
david 2012-09-01 03:29:39 +00:00
parent 3b55096ab4
commit f7873c0089
2 changed files with 63 additions and 4 deletions

View file

@ -1125,3 +1125,55 @@ index 392d44f..bf3e9e7 100644
default:
errno = EINVAL;
return (-1);
o Fixed strict aliasing warnings in ip6_ntop.
diff --git libdnet-stripped/src/addr-util.c libdnet-stripped/src/addr-util.c
index 6a32958..973f16c 100644
--- libdnet-stripped/src/addr-util.c
+++ libdnet-stripped/src/addr-util.c
@@ -174,6 +174,7 @@ ip_pton(const char *p, ip_addr_t *ip)
char *
ip6_ntop(const ip6_addr_t *ip6, char *dst, size_t len)
{
+ uint16_t data[IP6_ADDR_LEN / 2];
struct { int base, len; } best, cur;
char *p = dst;
int i;
@@ -183,12 +184,18 @@ ip6_ntop(const ip6_addr_t *ip6, char *dst, size_t len)
if (len < 46)
return (NULL);
+ /* Copy into 16-bit array. */
+ for (i = 0; i < IP6_ADDR_LEN / 2; i++) {
+ data[i] = ip6->data[2 * i] << 8;
+ data[i] |= ip6->data[2 * i + 1];
+ }
+
best.base = cur.base = -1;
/*
* Algorithm borrowed from Vixie's inet_pton6()
*/
for (i = 0; i < IP6_ADDR_LEN; i += 2) {
- if (*((uint16_t *)&ip6->data[i]) == 0) {
+ if (data[i / 2] == 0) {
if (cur.base == -1) {
cur.base = i;
cur.len = 0;
@@ -215,13 +222,13 @@ ip6_ntop(const ip6_addr_t *ip6, char *dst, size_t len)
i += best.len;
} else if (i == 12 && best.base == 0 &&
(best.len == 10 || (best.len == 8 &&
- *((uint16_t *)&ip6->data[10]) == 0xffff))) {
- if (ip_ntop((ip_addr_t *)&ip6->data[12], p,
+ data[5] == 0xffff))) {
+ if (ip_ntop((ip_addr_t *)&data[6], p,
len - (p - dst)) == NULL)
return (NULL);
return (dst);
} else p += sprintf(p, "%x:",
- ntohs(*((uint16_t *)&ip6->data[i])));
+ ntohs(data[i / 2]));
}
if (best.base + 2 + best.len == IP6_ADDR_LEN) {
*p = '\0';

View file

@ -174,6 +174,7 @@ ip_pton(const char *p, ip_addr_t *ip)
char *
ip6_ntop(const ip6_addr_t *ip6, char *dst, size_t len)
{
uint16_t data[IP6_ADDR_LEN / 2];
struct { int base, len; } best, cur;
char *p = dst;
int i;
@ -183,12 +184,18 @@ ip6_ntop(const ip6_addr_t *ip6, char *dst, size_t len)
if (len < 46)
return (NULL);
/* Copy into 16-bit array. */
for (i = 0; i < IP6_ADDR_LEN / 2; i++) {
data[i] = ip6->data[2 * i] << 8;
data[i] |= ip6->data[2 * i + 1];
}
best.base = cur.base = -1;
/*
* Algorithm borrowed from Vixie's inet_pton6()
*/
for (i = 0; i < IP6_ADDR_LEN; i += 2) {
if (*((uint16_t *)&ip6->data[i]) == 0) {
if (data[i / 2] == 0) {
if (cur.base == -1) {
cur.base = i;
cur.len = 0;
@ -215,13 +222,13 @@ ip6_ntop(const ip6_addr_t *ip6, char *dst, size_t len)
i += best.len;
} else if (i == 12 && best.base == 0 &&
(best.len == 10 || (best.len == 8 &&
*((uint16_t *)&ip6->data[10]) == 0xffff))) {
if (ip_ntop((ip_addr_t *)&ip6->data[12], p,
data[5] == 0xffff))) {
if (ip_ntop((ip_addr_t *)&data[6], p,
len - (p - dst)) == NULL)
return (NULL);
return (dst);
} else p += sprintf(p, "%x:",
ntohs(*((uint16_t *)&ip6->data[i])));
ntohs(data[i / 2]));
}
if (best.base + 2 + best.len == IP6_ADDR_LEN) {
*p = '\0';