[
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)