shashank created CAMEL-25904:
--------------------------------
Summary: camel-beanio - BeanIOSplitter reads a file with the
default charset of the JVM and ignores its encoding, so a file consumed with
charset=ISO-8859-1 is split with its non-ASCII characters replaced
Key: CAMEL-25904
URL: https://issues.apache.org/jira/browse/CAMEL-25904
Project: Camel
Issue Type: Bug
Components: camel-beanio
Reporter: shashank
Assignee: shashank
{{BeanIOSplitter.evaluate}} (main 74ee085f7d64, lines 79-107) creates the
BeanIO reader like this:
{code:java}
if (body instanceof WrappedFile wrappedfile) {
body = wrappedfile.getFile();
}
if (body instanceof File file) {
beanReader = factory.createReader(getStreamName(), file);
}
if (beanReader == null) {
Reader reader = msg.getMandatoryBody(Reader.class);
beanReader = factory.createReader(getStreamName(), reader);
}
{code}
BeanIO's {{StreamFactory.createReader(String, File)}} (beanio 3.2.1) opens the
file with a {{FileReader}}, that is with the default charset of the JVM. Other
bodies (byte array, stream) are converted to a {{Reader}} with the charset of
the exchange, else the default charset. The {{encoding}} option of the splitter
({{setEncoding}}, kept in its {{BeanIOConfiguration}}) is never read.
The usual route for big files is a file consumer and the streaming splitter,
and the file body is always a {{File}}:
{code:java}
from("file:in?charset=ISO-8859-1")
.split(beanIOSplitter).streaming()
.to("direct:record");
{code}
The {{charset}} of the file consumer is ignored, and so is
{{beanIOSplitter.setEncoding(StandardCharsets.ISO_8859_1)}}: an ISO-8859-1 or
windows-1252 file (the typical encoding of the legacy fixed-length and CSV
files BeanIO is used for) is decoded as UTF-8 on Java 18+, and every non-ASCII
character of the records becomes U+FFFD ({{Jörg Müller}} -> {{J?rg M?ller}}).
The split completes without an error. CAMEL-12284 fixed the same for
{{BeanIODataFormat}} (its encoding option did not work); the splitter was added
later (CAMEL-9843) and has never used it.
*Fix*: {{BeanIOSplitter}} decodes a file, stream or byte array body itself,
with the charset of the exchange ({{CamelCharsetName}} header or property, as
set by the {{charset}} option of the file consumer), else with its {{encoding}}
(default: the default charset of the JVM, as before). A {{String}} or
{{Reader}} body is read as before. The reader is closed if BeanIO cannot create
its reader (an unknown stream name). Upgrade note in the 4.24 guide.
*Tests*: new {{BeanIOSplitterEncodingTest}} (4 tests, ISO-8859-1 data with ö,
ü, é, ß). On main, 3 fail with {{expected: <[Jörg Müller Développeur, Renée
Straße Architect]> but was: <[J?rg M?ller D?veloppeur, Ren?e Stra?e
Architect]>}} (U+FFFD shown as ?): {{fileIsReadWithTheEncodingOfTheSplitter}}
(a {{File}} body, {{setEncoding(ISO_8859_1)}}),
{{fileFromTheFileConsumerIsReadWithItsCharset}} (a real file consumer with
{{charset=ISO-8859-1}}), {{bytesAreReadWithTheEncodingOfTheSplitter}}.
{{bytesAreReadWithTheCharsetOfTheExchange}} passes on main and with the fix
(control: that path already used the exchange charset). camel-beanio unit
tests: 25 run, 0 failures.
*How it was found*: a sweep of the data formats and their streaming splitters
for options that one code path does not use (here the {{File}} branch hands the
file to a library method without a charset). The JUnit tests above are the
evidence.
*Affected*: main, camel-4.23.x, camel-4.22.x, camel-4.18.x and camel-4.14.x
(the same {{createReader(getStreamName(), file)}}; read, not run).
Not changed, possible follow-up: {{BeanIOIterator}} reads the first record in
its constructor, before {{evaluate}} sets the error handler on the reader, so
the {{ignoreInvalidRecords}} / {{ignoreUnexpectedRecords}} / custom
{{BeanReaderErrorHandler}} options do not apply to the first record (an invalid
first record fails the split, loudly).
_Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)