davsclaus opened a new pull request, #28979: URL: https://github.com/apache/camel/pull/28979
Fixes [CAMEL-26498](https://issues.apache.org/jira/browse/CAMEL-26498). Hardening (defence in depth) for SAXSource bodies that a route creates itself. ### What was wrong With stream caching on, `StreamSourceConverter.convertToStreamCache(SAXSource, Exchange)` turns the SAXSource into a String with `XmlConverter` and a `Transformer`. The SAXSource instances that Camel creates (`XmlConverter.toSAXSource` from String, bytes, InputStream, File, Path) carry the secure `XMLReader` from `XMLReaderPool`. A SAXSource with no `XMLReader` (for example `new SAXSource(new InputSource(...))` built in a route) was instead parsed by the default parser of the `TransformerFactory`, so the parser settings depended on the JAXP implementation on the classpath. ### What changed - `StreamSourceConverter.convertToStreamCache(SAXSource, Exchange)`: when `source.getXMLReader() == null`, it wraps the `InputSource` in a new `SAXSource` with the secure `XMLReader` of `XmlConverter` before the transform. Stream caching now parses every SAXSource with the same settings (secure processing, no external general/parameter entities, no external DTD). - `XmlConverter.createXMLReader()`: extracted from `toSAXSourceFromStream`, so both use the same pooled reader from `createSAXParserFactory()`. `StreamSourceConverter` is a static converter and cannot reach the registry's `XmlConverter` instance, so it keeps one static `XmlConverter` (like `DomConverter` keeps its own instance); the factory and pool are created once, not per call. - If the secure reader cannot be created, the conversion now fails instead of falling back to the default parser. ### Tests - `StreamCacheConverterTest.testConvertToStreamCacheSAXSourceWithoutXMLReaderDoesNotExpandExternalEntity`: a SAXSource without an XMLReader whose DOCTYPE declares an external entity pointing to a temp file; converted to `StreamCache` with the type converter (as stream caching does). The cached String is `<test/>` (the secure reader skips the entity). Before the fix it failed: with the JDK `TransformerFactory` the default parser rejected the entity because of Camel's `accessExternalDTD` setting, so stream caching threw a `TypeConversionException`. The test checks that the result no longer depends on the `TransformerFactory`'s parser. - The existing `testConvertToStreamCache` still round-trips a plain SAXSource without an XMLReader. - camel-xml-jaxp: `mvn clean install -Psourcecheck`, 21 tests pass. camel-core: converter, XSLT, validator and stream caching tests (731) pass against the changed camel-xml-jaxp. ### Not changed - `XmlConverter.toSAXSourceFromStream` still logs a WARN and returns a SAXSource without an XMLReader when the SAX parser cannot be created. That converter is used by XSLT, validator and other code beyond stream caching, and throwing there could break routes in an environment where the SAX parser cannot be created but the transformer still works. Such a SAXSource is now parsed with the secure reader when it is stream cached. - No upgrade-guide entry: no working route now fails. With the JDK or Saxon `TransformerFactory`, a reader-less SAXSource with an external entity or DTD failed stream caching before and is now parsed with the entity skipped, like a SAXSource created by Camel's converters. No doc page describes this. _Claude Code on behalf of Claus Ibsen (davsclaus)_ 🤖 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]
