From 8158996f0749eee31e824b94db9d59b12e560836 Mon Sep 17 00:00:00 2001 From: Sahana Bogar Date: Thu, 25 Jun 2026 12:36:41 +0530 Subject: [PATCH] range-check the port for IPv6 hosts in isValidAuthority --- .../validator/routines/UrlValidator.java | 21 +++++++++++-------- .../validator/routines/UrlValidatorTest.java | 11 ++++++++++ 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/apache/commons/validator/routines/UrlValidator.java b/src/main/java/org/apache/commons/validator/routines/UrlValidator.java index 5c6b9059e..4a9bf519d 100644 --- a/src/main/java/org/apache/commons/validator/routines/UrlValidator.java +++ b/src/main/java/org/apache/commons/validator/routines/UrlValidator.java @@ -443,16 +443,19 @@ protected boolean isValidAuthority(final String authority) { return false; } } - final String port = authorityMatcher.group(PARSE_AUTHORITY_PORT); - if (!GenericValidator.isBlankOrNull(port)) { - try { - final int iPort = Integer.parseInt(port); - if (iPort < 0 || iPort > MAX_UNSIGNED_16_BIT_INT) { - return false; - } - } catch (final NumberFormatException nfe) { - return false; // this can happen for big numbers + } + + // the port is captured in the same group regardless of host form, so it must be + // range checked for a bracketed IPv6 host too, not just the hostname/IPv4 branch + final String port = authorityMatcher.group(PARSE_AUTHORITY_PORT); + if (!GenericValidator.isBlankOrNull(port)) { + try { + final int iPort = Integer.parseInt(port); + if (iPort < 0 || iPort > MAX_UNSIGNED_16_BIT_INT) { + return false; } + } catch (final NumberFormatException nfe) { + return false; // this can happen for big numbers } } diff --git a/src/test/java/org/apache/commons/validator/routines/UrlValidatorTest.java b/src/test/java/org/apache/commons/validator/routines/UrlValidatorTest.java index 58d5602cd..33f4d3945 100644 --- a/src/test/java/org/apache/commons/validator/routines/UrlValidatorTest.java +++ b/src/test/java/org/apache/commons/validator/routines/UrlValidatorTest.java @@ -173,6 +173,17 @@ void testIpv6EmbeddedIpv4() { assertFalse(urlValidator.isValid("http://[::ffff:129.144.52.999]/")); } + @Test + void testIpv6Port() { + final UrlValidator urlValidator = new UrlValidator(); + // a port on a bracketed IPv6 host must be range checked just like a hostname/IPv4 host + assertTrue(urlValidator.isValid("http://[::1]:65535/index.html")); + assertFalse(urlValidator.isValid("http://[::1]:65536/index.html")); + assertFalse(urlValidator.isValid("http://[::1]:99999/index.html")); + assertTrue(urlValidator.isValidAuthority("[::1]:65535")); + assertFalse(urlValidator.isValidAuthority("[::1]:65536")); + } + @ParameterizedTest // @formatter:off @ValueSource(strings = {