SpEL vararg method invocation fails if string literal contains a comma
See original GitHub issueAffects: 4.1.2 and up
I’m trying to use my own matching functions with spring-expression, but I came across a possible bug.
Here’s some code for context:
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class RuleEvaluationContext extends StandardEvaluationContext {
public RuleEvaluationContext(Object rootObject) {
super(rootObject);
registerFunctions();
}
public RuleEvaluationContext() {
super();
registerFunctions();
}
private void registerFunctions() {
for (Functions fun : Functions.values()) {
this.registerFunction(fun.funcName(), fun.method());
}
}
}
enum Functions {
/* Functions commented for the sake of simplicity
CONTAINS(Contains.FUNC_NAME,
getDeclaredMethod(Contains.class, Contains.FUNC_NAME, String.class, String[].class)),
STARTS_WITH(StartsWith.FUNC_NAME,
getDeclaredMethod(StartsWith.class, StartsWith.FUNC_NAME, String.class, String[].class)),
*/
MATCHES(Matches.FUNC_NAME,
getDeclaredMethod(Matches.class, Matches.FUNC_NAME, String.class, String[].class)),
/*
EQUALS(Equals.FUNC_NAME,
getDeclaredMethod(Equals.class, Equals.FUNC_NAME, String.class, String.class)),
GREATER(GreaterThan.FUNC_NAME,
getDeclaredMethod(GreaterThan.class, GreaterThan.FUNC_NAME, String.class, String.class)),
LESS_THAN(LessThan.FUNC_NAME,
getDeclaredMethod(LessThan.class, LessThan.FUNC_NAME, String.class, String.class));
*/
private final String funcName;
private final Method method;
Functions(String funcName, Method method) {
this.funcName = funcName;
this.method = method;
}
public String funcName() {
return funcName;
}
public Method method() {
return method;
}
private static Method getDeclaredMethod(Class c, String name, Class<?>... parameterTypes) {
try {
return c.getDeclaredMethod(name, parameterTypes);
} catch (NoSuchMethodException e) {
throw new FunctionsException(e);
}
}
}
This is one of the registered functions:
public class Matches {
public static final String FUNC_NAME = "matches";
private Matches() {
super();
}
public static boolean matches(String text, String... regexps) {
if (text != null) {
for (String regex : regexps) {
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
Matcher matcher = pattern.matcher(text);
if (matcher.find()) {
return true;
}
}
}
return false;
}
}
@Test
public void test() {
final RuleEvaluationContext context = new RuleEvaluationContext(new FakeObject());
String originalRule = "#matches(prop, 'xyz,xyz')";
Expression expression = parser.parseExpression(originalRule);
Boolean result = expression.getValue(context, Boolean.class);
assertThat(result, is(false));
}
private final ExpressionParser parser = new SpelExpressionParser();
private static class FakeObject {
private String prop = "xyz";
public String getProp() {
return prop;
}
}
This test fails when it should pass. Upon further inspection I’ve found that the problem is that spring-expression breaks the ‘xyz,xyz’ into [“xyz”, “xyz”] as can be seen below.
However I’ve also found that using old versions of the library (pre 4.1.2), this doesn’t happen.
As does putting more strings inside the argument:
@Test
public void test() {
final RuleEvaluationContext context = new RuleEvaluationContext(new FakeObject());
String originalRule = "#matches(prop, 'abc', 'xyz,xyz')";
Expression expression = parser.parseExpression(originalRule);
Boolean result = expression.getValue(context, Boolean.class);
assertThat(result, is(false));
}
Issue Analytics
- State:
- Created 2 years ago
- Comments:11 (8 by maintainers)
Top Results From Across the Web
Passing varargs to Spring spEL causes "Method cannot be ...
As shown this method takes varargs of String type. It works fine when only one parameter is passed (as on the example above)...
Read more >[GitHub] [maven-indexer] dependabot[bot] opened a new pull ...
... <li>SpEL vararg method invocation fails if string literal contains a comma <a ...
Read more >8. Spring Expression Language (SpEL)
As an example of method invocation, we call the 'concat' method on the string literal. ExpressionParser parser = new SpelExpressionParser(); Expression exp ...
Read more >Spring Security – Access Denied SpEL Changes - Europheus
This is a result of this change in 5.3.13. SpEL vararg method invocation fails if string literal contains a comma #27582 ...
Read more >Mypy Documentation - Read the Docs
These calls will fail when the program run, but mypy does not report an error. # because "greeting" does not have type annotations....
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
I have confirmed that this is a bug which applies to method invocations in general (not just to custom functions).
@bmoraes-axur, feel free to try this out in the next 5.3.13 snapshot and let us know if you run into any issues.