Netutil IPv6 bugs

Motivation:
NetUtil#isValidIpV6Address and NetUtil#getIPv6ByName allowed an invalid form of mapped IPv4 addresses which lead to accepting invalid IPv6 addresses as valid.

Modifications:
- NetUtil#isValidIpV6Address and NetUtil#getIPv6ByName should only allow 7 colons for an IPv4 address if they are the first 2 characters.

Result:
More correct implementation of NetUtil#isValidIpV6Address and NetUtil#getIPv6ByName
This commit is contained in:
Scott Mitchell 2017-04-27 15:12:02 -07:00 committed by Norman Maurer
parent b1cb059540
commit ea1cb20c90
2 changed files with 42 additions and 8 deletions

View File

@ -502,6 +502,15 @@ public final class NetUtil {
} else {
return false;
}
// a special case ::1:2:3:4:5:d.d.d.d allows 7 colons with an
// IPv4 ending, otherwise 7 :'s is bad
if ((numberOfColons != 6 && !doubleColon) ||
(numberOfColons == 7 && (ipAddress.charAt(startOffset) != ':' ||
ipAddress.charAt(1 + startOffset) != ':'))) {
return false;
}
for (; j >= startOffset; --j) {
tmpChar = ipAddress.charAt(j);
if (tmpChar != '0' && tmpChar != ':') {
@ -509,12 +518,10 @@ public final class NetUtil {
}
}
}
if (!isValidIp4Word(word.toString())) {
return false;
}
if (numberOfColons != 6 && !doubleColon) {
return false;
}
word.delete(0, word.length());
break;
@ -612,9 +619,10 @@ public final class NetUtil {
}
private static boolean isValidIPv4Mapped(byte[] bytes, int currentIndex, int compressBegin, int compressLength) {
return currentIndex <= 12 && currentIndex >= 2 &&
isValidIPv4MappedSeparators(bytes[currentIndex - 1], bytes[currentIndex - 2],
(compressBegin + compressLength) >= 14) && PlatformDependent.isZero(bytes, 0, currentIndex - 3);
final boolean mustBeZero = compressBegin + compressLength >= 14;
return currentIndex <= 12 && currentIndex >= 2 && (!mustBeZero || compressBegin < 12) &&
isValidIPv4MappedSeparators(bytes[currentIndex - 1], bytes[currentIndex - 2], mustBeZero) &&
PlatformDependent.isZero(bytes, 0, currentIndex - 3);
}
/**

View File

@ -95,7 +95,10 @@ public class NetUtilTest {
"0:0:0:0:0:0:10.0.0.1", "00000000000000000000ffff0a000001",
"0:0:0:0:0::10.0.0.1", "00000000000000000000ffff0a000001",
"::0:0:0:0:0:10.0.0.1", "00000000000000000000ffff0a000001",
"0:0:0:0:0:0::10.0.0.1", "00000000000000000000ffff0a000001",
"0::0:0:0:0:10.0.0.1", "00000000000000000000ffff0a000001",
"0:0::0:0:0:10.0.0.1", "00000000000000000000ffff0a000001",
"0:0:0::0:0:10.0.0.1", "00000000000000000000ffff0a000001",
"0:0:0:0::0:10.0.0.1", "00000000000000000000ffff0a000001",
"0:0:0:0:0:ffff:10.0.0.1", "00000000000000000000ffff0a000001",
"::ffff:192.168.0.1", "00000000000000000000ffffc0a80001",
// Test if various interface names after the percent sign are recognized.
@ -257,6 +260,12 @@ public class NetUtilTest {
"0:0:0:0:0:fffff:1.0.0.1", null,
// Invalid IPv4 mapped address - too many bytes (too many 0's)
"0:0:0:0:0:0:ffff:1.0.0.1", null,
// Invalid IPv4 mapped address - too many bytes (too many 0's)
"::0:0:0:0:0:ffff:1.0.0.1", null,
// Invalid IPv4 mapped address - too many bytes (too many 0's)
"0:0:0:0:0:0::1.0.0.1", null,
// Invalid IPv4 mapped address - too many bytes (too many 0's)
"0:0:0:0:0:00000:1.0.0.1", null,
// Invalid IPv4 mapped address - too few bytes (not enough 0's)
"0:0:0:0:ffff:1.0.0.1", null,
// Invalid IPv4 mapped address - 0's after the mapped ffff indicator
@ -403,12 +412,29 @@ public class NetUtilTest {
"0:0:0:0:0:0:255.254.253.252", "::ffff:255.254.253.252",
"0:0:0:0:0::1.2.3.4", "::ffff:1.2.3.4",
"0:0:0:0::1.2.3.4", "::ffff:1.2.3.4",
"0:0:0:0:0:0::1.2.3.4", "::ffff:1.2.3.4",
"::0:0:0:0:0:1.2.3.4", "::ffff:1.2.3.4",
"0::0:0:0:0:1.2.3.4", "::ffff:1.2.3.4",
"0:0::0:0:0:1.2.3.4", "::ffff:1.2.3.4",
"0:0:0::0:0:1.2.3.4", "::ffff:1.2.3.4",
"0:0:0:0::0:1.2.3.4", "::ffff:1.2.3.4",
"0:0:0:0:0::1.2.3.4", "::ffff:1.2.3.4",
"::0:0:0:0:1.2.3.4", "::ffff:1.2.3.4",
"0::0:0:0:1.2.3.4", "::ffff:1.2.3.4",
"0:0::0:0:1.2.3.4", "::ffff:1.2.3.4",
"0:0:0::0:1.2.3.4", "::ffff:1.2.3.4",
"0:0:0:0::1.2.3.4", "::ffff:1.2.3.4",
"::0:0:0:0:1.2.3.4", "::ffff:1.2.3.4",
"0::0:0:0:1.2.3.4", "::ffff:1.2.3.4",
"0:0::0:0:1.2.3.4", "::ffff:1.2.3.4",
"0:0:0::0:1.2.3.4", "::ffff:1.2.3.4",
"0:0:0:0::1.2.3.4", "::ffff:1.2.3.4",
"::0:0:0:1.2.3.4", "::ffff:1.2.3.4",
"0::0:0:1.2.3.4", "::ffff:1.2.3.4",
"0:0::0:1.2.3.4", "::ffff:1.2.3.4",
"0:0:0::1.2.3.4", "::ffff:1.2.3.4",
"::0:0:1.2.3.4", "::ffff:1.2.3.4",
"0::0:1.2.3.4", "::ffff:1.2.3.4",
"0:0::1.2.3.4", "::ffff:1.2.3.4",
"::0:1.2.3.4", "::ffff:1.2.3.4",
"::1.2.3.4", "::ffff:1.2.3.4",