Skip to content

Commit

Permalink
HTTPCORE-713: Optimize InetAddressUtils#isIPv6*Address
Browse files Browse the repository at this point in the history
Check input colon count before performing IPv6 regex validation
  • Loading branch information
schlosna authored and ok2c committed May 4, 2022
1 parent 1963a3e commit c6dfb03
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

/**
Expand All @@ -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();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,22 @@ public void testValidIPv6Address() {
Assert.assertTrue(InetAddressUtils.isIPv6StdAddress("2001:db8:0:0:0:0:1428:57ab"));
Assert.assertTrue(InetAddressUtils.isIPv6StdAddress("0:0:0:0:0:0:0:0"));
Assert.assertTrue(InetAddressUtils.isIPv6StdAddress("0:0:0:0:0:0:0:1"));

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

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

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

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

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

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

0 comments on commit c6dfb03

Please sign in to comment.