[ 
https://issues.apache.org/jira/browse/CAMEL-24580?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18110293#comment-18110293
 ] 

Karol Krawczyk commented on CAMEL-24580:
----------------------------------------

I looked at the scope before writing any code, because the fix cuts very 
differently depending on which comparison paths are included. Everything below 
is measured against current main.

*Current behaviour*

Every all-digit string gets numeric semantics, in both directions:

{noformat}
"0001" == "001"           true
"05"   == "5"             true
"-01"  == "-1"            true
"007"  == 7   (Integer)   true
"007"  == 7L  (Long)      true
"010" <=> "9"             1
{noformat}

*What the test suite already pins*

{{SimpleOperatorTest.testStartsWithTextAsNumeric}} asserts that for a body of 
{{"01234"}}, the predicate {{${in.body} starts with 01234}} is {{false}}: an 
unquoted zero-padded *literal* is normalised to the number 1234. That is 
deliberate and named as such, so literals are out of scope here.

{{SimpleOperatorTest.testLessThanOrEqualOperator}} sets {{dude2 = "0099"}} and 
{{dude = "555"}}, then asserts {{${in.header.dude2} <= ${in.header.dude}}} is 
true. It looks like it pins numeric comparison, but it does not: 
{{"0099".compareTo("555")}} is negative as well, so the assertion holds under 
text semantics too.

So nothing in the suite currently pins String-to-String equality for 
zero-padded values, which is exactly the case reported here.

*Two possible scopes*

1. Narrow. Only when both sides are String values and at least one is not in 
canonical numeric form (leading zero, length > 1), fall back to text 
comparison. This fixes the reported case with no test fallout. It leaves 
{{${header.Account1} == 1}} as true when {{Account1}} is {{"0001"}}.

2. Broad. The same rule also applies to String versus Integer/Long. More 
consistent, but it changes the following, which I measured with {{hour = 
"08"}}, the shape you get from {{${date:now:HH}}}:

{noformat}
${header.hour} == 08      true  ->  would become false
${header.hour} == 8       true  ->  would become false
${header.hour} == '08'    true  ->  stays true
{noformat}

Comparing a zero-padded date or time component against a numeric literal is a 
plausible pattern in real routes, and under the broad scope it would start 
failing silently. There is a migration path ({{== '08'}}), but it is a 
behaviour break rather than a bug fix.

[~ivanra] your report compares two headers against each other. What would you 
expect from {{${header.Account1} == 1}} when {{Account1}} is {{"0001"}}? That 
answer is precisely the line between the two scopes above.

[~davsclaus] which scope would you prefer here, and would you want an upgrade 
guide entry? Unlike CAMEL-24407, which restored behaviour that worked in Camel 
2, this one changes behaviour that has been in place for years, so I would lean 
towards documenting it whichever scope is chosen.

_Reported by Claude Code on behalf of Karol Krawczyk_

> simple predicate always casts digital strings as numbers
> --------------------------------------------------------
>
>                 Key: CAMEL-24580
>                 URL: https://issues.apache.org/jira/browse/CAMEL-24580
>             Project: Camel
>          Issue Type: Bug
>          Components: came-core
>            Reporter: Ivan Ravin
>            Assignee: Karol Krawczyk
>            Priority: Major
>
> Due to this error, strings with leading zeros are compared incorrectly
> {code:java}
> from("timer:test?repeatCount=1&delay=1000")
> .setHeader("Account1").constant("0001")
> .setHeader("Account2").constant("001")
> .filter().simple("${header.Account1} == ${header.Account2}")
>     .log(LoggingLevel.ERROR, "Accounts not equals")
> .end(); {code}



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

Reply via email to