Fix ubsan warnings when parsing ipv4/ipv6 addrs

left-shifting a one-byte integer by 24 invokes undefined behavior.
Let's not do that.
This commit is contained in:
Nick Mathewson 2014-03-18 11:35:50 -04:00
parent ec99dd82e4
commit 58fc9b6c0a
2 changed files with 16 additions and 16 deletions

View File

@ -1918,15 +1918,15 @@ evutil_inet_pton(int af, const char *src, void *dst)
return inet_pton(af, src, dst);
#else
if (af == AF_INET) {
int a,b,c,d;
unsigned a,b,c,d;
char more;
struct in_addr *addr = dst;
if (sscanf(src, "%d.%d.%d.%d%c", &a,&b,&c,&d,&more) != 4)
if (sscanf(src, "%u.%u.%u.%u%c", &a,&b,&c,&d,&more) != 4)
return 0;
if (a < 0 || a > 255) return 0;
if (b < 0 || b > 255) return 0;
if (c < 0 || c > 255) return 0;
if (d < 0 || d > 255) return 0;
if (a > 255) return 0;
if (b > 255) return 0;
if (c > 255) return 0;
if (d > 255) return 0;
addr->s_addr = htonl((a<<24) | (b<<16) | (c<<8) | d);
return 1;
#ifdef AF_INET6
@ -1941,7 +1941,7 @@ evutil_inet_pton(int af, const char *src, void *dst)
else if (!dot)
eow = src+strlen(src);
else {
int byte1,byte2,byte3,byte4;
unsigned byte1,byte2,byte3,byte4;
char more;
for (eow = dot-1; eow >= src && EVUTIL_ISDIGIT_(*eow); --eow)
;
@ -1949,14 +1949,14 @@ evutil_inet_pton(int af, const char *src, void *dst)
/* We use "scanf" because some platform inet_aton()s are too lax
* about IPv4 addresses of the form "1.2.3" */
if (sscanf(eow, "%d.%d.%d.%d%c",
if (sscanf(eow, "%u.%u.%u.%u%c",
&byte1,&byte2,&byte3,&byte4,&more) != 4)
return 0;
if (byte1 > 255 || byte1 < 0 ||
byte2 > 255 || byte2 < 0 ||
byte3 > 255 || byte3 < 0 ||
byte4 > 255 || byte4 < 0)
if (byte1 > 255 ||
byte2 > 255 ||
byte3 > 255 ||
byte4 > 255)
return 0;
words[6] = (byte1<<8) | byte2;

View File

@ -179,10 +179,10 @@ regress_ipv6_parse(void *ptr)
for (j = 0; j < 4; ++j) {
/* Can't use s6_addr32 here; some don't have it. */
ev_uint32_t u =
(in6.s6_addr[j*4 ] << 24) |
(in6.s6_addr[j*4+1] << 16) |
(in6.s6_addr[j*4+2] << 8) |
(in6.s6_addr[j*4+3]);
((ev_uint32_t)in6.s6_addr[j*4 ] << 24) |
((ev_uint32_t)in6.s6_addr[j*4+1] << 16) |
((ev_uint32_t)in6.s6_addr[j*4+2] << 8) |
((ev_uint32_t)in6.s6_addr[j*4+3]);
if (u != ent->res[j]) {
TT_FAIL(("%s did not parse as expected.", ent->addr));
continue;