shashank created CAMEL-25726:
--------------------------------
Summary: camel-azure-files - the producer creates the file with
the size from a stale CamelFileLength header, so a body the route made shorter
is stored with zero bytes at its end
Key: CAMEL-25726
URL: https://issues.apache.org/jira/browse/CAMEL-25726
Project: Camel
Issue Type: Bug
Components: camel-azure
Reporter: shashank
Assignee: shashank
The Azure Files producer creates the remote file with its final size and then
writes the body into it ({{FilesOperations.storeFile}}, main 826a664c5f16,
lines 486-497 and 508). When a {{CamelFileLength}} header is present, its value
is used as that size, whatever the body is:
{code:java}
var knownLength = exchange.getIn().getHeader(Exchange.FILE_LENGTH, Long.class);
if (knownLength != null) {
is = exchange.getIn().getMandatoryBody(InputStream.class);
length = knownLength.intValue();
{code}
Every file-family consumer (file, ftp, sftp, smb, azure-files) sets
{{CamelFileLength}} to the length of the consumed file, and the header stays on
the message when the route changes the body. So a route like
{code:java}
from("file:in").split(body().tokenize("\n")).to("azure-files://account/share/dir?fileName=${exchangeId}.txt&...");
{code}
(or a transform / marshal / enrich between the two) creates each Azure file
with the size of the whole input file and writes only the shorter body: the
stored file ends with zero bytes, and the exchange completes normally. A body
longer than the header fails at the write past the end of the file (read, not
run). The header is also narrowed with {{intValue()}}.
CAMEL-25167 made the same choice for the other file / object-storage producers:
their length helper {{PayloadHelper.getBodyLength}} "deliberately" does not use
{{CamelFileLength}}, "as it can be stale once the route changed the body".
camel-azure-files was not part of that change.
The component page says the producer is "optimized for" an {{InputStream}} with
{{CamelFileLength}} set, and for {{byte[]}}; it does not say that the header
also overrides the length of a {{byte[]}} or {{String}} body.
h3. Reproduction
New {{FilesOperationsStoreLengthTest}} (mocked {{ShareDirectoryClient}} /
{{ShareFileClient}}, no Azure service): {{storeFile}} with a 3-byte body and
{{CamelFileLength=10}} must create a 3-byte file; with a 20-character String
body and {{CamelFileLength=10}} a 20-byte file. On main the file is created
with 10 bytes in both ({{expected: <3> but was: <10>}}, {{expected: <20> but
was: <10>}}, 3 of 3 runs). A third test (a stream of unknown length with a
correct header is streamed with the header length) passes on main and with the
fix; it guards the documented streaming case.
h3. Proposed fix
The size is the length of the body when it is known without reading it
({{PayloadHelper.getBodyLength}}: a file or wrapped file, {{byte[]}}, a cached
stream, a byte-array or file stream); a body that is not a stream is converted
to {{byte[]}}; {{CamelFileLength}} is only used for a stream whose length
cannot be known otherwise, as documented. The size is passed as a {{long}}.
Upgrade note in the 4.24 guide and a paragraph on the component page.
With the fix the camel-azure-files tests pass: 31 run, 0 failures, 0 errors, 0
skipped.
Not changed: {{storeFileDirectly}} writes {{payload.getBytes()}} in the
platform charset (possible follow-up).
Affected: main (tested); camel-4.23.x, camel-4.22.x and camel-4.18.x have the
same code (read, not run).
Duplicate check (2026-10-17): JIRA text "azure-files" with "length" / "size" /
"zero": only CAMEL-25167 (other components); GitHub pull requests "azure-files
length", "FilesOperations": none about this.
_Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)