This is an automated email from the ASF dual-hosted git repository. chibenwa pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-jspf.git
commit 428c1c8ef078d2cd7fc1f59c50bd92f4f63ffeb1 Author: Quan Tran <[email protected]> AuthorDate: Fri Oct 30 16:44:00 2026 +0700 [FIX] Inet6Util.isValidIP6Address: count the groups The validator counted colons: it rejected an address where "::" starts or ends 7 groups (1:2:3:4:5:6:7:: has 8 colons), and, before an IPv4 tail, it did not check the groups left for the "::": it accepted 1:2:3::5:6:7:81.2.3.4, 9 groups. An ip6: mechanism with the first is a permerror, and the second is read as another network. Allow 8 colons, then count the groups as RFC 4291 2.2 does: 8, the IPv4 tail counting as 2, or at most 7 with a "::". --- .../java/org/apache/james/jspf/core/Inet6Util.java | 25 ++++++++++++++++++++-- .../org/apache/james/jspf/core/IPAddrTest.java | 14 ++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/resolver/src/main/java/org/apache/james/jspf/core/Inet6Util.java b/resolver/src/main/java/org/apache/james/jspf/core/Inet6Util.java index a47862a..e917c52 100644 --- a/resolver/src/main/java/org/apache/james/jspf/core/Inet6Util.java +++ b/resolver/src/main/java/org/apache/james/jspf/core/Inet6Util.java @@ -298,7 +298,8 @@ public class Inet6Util { } // END FIX "IP6 mechanism syntax #ip6-bad1" numberOfColons++; - if (numberOfColons > 7) + // 8 when a "::" starts or ends x:x:x:x:x:x:x: the groups are counted below + if (numberOfColons > 8) return false; if (numberOfPeriods > 0) return false; @@ -363,7 +364,27 @@ public class Inet6Util { } } - return true; + String address = ipAddress.substring(offset, length - offset); + if (address.indexOf('%') >= 0) { + address = address.substring(0, address.indexOf('%')); + } + return hasValidGroupCount(address, doubleColon); + } + + /** + * RFC 4291 2.2: 8 groups of 16 bits, the last 2 of which can be written as an IPv4 address. A "::" + * stands for one or more groups of zeros, so it leaves at most 7. + */ + private static boolean hasValidGroupCount(String address, boolean doubleColon) { + int groups = 0; + for (String group : address.split(":")) { + if (group.indexOf('.') >= 0) { + groups += 2; + } else if (!group.isEmpty()) { + groups++; + } + } + return doubleColon ? groups <= 7 : groups == 8; } public static boolean isValidIP4Word(String word) { diff --git a/resolver/src/test/java/org/apache/james/jspf/core/IPAddrTest.java b/resolver/src/test/java/org/apache/james/jspf/core/IPAddrTest.java index fc63337..a5f689d 100644 --- a/resolver/src/test/java/org/apache/james/jspf/core/IPAddrTest.java +++ b/resolver/src/test/java/org/apache/james/jspf/core/IPAddrTest.java @@ -53,6 +53,20 @@ public class IPAddrTest extends TestCase { assertEquals("ip6", IPAddr.getInAddress("::")); } + public void testIsValidIP6AddressCountsTheGroups() { + assertTrue(Inet6Util.isValidIP6Address("1:2:3:4:5:6:7::")); + assertTrue(Inet6Util.isValidIP6Address("::2:3:4:5:6:7:8")); + assertTrue(Inet6Util.isValidIP6Address("1:2:3:4:5::7:8")); + assertTrue(Inet6Util.isValidIP6Address("1:2:3:4:5:6:1.2.3.4")); + assertTrue(Inet6Util.isValidIP6Address("1:2:3:4:5::1.2.3.4")); + assertTrue(Inet6Util.isValidIP6Address("::1.2.3.4")); + assertFalse(Inet6Util.isValidIP6Address("1:2:3:4:5:6:7:8:9")); + assertFalse(Inet6Util.isValidIP6Address("1:2:3:4::5:6:7:8")); + assertFalse(Inet6Util.isValidIP6Address("1:2:3::5:6:7:81.2.3.4")); + assertFalse(Inet6Util.isValidIP6Address("1:2:3:4:5:6:7:1.2.3.4")); + assertFalse(Inet6Util.isValidIP6Address("1:2:3:4:5:6:7")); + } + public void testInvalidIp6Address() throws PermErrorException { try { assertEquals("ip6", IPAddr.getInAddress("12AB:0:0:CD3")); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
