ppkarwasz opened a new pull request, #30:
URL: https://github.com/apache/commons-xml/pull/30

   Stacked on #28 (`feature/reduce-shade-footprint`); only the three commits 
above that branch belong to this PR.
   
   ## Why
   
   The deny-all resolver floors rejected every unresolved external reference 
with an exception, so a document that merely carries a DOCTYPE (without needing 
anything from it) failed to parse. Resolving unresolved references to empty 
content keeps the identical security property, nothing is fetched and nothing 
leaks, while letting such documents parse. The ignore outcome is best-effort: 
where an implementation prescribes a rejection (XSLTC and Xalan reject an 
emptied `xsl:import` module at compile time, Xerces treats an entity declared 
in an emptied subset as undeclared and fatal), the block remains an acceptable 
outcome and tests assert "blocks or does not leak".
   
   ## What
   
   1. **Make the resolver floors ignore-all instead of deny-all.** The four 
floors resolve unresolved lookups to empty content and are renamed 
`FallbackDeny*` to `FallbackIgnore*`. The deny/ignore split made several 
variants redundant (`DtdAwareDenyResolver`, `DtdSubsetFloor`, the old 
Woodstox-only `FallbackIgnoreXMLResolver`, `HardeningException.forbidden`); 
removing them takes the shade closure from 33 to 30 classes. The StAX floor 
collapses into the `HardeningXMLInputFactory` constructor, with a single 
`setXMLResolver` covering both the JDK Zephyr and Woodstox.
   2. **Drop `XERCES_LOAD_EXTERNAL_DTD` from the hardening recipes.** Skipping 
the external DTD subset up front is redundant once the floor resolves it to 
empty. Actually requesting the subset exposed two gaps, fixed here: the floors 
now echo the requested identifiers on the empty source they return (Xerces 
derives the entity's base URI from the system id and fails on null), and the 
LSResourceResolver floor hands its content over as a character stream because 
the JDK's `DOMEntityResolverWrapper` discards empty string data.
   3. **Extend the ignore-all floor to Saxon resource resolution.** Saxon's 
`ALLOWED_PROTOCOLS=""` lockdown was the odd one out, rejecting instead of 
ignoring. It is replaced by a nature-aware ignore-all `ResourceResolver` on the 
`HardenedConfiguration` (`EmptySource` for XML/XSLT/XSD natures, an empty 
`StreamSource` for text, `null` for entity/DTD natures so the lookup falls 
through to the hardened reader's floor and caller allow-listing keeps working), 
made non-removable by a `setResourceResolver` override (plain-JAXP 
`TransformerFactory.setURIResolver` replaces the Configuration resolver 
wholesale), plus `CollectionFn.EMPTY_COLLECTION` for `fn:collection`, the one 
channel that bypasses the resolver.
   
   ## Testing
   
   Full surefire matrix green (stock JDK, Xerces, Xalan, Xalan+Xerces, Saxon, 
Saxon+Xerces, Woodstox). Tests that asserted an exception now assert the 
external resource does not leak; where implementations diverge they accept 
either outcome through the `assert*BlocksOrDoesNotLeak` helpers. Saxon now 
passes the DOCTYPE-only and external-DTD suites identically to the other stacks.
   
   🤖 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]

Reply via email to