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]

Reply via email to