[ 
https://issues.apache.org/jira/browse/CAMEL-25044?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Claus Ibsen resolved CAMEL-25044.
---------------------------------
    Resolution: Fixed

Merged to main in https://github.com/apache/camel/pull/26924 
(1dd20e7560400ac6a9da2011bbb2161b4dded31e).

_Claude Code on behalf of davsclaus_

> camel-core - ExpressionBuilder and PredicateBuilder: fix bugs found in a deep 
> review
> ------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25044
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25044
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-core
>            Reporter: Claus Ibsen
>            Assignee: Claus Ibsen
>            Priority: Major
>             Fix For: 4.23.0
>
>
> A deep review of ExpressionBuilder, PredicateBuilder and ValueBuilder in 
> camel-support found the bugs below. Each one was reproduced against 
> 4.23.0-SNAPSHOT and has a test that fails without the fix.
> # *{{<}} is true when both sides are null.* {{PredicateBuilder.isLessThan}} 
> returned true for two null values ("they are equal"), where {{>}} returns 
> false. So the Simple predicate {{${header.a} < ${header.b}}} was true when 
> neither header existed. This dates back to 2009; {{<=}} and {{>=}} stay true 
> for two nulls.
> # *PredicateBuilder.language evaluates on an exchange shared by all threads.* 
> It set the body on {{ExchangeHelper.getDummy}}, a single static exchange, so 
> concurrent exchanges read each other's values (about 10% wrong answers with 8 
> threads). It now uses a new exchange for each evaluation, as 
> {{ExpressionBuilder.languageExpression}} does.
> # *A missing variable as the source of a language is a null input.* 
> {{singleInputExpression("variable:name")}} is not mandatory, while 
> {{header:}} and {{property:}} are. Before CAMEL-20378 (4.4) the variable was 
> mandatory, and the refactoring dropped the flag. It now fails with 
> NoSuchVariableException.
> # *{{in(...)}} with a null value never matches a missing value.* 
> {{convertToExpression}} returned the Expression object itself instead of its 
> value when the type is null, so {{header("foo").in("a", null)}} was false 
> without the header, while {{isEqualTo(null)}} is true.
> # *{{${join}}} drops the separators of leading empty elements.* The separator 
> was only added when the result so far was not empty, so {{["", "", "c"]}} 
> joined as {{c}} instead of {{,,c}}.
> # *{{headerExpression(name, byte[].class)}} and {{variableExpression(name, 
> byte[].class)}} always fail.* The type was resolved by its binary name 
> {{[B}}, which the class resolver cannot load. Arrays now use their canonical 
> name {{byte[]}}.
> # *A null constant in an optimized concat is the text "null".* The 
> optimization turned a constant with a null value into "null", while the 
> evaluated path skips null values.
> # *{{ExpressionBuilder.languageExpression(expression, ...)}} does not init 
> its input expression.* Used by the mock component's language expectations; an 
> input that needs init (such as a simple expression) failed with a 
> NullPointerException.
> *Not changed*
> * {{ExchangeHelper.getDummy}} itself: its other callers use it only while 
> routes are created.
> * {{sortExpression}} sorts a List body in place, and {{beanExpression}} 
> creates a new bean expression on every evaluation. Both are long-standing and 
> not wrong results.
> _Claude Code on behalf of Claus Ibsen_



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to