diff --git a/src/main/java/org/apache/commons/validator/routines/InetAddressValidator.java b/src/main/java/org/apache/commons/validator/routines/InetAddressValidator.java index c8d9c1063..29124da1f 100644 --- a/src/main/java/org/apache/commons/validator/routines/InetAddressValidator.java +++ b/src/main/java/org/apache/commons/validator/routines/InetAddressValidator.java @@ -201,9 +201,14 @@ public boolean isValidInet6Address(String inet6Address) { if (octet.length() > IPV6_MAX_HEX_DIGITS_PER_GROUP) { return false; } - final char char0 = octet.charAt(0); - if (char0 == '+' || char0 == '-') { - return false; // Integer.parseInt accepts a leading sign, which is not a valid hex group + // Only ASCII hex digits are valid. Integer.parseInt(_, 16) also tolerates a leading sign + // and the non-ASCII Unicode digits that Character.digit maps to 0-15 (for example the + // fullwidth and Arabic-Indic forms), none of which belong in an IPv6 hex group. + for (int n = 0; n < octet.length(); n++) { + final char ch = octet.charAt(n); + if ((ch < '0' || ch > '9') && (ch < 'A' || ch > 'F') && (ch < 'a' || ch > 'f')) { + return false; + } } int octetInt = 0; try { diff --git a/src/test/java/org/apache/commons/validator/routines/InetAddressValidatorTest.java b/src/test/java/org/apache/commons/validator/routines/InetAddressValidatorTest.java index 212ce351d..c3d862e20 100644 --- a/src/test/java/org/apache/commons/validator/routines/InetAddressValidatorTest.java +++ b/src/test/java/org/apache/commons/validator/routines/InetAddressValidatorTest.java @@ -162,6 +162,9 @@ void testIPv6() { assertFalse(validator.isValidInet6Address("1:2:3:4:5:6:7:+8"), "IPV6 1:2:3:4:5:6:7:+8 should be invalid"); // signed hex group assertFalse(validator.isValidInet6Address("fe80::+1"), "IPV6 fe80::+1 should be invalid"); // signed hex group assertFalse(validator.isValidInet6Address("::+f"), "IPV6 ::+f should be invalid"); // signed hex group + assertFalse(validator.isValidInet6Address("1234::"), "IPV6 with fullwidth digits should be invalid"); // non-ASCII hex group + assertFalse(validator.isValidInet6Address("١٢::"), "IPV6 with Arabic-Indic digits should be invalid"); // non-ASCII hex group + assertFalse(validator.isValidInet6Address("1:2:3:4:5:6:7:8"), "IPV6 with a fullwidth digit group should be invalid"); // non-ASCII hex group assertTrue(validator.isValidInet6Address("1:2:3:4::7:8"), "IPV6 1:2:3:4::7:8 should be valid"); assertTrue(validator.isValidInet6Address("1:2:3::7:8"), "IPV6 1:2:3::7:8 should be valid"); assertTrue(validator.isValidInet6Address("1:2::7:8"), "IPV6 1:2::7:8 should be valid");