Skip to content

Bump dom4j to 2.1.5 and keep SAXReader from bypassing Commons Secure XML - #109

Merged
garydgregory merged 2 commits into
apache:masterfrom
ppkarwasz:fix/dom4j-sax-reader
Sep 17, 2026
Merged

garydgregory merged 2 commits into
apache:masterfrom
ppkarwasz:fix/dom4j-sax-reader

Conversation

@ppkarwasz

Copy link
Copy Markdown
Member

Two commits:

  1. Bump dom4j:dom4j 1.6.1 to org.dom4j:dom4j 2.1.5, the last dom4j release that runs on Java 8 (2.2.0 requires Java 11).

  2. Keep dom4j SAXReader from bypassing Commons Secure XML. Unless an EntityResolver is set explicitly, SAXReader.read installs its own resolver, which resolves every external entity to an InputSource carrying only its system ID.

Not addressed here: <xu:assertDocumentsEqual> feeds the documents' XML text into XMLUnit's Diff, which re-parses it with XMLUnit's own JAXP parser, so a DOCTYPE still triggers an external fetch on that path.

🤖 Generated with Claude Code

2.1.5 is the last dom4j release that runs on Java 8; 2.2.0 requires
Java 11.

dom4j 2.x drops the untyped `Stylesheet.run(Object)` and
`applyTemplates(Object, ...)` overloads, so the JSL tag library now
dispatches on the runtime type of its XPath context itself.

The xmlunit and jaxme modules used the released commons-jelly-tags-xml
1.1 as a test dependency, whose POM drags in dom4j:dom4j 1.5 and the XPP
pull parser. The old coordinates are no longer overridden by the new
ones and the XPP JAXP factory rejects secure processing, so both modules
now depend on the in-tree 1.2-SNAPSHOT like the other tag libraries.

Assisted-By: Claude Fable 5.1 <noreply@anthropic.com>
Unless an EntityResolver is set explicitly, `SAXReader.read` installs
its own resolver, which resolves every external entity to an
InputSource carrying only its system ID. The parser then fetches that
system ID, which defeats the ignore-all resolver floor that Commons
Secure XML installs on the XMLReader we hand to dom4j.

Every SAXReader created by the xml and xmlunit tag libraries now gets a
resolver that resolves nothing, so each lookup falls through to that
floor. The three identical factory methods of the xmlunit tags move to
a shared helper in XMLUnitTagSupport.

Both modules gain a regression test that parses a document whose
DOCTYPE points to a DTD that does not exist.

Assisted-By: Claude Fable 5.1 <noreply@anthropic.com>
@garydgregory
garydgregory merged commit f29f66e into apache:master Sep 17, 2026
9 checks passed
@garydgregory

Copy link
Copy Markdown
Member

Thank you @ppkarwasz , merged 🚀

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