shashank created CAMEL-26329:
--------------------------------

             Summary: camel-support - Simple == compares a number and a numeric 
String as text when they are written differently: ${header.amount} == '10' is 
false for a BigDecimal 10.00 while <= and >= are true
                 Key: CAMEL-26329
                 URL: https://issues.apache.org/jira/browse/CAMEL-26329
             Project: Camel
          Issue Type: Bug
          Components: camel-core
            Reporter: shashank
            Assignee: shashank


Since CAMEL-25013 (4.23.0) the Simple comparison operators compare two numbers, 
or a number and a numeric String, by their values, and the 4.23 upgrade guide 
entry lists "a number compared with a numeric {{String}}" among them (its 
examples include {{==}}). {{ObjectHelper.typeCoerceCompare}} does that, but 
{{typeCoerceEquals}} only got the number/number case. For a number and a 
numeric String that are not written the same way, {{==}} still converts the 
String to the type of the number and uses {{equals}} ({{BigDecimal.equals}} 
also compares the scale), or converts the number to a String and compares the 
text. So {{==}} and {{!=}} disagree with {{<=}} and {{>=}} (main aa63c0a4cb94):

{code}
amount = BigDecimal 10.00 (for example a DECIMAL(10,2) column read with 
camel-sql)
${header.amount} <= '10'    true
${header.amount} >= '10'    true
${header.amount} == '10'    false
${header.amount} == ${header.s}  false, for a String header s = "10"

text = String "10.00"
${header.text} == 10        false   (<= and >= are true)

count = Integer 3
${header.count} == '3.0'    false
${header.count} in '3.0'    true    (in compares the values since CAMEL-25013)
{code}

The {{==}} result is the same in older versions; since 4.23 it disagrees with 
the other operators, which compare the values.

{{simple-operators.adoc}} shows {{simple("$\{header.bar} == '100'")}} as the 
way to compare a header with a number, so a {{choice()}} on a BigDecimal amount 
with a scale takes the wrong branch without an error. The same happens for 
{{Integer}}, {{Long}}, {{Short}} and {{BigInteger}} values compared with 
{{'1e1'}} or {{' 10'}} (with spaces). A {{Double}} or {{Float}} is not 
affected, because the String is converted to a double first.

*Fix* (proposed): in {{typeCoerceEquals}}, when one side is a number other than 
a double or float and the other side is a String that parses as a 
{{BigDecimal}} (ignoring leading and trailing spaces, as the {{in}} operator 
does), compare them with the same {{compareNumbers}} that {{typeCoerceCompare}} 
uses. {{typeCoerceCompare}} parses the String the same way, so {{<}} and {{>}} 
with {{" 9007199254740992"}} or {{1e0}} are exact and no longer compared as 
doubles. The text is checked to have the form of a number before it is parsed 
(so text such as {{-}} or {{2026-10-26}} is not handed to the BigDecimal 
parser), and text longer than 1000 characters is not parsed: parsing a 
BigDecimal takes time that grows with the square of the number of digits (a 
million digits take about 12 s). Text that is not a number, null, two Strings, 
and doubles are unchanged. A 4.24 upgrade guide entry describes the change, as 
{{==}} and {{!=}} give different results than in 4.23 for these values (also 
{{=~}}, {{contains}} on a collection, and the Java DSL and mock predicates).

*Tests*: {{TypeCoerceCompareTest}} (4 new methods) and 
{{SimpleOperatorTest.testEqualsNumberWithNumericTextWrittenDifferently}} fail 
on main and pass with the change. A differential fuzz harness of the Simple 
numeric operators (5 million inputs, typed headers vs quoted, unquoted and 
header right sides, compared with the comparison of the values) found 1,829 
wrong results on main, all {{==}}/{{!=}} of a number and a numeric String 
written differently; with the change there are none, and no other input changes 
its result.

*How it was found*: a fuzz harness that checks the Simple comparison operators 
against each other ({{==}} must agree with {{<=}} and {{>=}} both being true) 
on 5 million generated number and text pairs, run on HotSpot; all 1 829 
disagreements came from this one cause, and none remains with the fix.

*Affected*: 4.23.0 and main. The fix builds on the value comparison of 
CAMEL-25013, which the older branches do not have, so this follow-up is for 
main only.

_Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to