mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-22 10:50:07 +00:00
inet_pton: Reject IPv6 addresses with many leading zeros [BZ #16637]
2001:db8:00001::f is not a valid IPv6 address according to RFC 2373.
This commit is contained in:
parent
fa872e1b62
commit
9a0cc8c1bd
@ -1,3 +1,11 @@
|
||||
2017-06-23 Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
[BZ #16637]
|
||||
inet_pton: Reject invalid IPv6 addresses with many leading zeros.
|
||||
* resolv/inet_pton.c (inet_pton6): Count number of hexadecimal
|
||||
digits between colons.
|
||||
* resolv/tst-inet_pton.c (test_cases): Adjust test expectations.
|
||||
|
||||
2017-05-23 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Juan Manuel Torres Palma <jmtorrespalma@gmail.com>
|
||||
|
||||
|
@ -144,7 +144,8 @@ inet_pton6 (const char *src, const char *src_endp, unsigned char *dst)
|
||||
{
|
||||
unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
const char *curtok;
|
||||
int ch, saw_xdigit;
|
||||
int ch;
|
||||
size_t xdigits_seen; /* Number of hex digits since colon. */
|
||||
unsigned int val;
|
||||
|
||||
tp = memset (tmp, '\0', NS_IN6ADDRSZ);
|
||||
@ -162,7 +163,7 @@ inet_pton6 (const char *src, const char *src_endp, unsigned char *dst)
|
||||
}
|
||||
|
||||
curtok = src;
|
||||
saw_xdigit = 0;
|
||||
xdigits_seen = 0;
|
||||
val = 0;
|
||||
while (src < src_endp)
|
||||
{
|
||||
@ -170,17 +171,19 @@ inet_pton6 (const char *src, const char *src_endp, unsigned char *dst)
|
||||
int digit = hex_digit_value (ch);
|
||||
if (digit >= 0)
|
||||
{
|
||||
if (xdigits_seen == 4)
|
||||
return 0;
|
||||
val <<= 4;
|
||||
val |= digit;
|
||||
if (val > 0xffff)
|
||||
return 0;
|
||||
saw_xdigit = 1;
|
||||
++xdigits_seen;
|
||||
continue;
|
||||
}
|
||||
if (ch == ':')
|
||||
{
|
||||
curtok = src;
|
||||
if (!saw_xdigit)
|
||||
if (xdigits_seen == 0)
|
||||
{
|
||||
if (colonp)
|
||||
return 0;
|
||||
@ -193,7 +196,7 @@ inet_pton6 (const char *src, const char *src_endp, unsigned char *dst)
|
||||
return 0;
|
||||
*tp++ = (unsigned char) (val >> 8) & 0xff;
|
||||
*tp++ = (unsigned char) val & 0xff;
|
||||
saw_xdigit = 0;
|
||||
xdigits_seen = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
@ -201,12 +204,12 @@ inet_pton6 (const char *src, const char *src_endp, unsigned char *dst)
|
||||
&& inet_pton4 (curtok, src_endp, tp) > 0)
|
||||
{
|
||||
tp += NS_INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
xdigits_seen = 0;
|
||||
break; /* '\0' was seen by inet_pton4. */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (saw_xdigit)
|
||||
if (xdigits_seen > 0)
|
||||
{
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return 0;
|
||||
|
@ -226,13 +226,7 @@ const struct test_case test_cases[] =
|
||||
},
|
||||
{.input = "2", },
|
||||
{.input = "2.", },
|
||||
{.input = "2001:db8:00001::f",
|
||||
.ipv6_ok = true,
|
||||
.ipv6_expected = {
|
||||
0x20, 0x1, 0xd, 0xb8, 0x0, 0x1, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf
|
||||
},
|
||||
},
|
||||
{.input = "2001:db8:00001::f", },
|
||||
{.input = "2001:db8:10000::f", },
|
||||
{.input = "2001:db8:1234:5678:abcd:ef01:2345:67",
|
||||
.ipv6_ok = true,
|
||||
@ -454,13 +448,7 @@ const struct test_case test_cases[] =
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
|
||||
},
|
||||
},
|
||||
{.input = "::00001",
|
||||
.ipv6_ok = true,
|
||||
.ipv6_expected = {
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1
|
||||
},
|
||||
},
|
||||
{.input = "::00001", },
|
||||
{.input = "::1",
|
||||
.ipv6_ok = true,
|
||||
.ipv6_expected = {
|
||||
|
Loading…
Reference in New Issue
Block a user