allthingssecurity opened a new pull request, #26977: URL: https://github.com/apache/camel/pull/26977
# Description [CAMEL-25081](https://issues.apache.org/jira/browse/CAMEL-25081) Follow-up to #26908 (CAMEL-25033). Claus asked there to file the comma split as a separate issue and change. When the method option binds parameters from the method name, `MethodInfo.ParameterExpression` takes the text between the outer parentheses and splits it with `StringQuoteHelper.splitSafeQuote(methodParameters, ',', true, true)`. `splitSafeQuote` only knows about quotes, so it also splits at a comma inside a Simple expression, for example between the arguments of an OGNL method call. Each piece is then evaluated as its own Simple expression, which is not closed, and every exchange fails: ```java from("direct:a").bean(MyBean.class, "echo(${body.substring(0, 3)})"); // body abcdef -> SimpleParserException: expected symbol functionEnd but was eol: missing } to close the function from("direct:b").bean(MyBean.class, "two(${body}, ${header.v.replace('a', 'b')})"); // body X, header v = aaa -> same exception (split into 3 pieces) ``` `BeanInfo.matchMethod` splits the same text the same way to select among overloaded methods. With `echo(String)` and `echo(String, String)`, `echo(${body.substring(0, 3)})` is counted as two parameters, the second of which (`3)}`) is not a valid parameter value. Neither method matches, and the call fails with `AmbiguousMethodCallException`. The fix: - `StringQuoteHelper` gets a `splitSafeQuote(input, separator, trim, keepQuotes, nested)` overload. With `nested` enabled it keeps a bracket depth for `(`/`)` and `{`/`}` outside quotes, and only splits at the separator when the depth is 0. A closing bracket without an opening one does not make the depth negative. Nothing else in the loop changes (quotes, empty quotes, trimming, keepQuotes). The existing 4-argument method delegates with `nested = false`, so all other callers (`PropertyBindingSupport`, the Simple functions) are unchanged. - `MethodInfo` (parameter values) and `BeanInfo.matchMethod` (overload selection) use the new overload, so both see the same parameters. - `bean-binding.adoc` says that a comma inside `${ }` is part of the parameter. Only inputs with a comma inside brackets (outside quotes) change. With a Simple expression those failed on every exchange. The one other case is an unquoted literal with a comma inside brackets, such as `two({a, b})`, which used to pass `{a` and `b}` and is now a single parameter. That is not one of the documented parameter forms (a quoted String, a number, `true`/`false`, `null`, a Simple expression or a type), so I did not add an upgrade guide entry. This is the same kind of fix that CAMEL-24967 made for the arguments of Simple functions. The bean parameter parsing was not part of that change. Tests: - `BeanParameterValueWithCommaTest` (camel-core): `echo(${body.substring(0, 3)})` -> `[abc]`; `two(${body}, ${header.v.replace('a', 'b')})` -> `[X|bbb]`; commas in both parameters, `two(${body.substring(1, 3)}, ${body.substring(0, 1)})` -> `[bc|a]`; nested parentheses `${body.substring(0, 4).substring(1, 3)}` and a nested function `${replace(a,z,${header.v})}`; an overloaded bean with `echo(${body.substring(0, 3)})`, `echo(${body.substring(0, 3)}, ${body.substring(3, 5)})` and `echo(String.class ${body.substring(0, 3)})`. Controls that pass on main as well: `echo(${body})`, `two(${body}, ${header.v})`, `echo('a,b')` -> `[a,b]`, `two('a,b', '(c, d)')` and `two(${body}, 'b')`. - `StringQuoteHelperTest` (camel-util): the nested split, brackets inside quotes, stray closing brackets, `trim`/`keepQuotes` combinations, and a test that the 5-argument method with `nested = true` returns exactly the 4-argument result, for all `trim`/`keepQuotes` combinations, on inputs without a comma inside brackets (`${body}, ${header.foo}`, `'a,b', 5`, `*, true`, empty quotes, `a,,b`, and others). Negative control: with the `MethodInfo` and `BeanInfo` changes reverted, 5 of the 6 tests in `BeanParameterValueWithCommaTest` fail with `SimpleParserException: ... missing } to close the function` (only the controls pass). With only the `MethodInfo` change, `testOverloadedMethod` still fails with `AmbiguousMethodCallException`, which is why `BeanInfo` is changed too. With the change, `*Bean*,*MethodInfo*,*Simple*,*StringQuoteHelper*` passes in camel-util (10), camel-bean (9), camel-core (1151, 1 skipped) and camel-console (48): 1218 tests, 0 failures. All camel-util tests (257) and `*PropertyBinding*` in camel-core (73) pass as well. I found this with a Lean model of the parameter split. It shows the two failing inputs above, and proves that the depth-aware split returns exactly what `splitSafeQuote` returns today for every input in which no comma sits inside brackets outside quotes. I then reproduced it against the real classes. A jqwik property over `${body.substring(i, j)}` fails on main for every input. # 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) filed for the change (usually before you start working on it). # 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 built and tested the affected modules, including the formatter and import-sort plugins. 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]
