Federico Mariani created CAMEL-24106:
----------------------------------------

             Summary: camel-xslt: 'source' option silently ignored when the 
message body is an InputStream - transforms the wrong document
                 Key: CAMEL-24106
                 URL: https://issues.apache.org/jira/browse/CAMEL-24106
             Project: Camel
          Issue Type: Bug
          Components: camel-xslt
    Affects Versions: 4.21.0
            Reporter: Federico Mariani
         Attachments: XsltSourceOptionInputStreamBodyTest.java

h3. Problem
{{XmlSourceHandlerFactoryImpl.getSource(Exchange, Expression)}} checks 
{{isInputStreamNeeded(exchange)}} against the *message body* first, and when it 
returns true it reads the body directly and never evaluates the configured 
{{source}} expression:

{code:java}
public Source getSource(Exchange exchange, Expression source) throws Exception {
    if (isInputStreamNeeded(exchange)) {
        InputStream is = exchange.getIn().getBody(InputStream.class);   // <-- 
'source' ignored
        return getSource(exchange, is);
    } else {
        Object body = source != null ? source.evaluate(exchange, Object.class) 
: exchange.getMessage().getBody();
        ...
{code}

{{isInputStreamNeeded()}} returns true when the body is an {{InputStream}}, a 
{{StreamCache}}, or any type without a direct {{Source}} converter - which is 
exactly the common case with {{file}}, {{http}}, {{ftp}}, {{netty}} consumers 
or stream caching. In all those setups {{xslt:...?source=header:x}} / 
{{source=variable:x}} / {{source=property:x}} silently transforms the *body* 
instead of the configured source. No error, wrong output.

h3. Failure scenario
{code:java}
from("direct:start")
    .to("xslt:xslt/transform.xsl?source=header:xmlSource")
    .to("mock:result");

template.send("direct:start", e -> {
    e.getIn().setHeader("xmlSource", 
"<mail><subject>FromHeader</subject>...</mail>");
    e.getIn().setBody(new 
ByteArrayInputStream("<mail><subject>FromBody</subject>...</mail>".getBytes()));
});
// output contains <subject>FromBody</subject> - the header source was never 
looked at
{code}

h3. History
Introduced together with the option itself in CAMEL-21859 (4.12.0). The tests 
added there only exercise header/variable/property sources with a *null* 
message body, which takes the {{else}} branch - hence unnoticed. Affects 
{{xslt}}, {{xslt-saxon}} (handler is inherited by 
{{SaxonXmlSourceHandlerFactoryImpl}}), and {{camel-xj}} in the XML->JSON 
direction (its JSON-input handler evaluates the expression correctly and is 
fine).

h3. Fix direction
Evaluate the {{source}} expression first and only fall back to the 
InputStream-conversion shortcut when no expression is configured (or base 
{{isInputStreamNeeded}} on the evaluated source value instead of the body).

h3. Reproducer
Attached {{XsltSourceOptionInputStreamBodyTest.java}} - two tests, one against 
{{xslt:}} and one against {{xslt-saxon:}}; both fail with output {{FromBody}} 
instead of {{FromHeader}}.
----
_This issue was researched and filed by Claude Code on behalf of [~fmariani] 
(GitHub: Croway), as part of a code review of camel-xslt and camel-xslt-saxon. 
The attached JUnit reproducer fails deterministically on current main 
(4.22.0-SNAPSHOT); place it in 
{{components/camel-xslt-saxon/src/test/java/org/apache/camel/component/xslt/saxon/}}._



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to