Skip to content
Permalink
Browse files
HTTPCORE-713: Optimize InetAddressUtils#isIPv6*Address
Check input colon count before performing IPv6 regex validation
  • Loading branch information
schlosna authored and ok2c committed May 4, 2022
1 parent e556a29 commit ece5876b65fad1a5ea0bf7985abc1b9aba1e08ac
Showing 2 changed files with 46 additions and 8 deletions.
@@ -101,14 +101,25 @@ public static boolean isIPv4MappedIPv64Address(final String input) {
return IPV4_MAPPED_IPV6_PATTERN.matcher(input).matches();
}

static boolean hasValidIPv6ColonCount(final String input) {
int colonCount = 0;
for (int i = 0; i < input.length(); i++) {
if (input.charAt(i) == COLON_CHAR) {
colonCount++;
}
}
// IPv6 address must have at least 2 colons and not more than 7 (i.e. 8 fields)
return colonCount >= 2 && colonCount <= MAX_COLON_COUNT;
}

/**
* Checks whether the parameter is a valid standard (non-compressed) IPv6 address
*
* @param input the address string to check for validity
* @return true if the input parameter is a valid standard (non-compressed) IPv6 address
*/
public static boolean isIPv6StdAddress(final String input) {
return IPV6_STD_PATTERN.matcher(input).matches();
return hasValidIPv6ColonCount(input) && IPV6_STD_PATTERN.matcher(input).matches();
}

/**
@@ -118,13 +129,7 @@ public static boolean isIPv6StdAddress(final String input) {
* @return true if the input parameter is a valid compressed IPv6 address
*/
public static boolean isIPv6HexCompressedAddress(final String input) {
int colonCount = 0;
for(int i = 0; i < input.length(); i++) {
if (input.charAt(i) == COLON_CHAR) {
colonCount++;
}
}
return colonCount <= MAX_COLON_COUNT && IPV6_HEX_COMPRESSED_PATTERN.matcher(input).matches();
return hasValidIPv6ColonCount(input) && IPV6_HEX_COMPRESSED_PATTERN.matcher(input).matches();
}

