allthingssecurity opened a new pull request, #26909: URL: https://github.com/apache/camel/pull/26909
# Description [CAMEL-25034](https://issues.apache.org/jira/browse/CAMEL-25034) `convertBodyTo(type, charset)`, `convertHeaderTo(name, type, charset)` and `convertVariableTo(name, type, charset)` pass the configured charset to the type converters through the exchange property `CamelCharsetName`. They set the property, convert, and then restore the old value. This had two problems: 1. The converters read the charset with `ExchangeHelper.getCharsetName`/`getCharset`, where the `CamelCharsetName` **header** takes precedence over the property. When the message has that header, the configured charset is ignored and the value is decoded with the header's charset. The HL7 data format sets the header, and routes set it too: ```java from("direct:conv").convertBodyTo(String.class, "UTF-8"); // body = "café" as UTF-8 bytes, header CamelCharsetName=ISO-8859-1 -> "café" ``` 2. The property was restored only after a successful conversion. When the conversion failed, the configured charset stayed on the exchange, and `onException`, the error handler and the dead letter channel used it for their own conversions. The comment in the processors already says the configured charset should win ("override existing charset with configured charset as that is what the user have explicit configured and expects to be used"), and CAMEL-12279 added the restore of the property. Neither covered the header or a failed conversion. The same code is in 2.x, 3.x and 4.x. This change, in `ConvertBodyProcessor`, `ConvertHeaderProcessor` and `ConvertVariableProcessor`: - If the message has a `CamelCharsetName` header, it is set to the configured charset while the value is converted, the same way as the property. - The header and the property are restored in a `finally` block right after the conversion. The body processor now restores them before it copies the message, so the new message keeps the original header. - Nothing changes without a configured charset. `ExchangeHelper.getCharsetName` is not changed, so the header still takes precedence over the property for all other callers. - Upgrade guide (4.23): a note, because a route whose message carries the header can now decode differently. Tests: `ConvertCharsetTest` checks that `convertBodyTo`, `convertHeaderTo` and `convertVariableTo` to `String` with `UTF-8` decode UTF-8 bytes of `café` correctly when the header is `ISO-8859-1`, and that the header is unchanged afterwards. It also checks that a failing conversion to `Integer` with `UTF-16` leaves the property as it was, both when it was not set and when it was `ISO-8859-1`. Without the main-code change all six tests fail: ``` testConvertBodyWithCharsetHeader mock://result Body of message: 0. Expected: <café> but was: <café> testConvertHeaderWithCharsetHeader mock://result Header with name data for message: 0. Expected: <café> but was: <café> testConvertVariableWithCharsetHeader mock://result Variable with name data for message: 0. Expected: <café> but was: <café> testConvertBodyFailedRestoresCharset exchangeProperty(CamelCharsetName) == ISO-8859-1 evaluated as: UTF-16 == ISO-8859-1 testConvertHeaderFailedRestoresCharset exchangeProperty(CamelCharsetName) is null evaluated as: UTF-16 is null testConvertVariableFailedRestoresCharset exchangeProperty(CamelCharsetName) is null evaluated as: UTF-16 is null ``` With the change, `*Convert*,*Charset*` in camel-core and camel-support pass: 349 tests, 0 failures (2 skipped, as on main). I found this with a Lean model of the processor and the charset lookup. It proves that whenever the header names a different charset, the configured charset is not used, and that every failed conversion leaves the configured charset in the property. It also proves that the other cases (no header, or no configured charset) were already correct, so the change only affects these two cases. I then reproduced the bug against the real classes. Property-based tests (jqwik) fail on main for random Latin-1 text (shrunk to `à`) and for every failing conversion. With this change, all three properties pass: 500 texts with the header, 500 without, and 50 failing conversions. # 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]
