This is an automated email from the ASF dual-hosted git repository. markt-asf pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 6c3ae6cf4cb1caabb7f19e1f27a861ed97a0de91 Author: Mark Thomas <[email protected]> AuthorDate: Tue Nov 10 17:44:05 2026 +0000 Improve search of existing methods when defining functions --- java/javax/el/ELProcessor.java | 2 +- test/javax/el/TestELProcessor.java | 154 +++++++++++++++++++++++++++++++++++++ test/javax/el/TesterFunctions.java | 4 + webapps/docs/changelog.xml | 8 ++ 4 files changed, 167 insertions(+), 1 deletion(-) diff --git a/java/javax/el/ELProcessor.java b/java/javax/el/ELProcessor.java index 15afc9920e..e9611af413 100644 --- a/java/javax/el/ELProcessor.java +++ b/java/javax/el/ELProcessor.java @@ -239,7 +239,7 @@ public class ELProcessor { if (paramString.length() == 0) { parameterTypeNames = EMPTY_STRING_ARRAY; } else { - parameterTypeNames = paramString.split(","); + parameterTypeNames = paramString.split(",", -1); ImportHandler importHandler = context.getImportHandler(); for (int i = 0; i < parameterTypeNames.length; i++) { String parameterTypeName = JreCompat.getInstance().strip(parameterTypeNames[i]); diff --git a/test/javax/el/TestELProcessor.java b/test/javax/el/TestELProcessor.java index b46cbe68ab..c88da850d5 100644 --- a/test/javax/el/TestELProcessor.java +++ b/test/javax/el/TestELProcessor.java @@ -190,6 +190,160 @@ public class TestELProcessor { } + /* + * Tests based on https://github.com/jakartaee/expression-language/issues/492 and variants. + */ + + private void doDefineFunctionSignature(String function, String signature, String expectedName, String expr, + String expectedCalls) throws Exception { + TesterFunctions.resetCallList(); + ELProcessor elp = new ELProcessor(); + elp.defineFunction("fn", function, "jakarta.el.TesterFunctions", signature); + Assert.assertNotNull( + elp.getELManager().getELContext().getFunctionMapper().resolveFunction("fn", expectedName)); + elp.eval(expr); + Assert.assertEquals(expectedCalls, TesterFunctions.getCallList()); + } + + + @Test + public void testDefineFunctionNoParams01() throws Exception { + doDefineFunctionSignature("test", "void doIt()", "test", "fn:test()", "A"); + } + + + @Test + public void testDefineFunctionNoParams02() throws Exception { + doDefineFunctionSignature("test", "void doIt( )", "test", "fn:test()", "A"); + } + + + @Test + public void testDefineFunctionTwoParamsWithSpace() throws Exception { + doDefineFunctionSignature("test", "void doIt(int, int)", "test", "fn:test(1,2)", "J"); + } + + + @Test + public void testDefineFunctionTwoParamsNoSpace() throws Exception { + doDefineFunctionSignature("test", "void doIt(int,int)", "test", "fn:test(1,2)", "J"); + } + + + @Test + public void testDefineFunctionTwoParamsExtraSpace() throws Exception { + doDefineFunctionSignature("test", "void doIt( int , int )", "test", "fn:test(1,2)", "J"); + } + + + @Test + public void testDefineFunctionTwoParamsTab() throws Exception { + doDefineFunctionSignature("test", "void doIt(int,\tint)", "test", "fn:test(1,2)", "J"); + } + + + @Test + public void testDefineFunctionEmptyNameNoParams() throws Exception { + doDefineFunctionSignature("", "void doIt()", "doIt", "fn:doIt()", "A"); + } + + + @Test + public void testDefineFunctionEmptyNameTwoParams() throws Exception { + doDefineFunctionSignature("", "void doIt(int,int)", "doIt", "fn:doIt(1,2)", "J"); + } + + + @Test + public void testDefineFunctionEmptyNameTwoParamsWithSpace() throws Exception { + doDefineFunctionSignature("", "void doIt(int, int)", "doIt", "fn:doIt(1,2)", "J"); + } + + + @Test + public void testDefineFunctionLeadingTrailingSpace() throws Exception { + doDefineFunctionSignature("", " void doIt ( int , int ) ", "doIt", "fn:doIt(1,2)", "J"); + } + + + @Test + public void testDefineFunctionArraySpaceBetweenBrackets() throws Exception { + doDefineFunctionSignature("test", "void doIt(Integer[] [])", "test", "fn:test([[1].stream().toArray()].stream().toArray())", "G"); + } + + + @Test + public void testDefineFunctionVarArgsWithSpace() throws Exception { + doDefineFunctionSignature("test", "void doIt( long ... )", "test", "fn:test(1,2)", "H"); + } + + + private void doDefineFunctionInvalidSignature(String signature) { + ELProcessor elp = new ELProcessor(); + try { + elp.defineFunction("fn", "test", "jakarta.el.TesterFunctions", signature); + } catch (ClassNotFoundException | NoSuchMethodException e) { + // Expected + return; + } + Assert.fail("Invalid signature [" + signature + "] was accepted"); + } + + + @Test + public void testDefineFunctionInvalidTrailingComma() { + doDefineFunctionInvalidSignature("void doIt(int,)"); + } + + + @Test + public void testDefineFunctionInvalidTrailingCommaSpace() { + doDefineFunctionInvalidSignature("void doIt(int, )"); + } + + + @Test + public void testDefineFunctionInvalidLeadingComma() { + doDefineFunctionInvalidSignature("void doIt(,int)"); + } + + + @Test + public void testDefineFunctionInvalidOnlyComma() { + doDefineFunctionInvalidSignature("void doIt(,)"); + } + + + @Test + public void testDefineFunctionInvalidDoubleComma() { + doDefineFunctionInvalidSignature("void doIt(int,,int)"); + } + + + @Test + public void testDefineFunctionInvalidTrailingCommaTwoParams() { + doDefineFunctionInvalidSignature("void doIt(int,int,)"); + } + + + @Test + public void testDefineFunctionInvalidMissingCloseParen() { + doDefineFunctionInvalidSignature("void doIt(int,int"); + } + + + @Test + public void testDefineFunctionInvalidMissingReturnType() { + doDefineFunctionInvalidSignature("doIt(int,int)"); + } + + + @Test + public void testDefineFunctionInvalidUnknownType() { + doDefineFunctionInvalidSignature("void doIt(int,NoSuchType)"); + } + + @Test public void testPrimitiveArray01() { ELProcessor elp = new ELProcessor(); diff --git a/test/javax/el/TesterFunctions.java b/test/javax/el/TesterFunctions.java index 565a49587d..c406c5ccbe 100644 --- a/test/javax/el/TesterFunctions.java +++ b/test/javax/el/TesterFunctions.java @@ -63,4 +63,8 @@ public class TesterFunctions { public static void doIt(@SuppressWarnings("unused") Object... a) { calls.append('I'); } + + public static void doIt(@SuppressWarnings("unused") int a, @SuppressWarnings("unused") int b) { + calls.append('J'); + } } diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index dfa4a23496..a4a325a347 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -108,6 +108,14 @@ issues do not "pop up" wrt. others). --> <section name="Tomcat 9.0.125 (remm)" rtext="in development"> + <subsection name="Jasper"> + <changelog> + <fix> + Improve search of existing methods when defining functions using an + <code>ELProcressor</code>. (markt) + </fix> + </changelog> + </subsection> </section> <section name="Tomcat 9.0.124 (remm)" rtext="release in progress"> <subsection name="General"> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
