This is an automated email from the ASF dual-hosted git repository.

rmaucher pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit ddb7764886ab0b33dad32417d4597b030052d18e
Author: opencode <[email protected]>
AuthorDate: Sun Oct 18 15:40:28 2026 +0200

    Accept zero varargs elements in EL method expression calls
    
    The argument count check in AstValue.convertArgs, which prepares the
    arguments for a method expression invocation, rejected calls that
    supplied exactly the fixed parameters of a varargs method. A varargs
    method with N parameters accepts N minus 1 arguments, the final
    parameter being supplied by zero or more arguments, but the guard
    required N. Such calls were reported as IllegalArgumentException even
    though the same call written directly in the expression, and the same
    call through the value expression mechanism, both worked. The two
    invocation mechanisms disagreed on valid Java arity.
    
    Reduce the required count by one for varargs methods and report the
    true minimum in the too-few-parameters message. Building the trailing
    varargs array already handles the zero-element case for every
    component type.
    
    Two existing tests relied on the incorrect arity. testBug60844
    asserted the rejected error for a call with one value of the wrong
    type against a method whose minimum arity is one; that call is now
    valid by arity and fails in the argument coercion with an ELException,
    as it would via the value expression mechanism, so the test now uses a
    genuinely too-few call and still pins the reported error.
    testStaticMethodOnInstance asserted the rejection of a call with only
    the format string; the call is valid and the test now asserts the
    correct result. Adds tests for calls with zero and one varargs
    elements.
---
 java/org/apache/el/parser/AstValue.java          |  7 +++--
 test/org/apache/el/TestMethodExpressionImpl.java | 35 ++++++++++++++++++++++--
 test/org/apache/el/util/TestReflectionUtil.java  | 18 ++++++------
 3 files changed, 46 insertions(+), 14 deletions(-)

diff --git a/java/org/apache/el/parser/AstValue.java 
b/java/org/apache/el/parser/AstValue.java
index e0e53e7eeb..55013fab88 100644
--- a/java/org/apache/el/parser/AstValue.java
+++ b/java/org/apache/el/parser/AstValue.java
@@ -278,7 +278,10 @@ public final class AstValue extends SimpleNode {
 
         int paramCount = types.length;
 
-        if (m.isVarArgs() && paramCount > 1 && (src == null || paramCount > 
src.length) ||
+        // For a varargs method, the final parameter may be supplied by zero or
+        // more arguments so the minimum number of arguments is one less than
+        // the number of parameters.
+        if (m.isVarArgs() && paramCount > 1 && (src == null || paramCount - 1 
> src.length) ||
                 !m.isVarArgs() && (src == null || src.length != paramCount)) {
             String srcCount = null;
             if (src != null) {
@@ -287,7 +290,7 @@ public final class AstValue extends SimpleNode {
             String msg;
             if (m.isVarArgs()) {
                 msg = MessageFactory.get("error.invoke.tooFewParams", 
m.getName(), srcCount,
-                        Integer.toString(paramCount));
+                        Integer.toString(paramCount - 1));
             } else {
                 msg = MessageFactory.get("error.invoke.wrongParams", 
m.getName(), srcCount,
                         Integer.toString(paramCount));
diff --git a/test/org/apache/el/TestMethodExpressionImpl.java 
b/test/org/apache/el/TestMethodExpressionImpl.java
index 0701725a81..50844b14b1 100644
--- a/test/org/apache/el/TestMethodExpressionImpl.java
+++ b/test/org/apache/el/TestMethodExpressionImpl.java
@@ -492,9 +492,13 @@ public class TestMethodExpressionImpl {
 
     @Test(expected = IllegalArgumentException.class)
     public void testBug60844() {
+        // Fewer parameter values than the minimum required by a varargs
+        // method (here, the fixed parameters only). A single value would be
+        // a valid number of arguments for this method, so the call below
+        // with no values is the too-few-parameters case.
         MethodExpression me2 = factory.createMethodExpression(context, 
"${beanC.sayHello}", null,
-                new Class[] { TesterBeanA.class, TesterBeanB.class });
-        me2.invoke(context, new Object[] { new Object() });
+                new Class[] { TesterBeanA.class });
+        me2.invoke(context, new Object[] { });
     }
 
 
@@ -721,6 +725,33 @@ public class TestMethodExpressionImpl {
     }
 
 
+    @Test
+    public void testVarArgsZeroVarArgsElements() {
+        // A call that supplies only the fixed parameters of a varargs method
+        // is valid Java. The method expression mechanism must accept it, as
+        // the value expression mechanism already does.
+        context.getVariableMapper().setVariable("beanH",
+                factory.createValueExpression(new TesterBeanH(), 
TesterBeanH.class));
+
+        MethodExpression me = factory.createMethodExpression(context, 
"${beanH.doTest}", String.class,
+                new Class<?>[] { String.class });
+
+        Assert.assertEquals("String-VString", me.invoke(context, new Object[] 
{ "apple" }));
+    }
+
+
+    @Test
+    public void testVarArgsOneVarArgsElement() {
+        context.getVariableMapper().setVariable("beanH",
+                factory.createValueExpression(new TesterBeanH(), 
TesterBeanH.class));
+
+        MethodExpression me = factory.createMethodExpression(context, 
"${beanH.doTest}", String.class,
+                new Class<?>[] { String.class, String.class });
+
+        Assert.assertEquals("String-VString", me.invoke(context, new Object[] 
{ "apple", "apple" }));
+    }
+
+
     @Test
     public void testGetMethodInfo01() throws Exception {
         MethodExpression me = factory.createMethodExpression(context, 
"#{beanA.setName('New value')}", null, null);
diff --git a/test/org/apache/el/util/TestReflectionUtil.java 
b/test/org/apache/el/util/TestReflectionUtil.java
index 4362fc255e..ee194ea7da 100644
--- a/test/org/apache/el/util/TestReflectionUtil.java
+++ b/test/org/apache/el/util/TestReflectionUtil.java
@@ -72,16 +72,14 @@ public class TestReflectionUtil {
         ExpressionFactory factory = ExpressionFactory.newInstance();
         ELContext context = new ELContextImpl(factory);
 
-        MethodExpression methodExpression = 
factory.createMethodExpression(context, "${\"1\".format(2)}", String.class, new 
Class<?>[] {});
+        MethodExpression methodExpression = 
factory.createMethodExpression(context, "${\"1\".format(2)}", String.class,
+                new Class<?>[] {});
 
-        try {
-            methodExpression.invoke(context, null);
-        } catch (IllegalArgumentException iae) {
-            // Ensure correct IllegalArgumentException is thrown
-            String msg = iae.getMessage();
-            Assert.assertTrue(msg, msg.contains("[format]"));
-            return;
-        }
-        Assert.fail("No exception");
+        // The static method format(String,Object...) must be resolvable and
+        // invocable when called on an instance. The single argument is the
+        // format string. No varargs elements are provided which is valid.
+        Object result = methodExpression.invoke(context, null);
+
+        Assert.assertEquals("2", result);
     }
 }


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

Reply via email to