Skip to content

COMMONSXML-8: Base TransformerFactory and XPathFactory hardening on feature support - #17

Merged
garydgregory merged 3 commits into
apache:mainfrom
ppkarwasz:feature/transformer-feature-based-hardening
Jul 6, 2026
Merged

COMMONSXML-8: Base TransformerFactory and XPathFactory hardening on feature support#17
garydgregory merged 3 commits into
apache:mainfrom
ppkarwasz:feature/transformer-feature-based-hardening

Conversation

@ppkarwasz

Copy link
Copy Markdown
Member

JIRA: https://issues.apache.org/jira/browse/COMMONSXML-8

Applies the capability-driven approach of COMMONSXML-1 to the last two paths, TrAX and XPath, with Saxon kept as the single documented class-name exception (a locked-down Configuration, handled by the unchanged SaxonProvider). StockJdkProvider and XalanProvider are removed, and the two hardeners are named after the product (TransformerHardener, XPathHardener) to match DocumentBuilderHardener and SAXParserHardener.

One change is worth noting on the TrAX path:

  • ACCESS_EXTERNAL_STYLESHEET is dropped in favor of the deny-all URIResolver, which already blocks the same channel (xsl:import/xsl:include, document()) uniformly across XSLTC and Xalan.
  • ACCESS_EXTERNAL_DTD could not be dropped. The JDK XSLTC copies this factory attribute onto the reader it uses to parse the stylesheet (Util.getInputSource), overwriting the value our hardened reader had set, so it is required there; Xalan rejects it and is covered by the hardened reader instead.

ppkarwasz added 3 commits July 6, 2026 12:05
Replace the class-name dispatch(TransformerFactory) switch with a
capability-driven TransformerHardener, mirroring the DOM and SAX
hardeners. It probes what the factory supports rather than branching per
vendor, keeping a single documented class-name exception for Saxon, whose
hardening (a Configuration that closes every resource-resolution channel
plus the extension-function surface) is reachable only through a vendor API.

Stock JDK XSLTC and Apache Xalan now share one recipe: FSP, best-effort
limits and ACCESS_EXTERNAL_* (defense-in-depth where honoured), a deny-all
URIResolver as the required block for xsl:import/xsl:include and document(),
and a HardeningTransformerFactory wrapper. XSLTC previously relied on
ACCESS_EXTERNAL_STYLESHEET as its required block and Xalan on the resolver;
both now use the resolver, so ACCESS_EXTERNAL_* drops to best-effort. Both
block paths surface as TransformerException, already accepted by the tests.

Supporting changes: JaxpSetters gains setOptionalAttribute(TransformerFactory)
and loses the now-unused strict setAttribute overload; Limits.applyToJdkTransformer
becomes best-effort tryApply(TransformerFactory); StockJdkProvider and
XalanProvider drop their configure(TransformerFactory) recipes (SaxonProvider
is unchanged, still shared with XPath).

Assisted-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the class-name dispatch(XPathFactory) switch with a capability-driven
XPathHardener, mirroring TransformerHardener. The XPath object model splits the
same way as TrAX: the stock JDK and Apache Xalan ship an XPath 1.0 engine with
no URI-fetching functions, while Saxon adds the XPath 3.1 fn:doc, fn:collection
and fn:unparsed-text functions. So it keeps one documented class-name exception
for Saxon (net.sf.saxon plus the com.saxonica.config Professional/Enterprise
editions, which subclass the open-source XPathFactoryImpl), handed to
SaxonProvider for a locked-down Configuration; every other engine gets FSP
(required) and best-effort FODP (stock JDK pins its bundled parser, Xalan
rejects it).

The two capability-driven hardeners are named after the product rather than the
factory, matching DocumentBuilderHardener and SAXParserHardener.

Supporting changes: JaxpSetters gains setOptionalFeature(XPathFactory);
StockJdkProvider and XalanProvider are removed, since configure(XPathFactory)
was their last remaining recipe (SaxonProvider is unchanged, shared with TrAX).

Assisted-By: Claude Opus 4.8 <noreply@anthropic.com>
@ppkarwasz
ppkarwasz requested a review from garydgregory July 6, 2026 12:52
@garydgregory
garydgregory merged commit a8dbc70 into apache:main Jul 6, 2026
15 checks passed
@garydgregory

Copy link
Copy Markdown
Member

Thank you @ppkarwasz , merged 🚀

@ppkarwasz
ppkarwasz deleted the feature/transformer-feature-based-hardening branch July 6, 2026 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants