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]

Reply via email to