Describe the bug
When you call SearchExpressionHandlerImpl.resolveClientIds(...) with an expression like "@this," that ends with the delimiter the function will call handler.invokeOnComponent(searchExpressionContext, expression, internalCallback); with an empty string leading to a IllegalArgumentException
java.lang.IllegalArgumentException: ""
at jakarta.faces.component.UIComponentBase.findComponent(UIComponentBase.java:371)
at com.sun.faces.component.search.SearchExpressionHandlerImpl.invokeOnComponent(SearchExpressionHandlerImpl.java:294)
at jakarta.faces.component.search.SearchExpressionHandler.invokeOnComponent(SearchExpressionHandler.java:180)
at com.sun.faces.component.search.SearchExpressionHandlerImpl.resolveClientIds(SearchExpressionHandlerImpl.java:109)
The problem lies in function splitExpressions(...) which does not remove trailing separators.
But it does remove leading separators since ",@this" will work as expression, making it inconsistent.
This leads to problems with composite components having optional expressions like <p:commandButton update="@form, #{cc.attrs.update}"/>
To Reproduce
Call the function with expression "@this," or "@this, " (optional space at end)
or using PrimeFaces with below example since PF 14 delegates the ajax client-id resolving to the faces implementation `SearchExpressionHandlerImpl. primefaces/primefaces#14114
<!-- not working - separator at end -->
<p:commandButton update="@this,"/>`
<!-- working - separator at start -->
<p:commandButton update=",@this"/>`
Solution
Fix splitExpression to ignore trailing separators (or empty sub expressions) in the expression argument
or
check the splitted expression inside the loop of resolveClientIds(...) to not be empty, consistent with checking the whole expression before splitting to not be empty.
|
for (String expression : handler.splitExpressions(facesContext, expressions)) { |
// "@this," will split to
if (!expressions.isEmpty()) {
// ["@this", ""] - splitExpressions should only return ["@this"]
for (String expression : handler.splitExpressions(facesContext, expressions)) {
// check single expression to not be empty
if (!expression.trim().isEmpty()) {
if (handler.isPassthroughExpression(searchExpressionContext, expression)) {
internalCallback.addClientId(expression);
} else {
handler.invokeOnComponent(searchExpressionContext, expression, internalCallback);
}
}
}
}
Expected behavior
Ignore empty expressions.
Describe the bug
When you call
SearchExpressionHandlerImpl.resolveClientIds(...)with an expression like"@this,"that ends with the delimiter the function will callhandler.invokeOnComponent(searchExpressionContext, expression, internalCallback);with an empty string leading to aIllegalArgumentExceptionThe problem lies in function
splitExpressions(...)which does not remove trailing separators.But it does remove leading separators since ",@this" will work as expression, making it inconsistent.
This leads to problems with composite components having optional expressions like
<p:commandButton update="@form, #{cc.attrs.update}"/>To Reproduce
Call the function with expression "@this," or "@this, " (optional space at end)
or using PrimeFaces with below example since PF 14 delegates the ajax client-id resolving to the faces implementation `SearchExpressionHandlerImpl. primefaces/primefaces#14114
Solution
Fix
splitExpressionto ignore trailing separators (or empty sub expressions) in the expression argumentor
check the splitted
expressioninside the loop ofresolveClientIds(...)to not be empty, consistent with checking the whole expression before splitting to not be empty.mojarra/impl/src/main/java/com/sun/faces/component/search/SearchExpressionHandlerImpl.java
Line 103 in 932606d
Expected behavior
Ignore empty expressions.