From: Tom Lane Date: Mon, 8 Nov 2004 01:54:58 +0000 (+0000) Subject: Fix unportable code in SockAddr_cidr_mask: you can't assume that X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=30f4f73a5cd9814fdf957611081237c4e6417326;p=users%2Fbernd%2Fpostgres.git Fix unportable code in SockAddr_cidr_mask: you can't assume that shifting left by full word width gives zero. Per bug report from Tyson Thomson. --- diff --git a/src/backend/libpq/ip.c b/src/backend/libpq/ip.c index bf7dac28b5..2356bcd319 100644 --- a/src/backend/libpq/ip.c +++ b/src/backend/libpq/ip.c @@ -344,37 +344,40 @@ SockAddr_cidr_mask(struct sockaddr_storage * mask, char *numbits, int family) { long bits; char *endptr; - struct sockaddr_in mask4; - -#ifdef HAVE_IPV6 - struct sockaddr_in6 mask6; -#endif bits = strtol(numbits, &endptr, 10); if (*numbits == '\0' || *endptr != '\0') return -1; - if ((bits < 0) || (family == AF_INET && bits > 32) -#ifdef HAVE_IPV6 - || (family == AF_INET6 && bits > 128) -#endif - ) - return -1; - switch (family) { case AF_INET: - mask4.sin_addr.s_addr = - htonl((0xffffffffUL << (32 - bits)) - & 0xffffffffUL); - memcpy(mask, &mask4, sizeof(mask4)); - break; + { + struct sockaddr_in mask4; + long maskl; + + if (bits < 0 || bits > 32) + return -1; + /* avoid "x << 32", which is not portable */ + if (bits > 0) + maskl = (0xffffffffUL << (32 - (int) bits)) + & 0xffffffffUL; + else + maskl = 0; + mask4.sin_addr.s_addr = htonl(maskl); + memcpy(mask, &mask4, sizeof(mask4)); + break; + } + #ifdef HAVE_IPV6 case AF_INET6: { + struct sockaddr_in6 mask6; int i; + if (bits < 0 || bits > 128) + return -1; for (i = 0; i < 16; i++) { if (bits <= 0) @@ -384,7 +387,7 @@ SockAddr_cidr_mask(struct sockaddr_storage * mask, char *numbits, int family) else { mask6.sin6_addr.s6_addr[i] = - (0xff << (8 - bits)) & 0xff; + (0xff << (8 - (int) bits)) & 0xff; } bits -= 8; }