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 7b8d973b1a7d1fc7924ef9af192afa90ed23d0dc
Author: Quan Tran <[email protected]>
AuthorDate: Fri Oct 30 16:33:50 2026 +0700

    [FIX] MacroExpand: read a digit transformer above an int as all the parts
    
    %{d99999999999} made Integer.parseInt throw NumberFormatException out
    of the expansion, of a domain-spec or of an explanation: the check
    ended as neutral.
    
    RFC 7208 7.3: a number of parts above the parts available means all of
    them, so read such a value as Integer.MAX_VALUE. A value of zero,
    whatever its number of digits, is still an error.
---
 .../java/org/apache/james/jspf/core/MacroExpand.java  | 19 ++++++++++++++++---
 .../org/apache/james/jspf/core/MacroExpandTest.java   | 13 +++++++++++++
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/resolver/src/main/java/org/apache/james/jspf/core/MacroExpand.java 
b/resolver/src/main/java/org/apache/james/jspf/core/MacroExpand.java
index 3e9c5f1..a997623 100644
--- a/resolver/src/main/java/org/apache/james/jspf/core/MacroExpand.java
+++ b/resolver/src/main/java/org/apache/james/jspf/core/MacroExpand.java
@@ -64,7 +64,20 @@ public class MacroExpand {
     public static class RequireClientDomainException extends Exception {
 
         private static final long serialVersionUID = 3834282981657676530L;
-        
+
+    }
+
+    /**
+     * @param digits the DIGIT transformer of a macro, of any length
+     * @return its value, Integer.MAX_VALUE for a larger one: more parts than 
there are means all of
+     *         them (RFC 7208 7.1)
+     */
+    private static int parseDigitTransformer(String digits) {
+        String value = digits.replaceFirst("^0+", "");
+        if (value.length() > 9) {
+            return Integer.MAX_VALUE;
+        }
+        return value.isEmpty() ? 0 : Integer.parseInt(value);
     }
 
     /**
@@ -345,7 +358,7 @@ public class MacroExpand {
         cellMatcher = cellPattern.matcher(replaceValue);
         while (cellMatcher.find()) {
             domainNumber = cellMatcher.group();
-            if (Integer.parseInt(domainNumber) == 0) {
+            if (parseDigitTransformer(domainNumber) == 0) {
                 throw new PermErrorException(
                         "Digit transformer must be non-zero");
             }
@@ -373,7 +386,7 @@ public class MacroExpand {
         // Truncate domain name to number of sub sections
         String returnData;
         if (!domainNumber.equals("")) {
-            returnData = subset(data, Integer.parseInt(domainNumber));
+            returnData = subset(data, parseDigitTransformer(domainNumber));
         } else {
             returnData = subset(data);
         }
diff --git 
a/resolver/src/test/java/org/apache/james/jspf/core/MacroExpandTest.java 
b/resolver/src/test/java/org/apache/james/jspf/core/MacroExpandTest.java
index abef56b..dcf2682 100644
--- a/resolver/src/test/java/org/apache/james/jspf/core/MacroExpandTest.java
+++ b/resolver/src/test/java/org/apache/james/jspf/core/MacroExpandTest.java
@@ -137,6 +137,19 @@ public class MacroExpandTest extends TestCase {
         assertEquals("example.email", defIp4me.expand("%{d2r}", new 
rfcIP4MacroData(), MacroExpand.DOMAIN));
     }
 
+    public void testDigitTransformerAboveAnIntKeepsAllTheParts() throws 
PermErrorException {
+        assertEquals("email.example.com", defIp4me.expand("%{d99999999999}", 
new rfcIP4MacroData(), MacroExpand.DOMAIN));
+        assertEquals("com.example.email", defIp4me.expand("%{d99999999999r}", 
new rfcIP4MacroData(), MacroExpand.DOMAIN));
+    }
+
+    public void testLongZeroDigitTransformerIsError() {
+        try {
+            defIp4me.expand("%{d00000000000}", new rfcIP4MacroData(), 
MacroExpand.DOMAIN);
+            fail("zero digit transformer");
+        } catch (PermErrorException e) {
+        }
+    }
+
     public void testPercL() throws PermErrorException {
         assertEquals("strong-bad", defIp4me.expand("%{l}", new 
rfcIP4MacroData(), MacroExpand.DOMAIN));
         assertEquals("strong.bad", defIp4me.expand("%{l-}", new 
rfcIP4MacroData(), MacroExpand.DOMAIN));


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to