allthingssecurity opened a new pull request, #28712:
URL: https://github.com/apache/camel/pull/28712

   # Description
   
   [CAMEL-26307](https://issues.apache.org/jira/browse/CAMEL-26307)
   
   The easy JSONPath syntax (`store.book.price < 20`, rewritten by 
`EasyPredicateParser` into `$.store.book[?(@.price < 20)]`) found the operator 
with `EasyPredicateOperators.getOperatorAtStart`, which returned the first 
operator of its list (`==, !=, <, <=, >, >=, =~, in, nin, size, empty`) that 
the text started with. For ` <= 10` that was `<`, and the parser then skipped 
the `=` as if it were the space after the operator:
   
   ```
   price <= 10                -> $..*[?(@.price <  10)]     (expected <=)
   store.book.price >= 8.95   -> $.store.book[?(@.price >  8.95)]
   price <20                  -> $..*[?(@.price < 0)]      (the first digit 
skipped)
   ```
   
   So `choice().when().jsonpath("store.book.price >= 100")` did not match a 
book of price 100, without an error. The operators were also looked for inside 
quoted values (and `in` inside words), so `store.book.title == 'Java in 
Action'` was split at ` in`, not rewritten, and failed as a path ("Use bracket 
notion ['my prop'] if your property contains blank characters").
   
   Changes:
   - `getOperatorAtStart` returns the longest operator the text starts with; a 
word operator (`in`, `nin`, `size`, `empty`) only when a space or the end 
follows it.
   - `EasyPredicateParser.tokens` skips the operator and the one space after it 
(if there is one), and does not look for operators inside a single- or 
double-quoted value.
   - Predicates with one space around a single operator other than `<=` and 
`>=`, with no operator word in the value, are rewritten exactly as before. 
Other inputs that change (all were rewritten wrongly before): a predicate 
without a space after the operator keeps its value whole (`price <20` -> 
`$..*[?(@.price < 20)]`, was `< 0`); a word operator followed by something 
other than a space is not an operator (`store.book.title =~ /.* index/` is now 
rewritten into a filter; `store.book.isbn index 3` is no longer rewritten into 
a filter with `in ex 3`, and `category in['x']` is left as is instead of 
becoming `in 'x'])`); a `$`-rooted path whose only operator word is inside a 
quoted key (`$.store.book[0]['check in']`) is no longer turned into a broken 
filter. No option or default changes; no upgrade guide entry.
   - Backport candidates, for the maintainers to label if wanted (contributors 
cannot set `port/*` labels): camel-4.22.x and 4.18.x have the same 
`getOperatorAtStart` and `tokens` (read, not run). The two production files of 
this commit apply to them cleanly (merge-tree); the commit as a whole does not, 
because `EasyPredicateParserTest` was added on main by CAMEL-24841, and the 
`$`-rooted predicates in the new tests (`$.store.book.price >= 10`, `$.status 
== 'a == b'`, `$.store.book.price >= 8.95`) need CAMEL-24841 too.
   
   Tests:
   - `EasyPredicateParserTest`: three new methods (`<=`, `>=`, `nin`, no space 
after the operator; operator words inside a quoted value; ` index` in a regex 
value is not the operator `in`).
   - New `EasyJsonPathComparisonOperatorsTest` (4 tests): a choice with `<=` 
and `>=` on the boundary value of `cheap.json`, and a title with `in`, matching 
and not matching.
   - The 7 new tests fail on main and pass with the change. camel-jsonpath: 140 
tests, 0 failures. Run offline on main as of e4c4dbbeb5da (2026-10-20, the date 
of the local snapshot jars of the core modules; the easy predicate classes and 
tests are the same as on the base of this branch); the formatter and 
import-sort plugins ran and changed nothing.
   
   How it was found: an OSS-Fuzz-style differential harness (random JSON 
documents and easy predicates evaluated through the jsonpath language, compared 
with the same comparison done in Java) run on HotSpot: of 50 000 random 
predicates (about half numeric, half string equality), 426 `<=` / `>=` 
predicates that only a price equal to the value satisfies were false, and 5 543 
string predicates with an operator word in the value threw. With this change 
200 000 inputs agree. A JVM model in Rocq that executes the real class files 
states the operator choice as kernel-checked theorems on the class files of 
main and of this change (`main_le_read_as_lt`: ` <= 10` gives `<`, ` >= 10` 
gives `>`, ` index` gives `in`; `fix_le_read_as_le`); HotSpot gives the same 
results for the same class files.
   
   # Target
   
   - [x] I checked that the commit is targeting the correct branch (Camel 4 
uses the `main` branch)
   
   # Tracking
   - [x] If this is a large change, bug fix, or code improvement, I checked 
there is a [JIRA issue](https://issues.apache.org/jira/browse/CAMEL-26307) 
filed for the change (usually before you start working on it): 
[CAMEL-26307](https://issues.apache.org/jira/browse/CAMEL-26307).
   
   # Apache Camel coding standards and style
   
   - [x] I checked that each commit in the pull request has a meaningful 
subject line and body.
   - [ ] I have run `mvn clean install -DskipTests` locally from root folder 
and I have committed all auto-generated changes.
     (I ran the camel-jsonpath tests above with the formatter and import-sort 
plugins; no generated files are affected. I did not run the full root build.)
   
   # AI-assisted contributions
   
   - [x] If this PR includes AI-generated code, commits have proper 
co-authorship attribution (e.g., `Co-authored-by` trailers) and the PR 
description identifies the AI tool used.
     This PR was prepared with Claude Code (Claude Opus 5.5). The commit 
carries a `Co-Authored-By` trailer.
   
   _Claude Code on behalf of allthingssecurity_
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to