1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-18 17:41:14 +03:00

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.
This commit is contained in:
Tom Lane 2004-11-08 01:54:58 +00:00
parent 5a57beccc3
commit 3392959b6e

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.23.2.1 2004/04/24 20:10:47 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.23.2.2 2004/11/08 01:54:58 tgl Exp $
*
* This file and the IPV6 implementation were initially provided by
* Nigel Kukard <nkukard@lbsd.net>, Linux Based Systems Design
@ -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);
{
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;
}