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]