/**
@@ -57,11 +57,22 @@ public void testValidIPv6Address() {
Assertions.assertTrue(InetAddressUtils.isIPv6StdAddress("2001:db8:0:0:0:0:1428:57ab"));
Assertions.assertTrue(InetAddressUtils.isIPv6StdAddress("0:0:0:0:0:0:0:0"));
Assertions.assertTrue(InetAddressUtils.isIPv6StdAddress("0:0:0:0:0:0:0:1"));

Assertions.assertTrue(InetAddressUtils.isIPv6HexCompressedAddress("2001:0db8:0:0::1428:57ab"));
Assertions.assertTrue(InetAddressUtils.isIPv6HexCompressedAddress("2001:0db8::1428:57ab"));
Assertions.assertTrue(InetAddressUtils.isIPv6HexCompressedAddress("2001:db8::1428:57ab"));
Assertions.assertTrue(InetAddressUtils.isIPv6HexCompressedAddress("::1"));
Assertions.assertTrue(InetAddressUtils.isIPv6HexCompressedAddress("::")); // http://tools.ietf.org/html/rfc4291#section-2.2

Assertions.assertTrue(InetAddressUtils.isIPv6Address("2001:0db8:0000:0000:0000:0000:1428:57ab"));
Assertions.assertTrue(InetAddressUtils.isIPv6Address("2001:db8:0:0:0:0:1428:57ab"));
Assertions.assertTrue(InetAddressUtils.isIPv6Address("0:0:0:0:0:0:0:0"));
Assertions.assertTrue(InetAddressUtils.isIPv6Address("0:0:0:0:0:0:0:1"));
Assertions.assertTrue(InetAddressUtils.isIPv6Address("2001:0db8:0:0::1428:57ab"));
Assertions.assertTrue(InetAddressUtils.isIPv6Address("2001:0db8::1428:57ab"));
Assertions.assertTrue(InetAddressUtils.isIPv6Address("2001:db8::1428:57ab"));
Assertions.assertTrue(InetAddressUtils.isIPv6Address("::1"));
Assertions.assertTrue(InetAddressUtils.isIPv6Address("::")); // http://tools.ietf.org/html/rfc4291#section-2.2
}

@Test
@@ -71,6 +82,7 @@ public void testInvalidIPv6Address() {
Assertions.assertFalse(InetAddressUtils.isIPv6StdAddress("0:0:0:0:0:0:0:0:0")); // Too many
Assertions.assertFalse(InetAddressUtils.isIPv6StdAddress("0:0:0:0:0:0:0")); // Too few
Assertions.assertFalse(InetAddressUtils.isIPv6HexCompressedAddress(":1"));
Assertions.assertFalse(InetAddressUtils.isIPv6Address(":1"));
Assertions.assertFalse(InetAddressUtils.isIPv6Address("2001:0db8::0000::57ab")); // Cannot have two contractions
Assertions.assertFalse(InetAddressUtils.isIPv6HexCompressedAddress("1:2:3:4:5:6:7::9")); // too many fields before ::
Assertions.assertFalse(InetAddressUtils.isIPv6HexCompressedAddress("1::3:4:5:6:7:8:9")); // too many fields after ::
@@ -135,6 +147,27 @@ public void testInvalidIPv6AddressIncorrectGroupCount() {
Assertions.assertFalse(InetAddressUtils.isIPv6HexCompressedAddress("1:2:3:4:5:6::8:9")); // too many fields in total
}

@Test
public void testHasValidIPv6ColonCount() {
Assertions.assertFalse(InetAddressUtils.hasValidIPv6ColonCount(""));
Assertions.assertFalse(InetAddressUtils.hasValidIPv6ColonCount(":"));
Assertions.assertFalse(InetAddressUtils.hasValidIPv6ColonCount("127.0.0.1"));
Assertions.assertFalse(InetAddressUtils.hasValidIPv6ColonCount(":0"));
Assertions.assertFalse(InetAddressUtils.hasValidIPv6ColonCount("0:"));
Assertions.assertFalse(InetAddressUtils.hasValidIPv6ColonCount("1:2:3:4:5:6:7:8:"));
Assertions.assertFalse(InetAddressUtils.hasValidIPv6ColonCount("1:2:3:4:5:6:7:8:9"));

Assertions.assertTrue(InetAddressUtils.hasValidIPv6ColonCount("2001:0db8:0000:0000:0000:0000:1428:57ab"));
Assertions.assertTrue(InetAddressUtils.hasValidIPv6ColonCount("2001:db8:0:0:0:0:1428:57ab"));
Assertions.assertTrue(InetAddressUtils.hasValidIPv6ColonCount("0:0:0:0:0:0:0:0"));
Assertions.assertTrue(InetAddressUtils.hasValidIPv6ColonCount("0:0:0:0:0:0:0:1"));
Assertions.assertTrue(InetAddressUtils.hasValidIPv6ColonCount("2001:0db8:0:0::1428:57ab"));
Assertions.assertTrue(InetAddressUtils.hasValidIPv6ColonCount("2001:0db8::1428:57ab"));
Assertions.assertTrue(InetAddressUtils.hasValidIPv6ColonCount("2001:db8::1428:57ab"));
Assertions.assertTrue(InetAddressUtils.hasValidIPv6ColonCount("::1"));
Assertions.assertTrue(InetAddressUtils.hasValidIPv6ColonCount("::")); // http://tools.ietf.org/html/rfc4291#section-2.2
}

@Test
public void testValidIPv4MappedIPv6Address() {
Assertions.assertTrue(InetAddressUtils.isIPv4MappedIPv64Address("::FFFF:1.2.3.4"));

0 comments on commit ece5876

Please sign in to comment.