This is an automated email from the ASF dual-hosted git repository. garydgregory pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/commons-xml.git
commit 74cc919eb0f2180f0b03a833b8b537b6cf5c00b3 Author: Gary Gregory <[email protected]> AuthorDate: Fri Aug 28 13:15:51 2026 -0400 Rename HardeningSAXParserFactory to SecureSAXParserFactory. --- .../commons/xml/FallbackIgnoreURIResolver.java | 4 +-- .../org/apache/commons/xml/HardeningSchema.java | 4 +-- .../apache/commons/xml/HardeningSchemaFactory.java | 14 ++++---- .../org/apache/commons/xml/HardeningTemplates.java | 2 +- .../commons/xml/HardeningTemplatesHandler.java | 2 +- .../apache/commons/xml/HardeningTransformer.java | 6 ++-- .../commons/xml/HardeningTransformerFactory.java | 30 ++++++++--------- .../org/apache/commons/xml/HardeningValidator.java | 6 ++-- .../org/apache/commons/xml/HardeningXMLFilter.java | 2 +- .../apache/commons/xml/HardeningXPathFactory.java | 4 +-- .../java/org/apache/commons/xml/SaxonProvider.java | 4 +-- .../commons/xml/SecureDocumentBuilderFactory.java | 2 +- .../org/apache/commons/xml/SecureSAXParser.java | 2 +- ...serFactory.java => SecureSAXParserFactory.java} | 6 ++-- src/site/markdown/index.md | 2 +- .../org/apache/commons/xml/AttackTestSupport.java | 26 +++++++-------- .../commons/xml/EntityResolverFloorTest.java | 6 ++-- .../commons/xml/HardeningFactoriesSmokeTest.java | 20 ++++++------ .../commons/xml/OverrideDefaultParserTest.java | 8 ++--- .../org/apache/commons/xml/ResetHardeningTest.java | 2 +- .../apache/commons/xml/SaxSurfaceTestSupport.java | 2 +- .../commons/xml/SchemaLocationPropertyTest.java | 2 +- .../apache/commons/xml/SchemaLocationSaxTest.java | 2 +- .../apache/commons/xml/ShadingFootprintTest.java | 38 +++++++++++----------- .../xml/UnsupportedXmlImplementationTest.java | 2 +- .../java/org/apache/commons/xml/XIncludeTest.java | 16 ++++----- 26 files changed, 107 insertions(+), 107 deletions(-) diff --git a/src/main/java/org/apache/commons/xml/FallbackIgnoreURIResolver.java b/src/main/java/org/apache/commons/xml/FallbackIgnoreURIResolver.java index 1c5a3b5..26bdd92 100644 --- a/src/main/java/org/apache/commons/xml/FallbackIgnoreURIResolver.java +++ b/src/main/java/org/apache/commons/xml/FallbackIgnoreURIResolver.java @@ -88,7 +88,7 @@ private static Document newEmptyDocument() { /** * Whether the opted-in rewrite should use the pluggable parser lookup instead of the platform's built-in parser; read per resolution so the factory-level floor tracks a later - * {@value HardeningSAXParserFactory#OVERRIDE_DEFAULT_PARSER} toggle. + * {@value SecureSAXParserFactory#OVERRIDE_DEFAULT_PARSER} toggle. */ private final BooleanSupplier overrideDefaultParser; @@ -125,7 +125,7 @@ public Source resolve(final String href, final String base) throws TransformerEx final Source resolved = delegate != null ? delegate.resolve(href, base) : null; if (resolved != null) { // The implementation parses the opted-in handle with an internal reader at its own defaults; the rewrite hands it a hardened reader instead. - return HardeningSAXParserFactory.harden(resolved, overrideDefaultParser.getAsBoolean()); + return SecureSAXParserFactory.harden(resolved, overrideDefaultParser.getAsBoolean()); } if (SecureException.throwOnUnresolved()) { throw new TransformerException(SecureException.forbidden("uri", null, null, href, base)); diff --git a/src/main/java/org/apache/commons/xml/HardeningSchema.java b/src/main/java/org/apache/commons/xml/HardeningSchema.java index 19385d9..981ec17 100644 --- a/src/main/java/org/apache/commons/xml/HardeningSchema.java +++ b/src/main/java/org/apache/commons/xml/HardeningSchema.java @@ -25,7 +25,7 @@ /** * {@link Schema} wrapper that hardens every {@link Validator} and {@link ValidatorHandler} the inner Schema produces: each {@link Validator} is wrapped in - * {@link HardeningValidator} (which rewrites the Source through {@link HardeningSAXParserFactory#harden(javax.xml.transform.Source, boolean)} and installs the resolver + * {@link HardeningValidator} (which rewrites the Source through {@link SecureSAXParserFactory#harden(javax.xml.transform.Source, boolean)} and installs the resolver * floor), and each {@link ValidatorHandler} is wrapped in a {@link HardeningValidatorHandler} that keeps the same ignore-all resolver floor so * {@code xsi:schemaLocation} is not resolved during SAX-driven validation. */ @@ -34,7 +34,7 @@ final class HardeningSchema extends Schema { private final Schema delegate; /** - * Snapshot of the factory's {@value HardeningSAXParserFactory#OVERRIDE_DEFAULT_PARSER} outcome, carried onto every produced Validator. + * Snapshot of the factory's {@value SecureSAXParserFactory#OVERRIDE_DEFAULT_PARSER} outcome, carried onto every produced Validator. */ final boolean overrideDefaultParser; diff --git a/src/main/java/org/apache/commons/xml/HardeningSchemaFactory.java b/src/main/java/org/apache/commons/xml/HardeningSchemaFactory.java index 8732bdb..0117779 100644 --- a/src/main/java/org/apache/commons/xml/HardeningSchemaFactory.java +++ b/src/main/java/org/apache/commons/xml/HardeningSchemaFactory.java @@ -70,7 +70,7 @@ public final class HardeningSchemaFactory { * <p>Unlike the other factory types there is no per-implementation branching and no feature or limit configuration on the factory itself: schema compilation * and validation reach external resources only through the resolver hook, so wrapping the factory with a non-removable ignore-all resolver floor is enough on * every implementation. The reader used to parse schema and instance documents is hardened separately, through - * {@link HardeningSAXParserFactory#harden(javax.xml.transform.Source, boolean)}.</p> + * {@link SecureSAXParserFactory#harden(javax.xml.transform.Source, boolean)}.</p> * * @param factory the factory to harden; never {@code null}. * @return a hardened factory. @@ -150,14 +150,14 @@ private HardeningSchemaFactory() { * <ol> * <li>{@link HardeningSchemaFactory} installs an ignore-all {@link FallbackIgnoreLSResourceResolver} floor on the factory (blocking * {@code xs:import}/{@code xs:include}/{@code xs:redefine} at compile time) and rewrites the Source on every {@code newSchema(Source[])} entry point - * through {@link HardeningSAXParserFactory#harden(Source, boolean)}.</li> + * through {@link SecureSAXParserFactory#harden(Source, boolean)}.</li> * <li>{@link HardeningSchema} wraps every Validator/ValidatorHandler the inner Schema produces and re-installs the floor on each (blocking * {@code xsi:schemaLocation} at validation time), since neither the JDK nor Xerces reliably propagates it through {@code Schema}.</li> * <li>{@link HardeningValidator} rewrites the Source on every {@link Validator#validate(Source)} call.</li> * </ol> * * <p> - * The hardened reader supplied by {@link HardeningSAXParserFactory#harden(Source, boolean)} already carries {@code FEATURE_SECURE_PROCESSING} and the processing limits, so a + * The hardened reader supplied by {@link SecureSAXParserFactory#harden(Source, boolean)} already carries {@code FEATURE_SECURE_PROCESSING} and the processing limits, so a * DOCTYPE, external entity or Billion Laughs payload in the schema or instance document is bounded there rather than on this factory. The JAXP 1.5 * {@code ACCESS_EXTERNAL_*} properties are deliberately not set: the resolver floor already blocks the same fetches on every implementation, and the JDK 8 * {@code SchemaFactory} has a bug whereby those properties keep blocking even when a caller's own resolver would grant the access. The floor is a non-removable @@ -170,7 +170,7 @@ private HardeningSchemaFactory() { private static final class Wrapper extends SchemaFactory { /** - * Hardens every schema source through {@link HardeningSAXParserFactory#harden(Source, boolean)}. + * Hardens every schema source through {@link SecureSAXParserFactory#harden(Source, boolean)}. * * @param schemas the schema sources to harden; must not be {@code null}. * @return a new array of hardened sources. @@ -183,7 +183,7 @@ private Source[] harden(final Source[] schemas) throws SAXException { final boolean overrideDefaultParser = overrideDefaultParser(); try { for (int i = 0; i < schemas.length; i++) { - hardened[i] = HardeningSAXParserFactory.harden(schemas[i], overrideDefaultParser); + hardened[i] = SecureSAXParserFactory.harden(schemas[i], overrideDefaultParser); } } catch (final TransformerConfigurationException e) { throw new SAXException("Failed to harden schema source", e); @@ -252,14 +252,14 @@ public Schema newSchema(final Source[] schemas) throws SAXException { /** * Checks whether parsers should be instantiated via {@code newInstance()} instead of {@code newDefaultInstance()}. * - * <p>The JDK implementation of {@link SchemaFactory} uses the JDK parsers while {@value HardeningSAXParserFactory#OVERRIDE_DEFAULT_PARSER} is unset or + * <p>The JDK implementation of {@link SchemaFactory} uses the JDK parsers while {@value SecureSAXParserFactory#OVERRIDE_DEFAULT_PARSER} is unset or * {@code false}.</p> * * @return {@code true} if parsers should be created via {@code newInstance()}. */ private boolean overrideDefaultParser() { try { - return delegate.getFeature(HardeningSAXParserFactory.OVERRIDE_DEFAULT_PARSER); + return delegate.getFeature(SecureSAXParserFactory.OVERRIDE_DEFAULT_PARSER); } catch (final SAXNotRecognizedException | SAXNotSupportedException e) { return true; } diff --git a/src/main/java/org/apache/commons/xml/HardeningTemplates.java b/src/main/java/org/apache/commons/xml/HardeningTemplates.java index 8aa0fa7..3b1a2fa 100644 --- a/src/main/java/org/apache/commons/xml/HardeningTemplates.java +++ b/src/main/java/org/apache/commons/xml/HardeningTemplates.java @@ -52,7 +52,7 @@ final class HardeningTemplates implements Templates { private final Supplier<Source> emptySource; /** - * Snapshot of the factory's {@value HardeningSAXParserFactory#OVERRIDE_DEFAULT_PARSER} outcome, carried onto every produced Transformer and self-provisioned + * Snapshot of the factory's {@value SecureSAXParserFactory#OVERRIDE_DEFAULT_PARSER} outcome, carried onto every produced Transformer and self-provisioned * filter reader. */ final boolean overrideDefaultParser; diff --git a/src/main/java/org/apache/commons/xml/HardeningTemplatesHandler.java b/src/main/java/org/apache/commons/xml/HardeningTemplatesHandler.java index 537d2ad..33d3126 100644 --- a/src/main/java/org/apache/commons/xml/HardeningTemplatesHandler.java +++ b/src/main/java/org/apache/commons/xml/HardeningTemplatesHandler.java @@ -52,7 +52,7 @@ final class HardeningTemplatesHandler implements TemplatesHandler { private final Supplier<Source> emptySource; /** - * Snapshot of the factory's {@value HardeningSAXParserFactory#OVERRIDE_DEFAULT_PARSER} outcome, carried onto the produced Templates. + * Snapshot of the factory's {@value SecureSAXParserFactory#OVERRIDE_DEFAULT_PARSER} outcome, carried onto the produced Templates. */ private final boolean overrideDefaultParser; diff --git a/src/main/java/org/apache/commons/xml/HardeningTransformer.java b/src/main/java/org/apache/commons/xml/HardeningTransformer.java index 2229168..6c07703 100644 --- a/src/main/java/org/apache/commons/xml/HardeningTransformer.java +++ b/src/main/java/org/apache/commons/xml/HardeningTransformer.java @@ -32,7 +32,7 @@ /** * {@link Transformer} wrapper that rewrites the Source on every {@link Transformer#transform(Source, Result)} call through - * {@link HardeningSAXParserFactory#harden(Source, boolean)} before delegating, and keeps an ignore-all {@link URIResolver} floor so runtime {@code document()} calls a + * {@link SecureSAXParserFactory#harden(Source, boolean)} before delegating, and keeps an ignore-all {@link URIResolver} floor so runtime {@code document()} calls a * caller does not resolve return empty rather than being fetched. * <p> * The floor is installed on the delegate transformer at construction, seeded with the factory's compile-time resolver; {@link #setURIResolver(URIResolver)} @@ -52,7 +52,7 @@ final class HardeningTransformer extends Transformer { private final FallbackIgnoreURIResolver floor; /** - * Snapshot of the factory's {@value HardeningSAXParserFactory#OVERRIDE_DEFAULT_PARSER} outcome at creation, like the JDK copies the feature onto the + * Snapshot of the factory's {@value SecureSAXParserFactory#OVERRIDE_DEFAULT_PARSER} outcome at creation, like the JDK copies the feature onto the * transformers it creates. */ private final boolean overrideDefaultParser; @@ -145,7 +145,7 @@ public void setURIResolver(final URIResolver resolver) { @Override public void transform(final Source xmlSource, final Result outputTarget) throws TransformerException { try { - delegate.transform(HardeningSAXParserFactory.harden(xmlSource, overrideDefaultParser), outputTarget); + delegate.transform(SecureSAXParserFactory.harden(xmlSource, overrideDefaultParser), outputTarget); } catch (final TransformerConfigurationException e) { throw new TransformerException(e); } diff --git a/src/main/java/org/apache/commons/xml/HardeningTransformerFactory.java b/src/main/java/org/apache/commons/xml/HardeningTransformerFactory.java index c54a0d3..a840c7f 100644 --- a/src/main/java/org/apache/commons/xml/HardeningTransformerFactory.java +++ b/src/main/java/org/apache/commons/xml/HardeningTransformerFactory.java @@ -185,7 +185,7 @@ private HardeningTransformerFactory() { } /** - * {@link TransformerFactory} wrapper that rewrites every Source-taking entry point through {@link HardeningSAXParserFactory#harden(Source, boolean)} before + * {@link TransformerFactory} wrapper that rewrites every Source-taking entry point through {@link SecureSAXParserFactory#harden(Source, boolean)} before * delegating. * * <p>Used by providers whose underlying TrAX implementation pulls a new {@code SAXParserFactory.newInstance()} for any Source that is not already a @@ -209,7 +209,7 @@ private HardeningTransformerFactory() { * <h2>Caveats</h2> * <ul> * <li>A {@link SAXSource} that carries its own {@link XMLReader} is trusted as-is: the caller is expected to supply a hardened reader (via - * {@link HardeningSAXParserFactory#newInstance()}) in that case. The same applies to the SAX events a caller feeds into a handler, and to a parent reader a + * {@link SecureSAXParserFactory#newInstance()}) in that case. The same applies to the SAX events a caller feeds into a handler, and to a parent reader a * caller sets on a returned {@link XMLFilter}.</li> * </ul> * @@ -220,10 +220,10 @@ private static final class Wrapper extends SAXTransformerFactory { /** * Parses a reader-less source into a DOM through a hardened, namespace-aware {@link javax.xml.parsers.DocumentBuilder} and returns a {@link DOMSource} * carrying its system id, so the consumer walks the tree instead of provisioning its own reader. Any other source is left to - * {@link HardeningSAXParserFactory#harden(Source, boolean)}. + * {@link SecureSAXParserFactory#harden(Source, boolean)}. * * @param source The source to scan for an associated stylesheet. - * @return A {@link DOMSource} for a reader-less source, otherwise the result of {@link HardeningSAXParserFactory#harden(Source, boolean)}. + * @return A {@link DOMSource} for a reader-less source, otherwise the result of {@link SecureSAXParserFactory#harden(Source, boolean)}. * @throws TransformerConfigurationException if the source cannot be parsed. * @throws FactoryConfigurationError Thrown from a factory in case of a {@link java.util.ServiceConfigurationError service * configuration error} or if the implementation is not available or cannot be instantiated. @@ -242,7 +242,7 @@ private Source hardenSourceToDom(final Source source) throws TransformerConfigur } } } - return HardeningSAXParserFactory.harden(source, overrideDefaultParser()); + return SecureSAXParserFactory.harden(source, overrideDefaultParser()); } /** @@ -256,7 +256,7 @@ private static boolean isXalan(final SAXTransformerFactory factory) { } /** - * Whether the delegate recognizes {@value HardeningSAXParserFactory#OVERRIDE_DEFAULT_PARSER}, probed with a same-value {@code setFeature}: + * Whether the delegate recognizes {@value SecureSAXParserFactory#OVERRIDE_DEFAULT_PARSER}, probed with a same-value {@code setFeature}: * {@code TransformerFactory.getFeature} cannot signal an unrecognized name (it returns {@code false}), while every implementation rejects a * {@code setFeature} for a name it does not support (Xalan with {@link TransformerConfigurationException}, Saxon with its own unchecked exception). * @@ -265,8 +265,8 @@ private static boolean isXalan(final SAXTransformerFactory factory) { */ private static boolean probeOverrideDefaultParser(final SAXTransformerFactory factory) { try { - factory.setFeature(HardeningSAXParserFactory.OVERRIDE_DEFAULT_PARSER, - factory.getFeature(HardeningSAXParserFactory.OVERRIDE_DEFAULT_PARSER)); + factory.setFeature(SecureSAXParserFactory.OVERRIDE_DEFAULT_PARSER, + factory.getFeature(SecureSAXParserFactory.OVERRIDE_DEFAULT_PARSER)); return true; } catch (final Exception e) { return false; @@ -286,7 +286,7 @@ private static Templates unwrap(final Templates templates) { private final FallbackIgnoreURIResolver floor; - /** Whether the delegate recognizes {@value HardeningSAXParserFactory#OVERRIDE_DEFAULT_PARSER}; its value is read per created product, like the JDK. */ + /** Whether the delegate recognizes {@value SecureSAXParserFactory#OVERRIDE_DEFAULT_PARSER}; its value is read per created product, like the JDK. */ private final boolean supportsOverrideDefaultParser; /** @@ -326,7 +326,7 @@ private Wrapper(final SAXTransformerFactory delegate, final Supplier<Source> emp public Source getAssociatedStylesheet(final Source source, final String media, final String title, final String charset) throws TransformerConfigurationException { // Xalan's getAssociatedStylesheet drops a SAXSource's reader and self-provisions its own to scan for xml-stylesheet PIs (XALANJ-2849). - final Source hardened = isXalan(delegate) ? hardenSourceToDom(source) : HardeningSAXParserFactory.harden(source, overrideDefaultParser()); + final Source hardened = isXalan(delegate) ? hardenSourceToDom(source) : SecureSAXParserFactory.harden(source, overrideDefaultParser()); return delegate.getAssociatedStylesheet(hardened, media, title, charset); } @@ -362,7 +362,7 @@ private TransformerHandler hardenHandler(final TransformerHandler handler) { */ @Override public Templates newTemplates(final Source source) throws TransformerConfigurationException { - final Templates templates = delegate.newTemplates(HardeningSAXParserFactory.harden(source, overrideDefaultParser())); + final Templates templates = delegate.newTemplates(SecureSAXParserFactory.harden(source, overrideDefaultParser())); return templates == null ? null : new HardeningTemplates(templates, getURIResolver(), emptySource, overrideDefaultParser()); } @@ -387,7 +387,7 @@ public Transformer newTransformer() throws TransformerConfigurationException { */ @Override public Transformer newTransformer(final Source source) throws TransformerConfigurationException { - final Transformer transformer = delegate.newTransformer(HardeningSAXParserFactory.harden(source, overrideDefaultParser())); + final Transformer transformer = delegate.newTransformer(SecureSAXParserFactory.harden(source, overrideDefaultParser())); return transformer == null ? null : new HardeningTransformer(transformer, getURIResolver(), emptySource, overrideDefaultParser()); } @@ -404,7 +404,7 @@ public TransformerHandler newTransformerHandler() throws TransformerConfiguratio */ @Override public TransformerHandler newTransformerHandler(final Source source) throws TransformerConfigurationException { - return hardenHandler(delegate.newTransformerHandler(HardeningSAXParserFactory.harden(source, overrideDefaultParser()))); + return hardenHandler(delegate.newTransformerHandler(SecureSAXParserFactory.harden(source, overrideDefaultParser()))); } @Override @@ -455,13 +455,13 @@ public void setURIResolver(final URIResolver resolver) { /** * Checks whether parsers should be instantiated via {@code newInstance()} instead of {@code newDefaultInstance()}. * - * <p>The JDK implementation of {@link TransformerFactory} uses the JDK parsers while {@value HardeningSAXParserFactory#OVERRIDE_DEFAULT_PARSER} is unset + * <p>The JDK implementation of {@link TransformerFactory} uses the JDK parsers while {@value SecureSAXParserFactory#OVERRIDE_DEFAULT_PARSER} is unset * or {@code false}.</p> * * @return {@code true} if parsers should be created via {@code newInstance()}. */ private boolean overrideDefaultParser() { - return !supportsOverrideDefaultParser || delegate.getFeature(HardeningSAXParserFactory.OVERRIDE_DEFAULT_PARSER); + return !supportsOverrideDefaultParser || delegate.getFeature(SecureSAXParserFactory.OVERRIDE_DEFAULT_PARSER); } } } diff --git a/src/main/java/org/apache/commons/xml/HardeningValidator.java b/src/main/java/org/apache/commons/xml/HardeningValidator.java index d6a3416..bab0002 100644 --- a/src/main/java/org/apache/commons/xml/HardeningValidator.java +++ b/src/main/java/org/apache/commons/xml/HardeningValidator.java @@ -34,7 +34,7 @@ /** * {@link Validator} wrapper that rewrites the Source on every {@link Validator#validate(Source)} and {@link Validator#validate(Source, Result)} call through - * {@link HardeningSAXParserFactory#harden(Source, boolean)} before delegating, and keeps an ignore-all {@link LSResourceResolver} floor so {@code xsi:schemaLocation} is not resolved at + * {@link SecureSAXParserFactory#harden(Source, boolean)} before delegating, and keeps an ignore-all {@link LSResourceResolver} floor so {@code xsi:schemaLocation} is not resolved at * validation time. {@link #reset()} re-establishes the bare ignore-all floor, matching the just-constructed state. */ final class HardeningValidator extends Validator { @@ -44,7 +44,7 @@ final class HardeningValidator extends Validator { private final FallbackIgnoreLSResourceResolver floor = new FallbackIgnoreLSResourceResolver(null); /** - * Snapshot of the factory's {@value HardeningSAXParserFactory#OVERRIDE_DEFAULT_PARSER} outcome at creation, like the JDK copies the feature onto its + * Snapshot of the factory's {@value SecureSAXParserFactory#OVERRIDE_DEFAULT_PARSER} outcome at creation, like the JDK copies the feature onto its * validators. */ private final boolean overrideDefaultParser; @@ -121,7 +121,7 @@ public void setResourceResolver(final LSResourceResolver resourceResolver) { @Override public void validate(final Source source, final Result result) throws SAXException, IOException { try { - delegate.validate(HardeningSAXParserFactory.harden(source, overrideDefaultParser), result); + delegate.validate(SecureSAXParserFactory.harden(source, overrideDefaultParser), result); } catch (final TransformerConfigurationException e) { throw new SAXException("Failed to harden source for validation", e); } diff --git a/src/main/java/org/apache/commons/xml/HardeningXMLFilter.java b/src/main/java/org/apache/commons/xml/HardeningXMLFilter.java index a72179b..903459e 100644 --- a/src/main/java/org/apache/commons/xml/HardeningXMLFilter.java +++ b/src/main/java/org/apache/commons/xml/HardeningXMLFilter.java @@ -70,7 +70,7 @@ public void parse(final InputSource input) throws SAXException, IOException { } if (getParent() == null) { try { - setParent(HardeningSAXParserFactory.newHardenedReader(templates.overrideDefaultParser)); + setParent(SecureSAXParserFactory.newHardenedReader(templates.overrideDefaultParser)); } catch (final TransformerException e) { throw new SAXException(e); } diff --git a/src/main/java/org/apache/commons/xml/HardeningXPathFactory.java b/src/main/java/org/apache/commons/xml/HardeningXPathFactory.java index 2d41f28..be13953 100644 --- a/src/main/java/org/apache/commons/xml/HardeningXPathFactory.java +++ b/src/main/java/org/apache/commons/xml/HardeningXPathFactory.java @@ -233,14 +233,14 @@ public void setFeature(final String name, final boolean value) throws XPathFacto /** * Checks whether parsers should be instantiated via {@code newInstance()} instead of {@code newDefaultInstance()}. * - * <p>The JDK implementation of {@link XPathFactory} uses the JDK parsers while {@value HardeningSAXParserFactory#OVERRIDE_DEFAULT_PARSER} is unset or + * <p>The JDK implementation of {@link XPathFactory} uses the JDK parsers while {@value SecureSAXParserFactory#OVERRIDE_DEFAULT_PARSER} is unset or * {@code false}.</p> * * @return {@code true} if parsers should be created via {@code newInstance()}. */ private boolean overrideDefaultParser() { try { - return delegate.getFeature(HardeningSAXParserFactory.OVERRIDE_DEFAULT_PARSER); + return delegate.getFeature(SecureSAXParserFactory.OVERRIDE_DEFAULT_PARSER); } catch (final XPathFactoryConfigurationException e) { return true; } diff --git a/src/main/java/org/apache/commons/xml/SaxonProvider.java b/src/main/java/org/apache/commons/xml/SaxonProvider.java index edd9b59..757b807 100644 --- a/src/main/java/org/apache/commons/xml/SaxonProvider.java +++ b/src/main/java/org/apache/commons/xml/SaxonProvider.java @@ -52,7 +52,7 @@ final class SaxonProvider { * * <ol> * <li><b>SAX layer.</b> {@link #makeParser} hands every {@link XMLReader} Saxon would otherwise use through - * {@link HardeningSAXParserFactory#harden(XMLReader)}, which routes it to the matching bundled hardening recipe. External DTDs, entities and XInclude + * {@link SecureSAXParserFactory#harden(XMLReader)}, which routes it to the matching bundled hardening recipe. External DTDs, entities and XInclude * resolve to empty content at parse time.</li> * <li><b>Collection layer.</b> {@code fn:collection} bypasses the resource resolver and fetches directly, so an empty {@link CollectionFinder} supplies its * ignore outcome instead.</li> @@ -87,7 +87,7 @@ private HardenedConfiguration() { @Override public XMLReader makeParser(final String className) throws TransformerFactoryConfigurationError { try { - return HardeningSAXParserFactory.harden(super.makeParser(className)); + return SecureSAXParserFactory.harden(super.makeParser(className)); } catch (final SecureException e) { throw new TransformerFactoryConfigurationError(e); } diff --git a/src/main/java/org/apache/commons/xml/SecureDocumentBuilderFactory.java b/src/main/java/org/apache/commons/xml/SecureDocumentBuilderFactory.java index d4942ed..9c2b6b6 100644 --- a/src/main/java/org/apache/commons/xml/SecureDocumentBuilderFactory.java +++ b/src/main/java/org/apache/commons/xml/SecureDocumentBuilderFactory.java @@ -194,7 +194,7 @@ public static DocumentBuilderFactory newNSInstance() { * reconfiguring the default parser, so it is honored through the standard lookup rather than bypassed. * </p> * - * @param overrideDefaultParser whether {@value HardeningSAXParserFactory#OVERRIDE_DEFAULT_PARSER} on the originating factory asks to override the JDK's default parser. + * @param overrideDefaultParser whether {@value SecureSAXParserFactory#OVERRIDE_DEFAULT_PARSER} on the originating factory asks to override the JDK's default parser. * @return A hardened, namespace-aware factory. * @throws IllegalStateException Thrown if a required hardening setting cannot be applied to the underlying implementation. * @throws FactoryConfigurationError Thrown from a factory in case of a {@link java.util.ServiceConfigurationError service configuration error} or if the diff --git a/src/main/java/org/apache/commons/xml/SecureSAXParser.java b/src/main/java/org/apache/commons/xml/SecureSAXParser.java index 8fb08c4..3bde1b2 100644 --- a/src/main/java/org/apache/commons/xml/SecureSAXParser.java +++ b/src/main/java/org/apache/commons/xml/SecureSAXParser.java @@ -81,7 +81,7 @@ public Schema getSchema() { @Override public XMLReader getXMLReader() throws SAXException { if (hardenedReader == null) { - hardenedReader = HardeningSAXParserFactory.harden(delegate.getXMLReader()); + hardenedReader = SecureSAXParserFactory.harden(delegate.getXMLReader()); } return hardenedReader; } diff --git a/src/main/java/org/apache/commons/xml/HardeningSAXParserFactory.java b/src/main/java/org/apache/commons/xml/SecureSAXParserFactory.java similarity index 99% rename from src/main/java/org/apache/commons/xml/HardeningSAXParserFactory.java rename to src/main/java/org/apache/commons/xml/SecureSAXParserFactory.java index 7c09f04..b3bd2f6 100644 --- a/src/main/java/org/apache/commons/xml/HardeningSAXParserFactory.java +++ b/src/main/java/org/apache/commons/xml/SecureSAXParserFactory.java @@ -54,7 +54,7 @@ * * @see org.apache.commons.xml */ -public final class HardeningSAXParserFactory { +public final class SecureSAXParserFactory { /** Class name of Android's Expat-backed {@link XMLReader}. */ private static final String ANDROID_EXPAT_READER = "org.apache.harmony.xml.ExpatReader"; @@ -313,7 +313,7 @@ private static void setFeature(final XMLReader reader, final String feature, fin } } - private HardeningSAXParserFactory() { + private SecureSAXParserFactory() { // static only } @@ -343,7 +343,7 @@ public void setFeature(final String name, final boolean value) throws SAXNotReco } /** - * Universal SAX factory wrapper that funnels every produced parser through {@link HardeningSAXParserFactory#harden(XMLReader)}. + * Universal SAX factory wrapper that funnels every produced parser through {@link SecureSAXParserFactory#harden(XMLReader)}. * <p> * {@link SAXParserFactory} exposes only a feature API and no property API, so the per-parse hardening (limits, entity blocking, implementation-specific fixups) * has to run on each {@link XMLReader} the factory produces. This wrapper returns a {@link SecureSAXParser}, which applies that hardening lazily to both the diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md index 0ea9d70..8c1c0ee 100644 --- a/src/site/markdown/index.md +++ b/src/site/markdown/index.md @@ -95,7 +95,7 @@ Document doc = HardeningDocumentBuilderFactory.newInstance().newDocumentBuilder( **SAX parsing** via `SAXParserFactory`: ```java -import org.apache.commons.xml.HardeningSAXParserFactory; +import org.apache.commons.xml.SecureSAXParserFactory; HardeningSAXParserFactory.newInstance().newSAXParser().parse(inputStream, myDefaultHandler); ``` diff --git a/src/test/java/org/apache/commons/xml/AttackTestSupport.java b/src/test/java/org/apache/commons/xml/AttackTestSupport.java index dbeb17d..d802a2f 100644 --- a/src/test/java/org/apache/commons/xml/AttackTestSupport.java +++ b/src/test/java/org/apache/commons/xml/AttackTestSupport.java @@ -91,7 +91,7 @@ final class AttackTestSupport { /** - * Test-only permissive counterpart of {@code HardeningSAXParserFactory.HardeningExpatXMLReader}: a pass-through Expat wrapper that rejects the + * Test-only permissive counterpart of {@code SecureSAXParserFactory.HardeningExpatXMLReader}: a pass-through Expat wrapper that rejects the * {@code namespace-prefixes} feature eagerly (so a probing TrAX identity transformer falls back instead of failing the whole parse) but installs no ignore-all * resolver floor, so the unconfigured/positive controls stay permissive. */ @@ -444,36 +444,36 @@ static void assertPermissiveValidatorValidates(final String xml) { /** * Asserts a hardened SAX parse of the payload throws. * - * <p>{@link XMLReader#parse(InputSource)} on a parser from {@link HardeningSAXParserFactory#newInstance()}; only a thrown exception passes.</p> + * <p>{@link XMLReader#parse(InputSource)} on a parser from {@link SecureSAXParserFactory#newInstance()}; only a thrown exception passes.</p> */ static void assertSaxBlocks(final String payload) { - assertParseFails(() -> consumeXmlReader(strictXMLReader(HardeningSAXParserFactory.newInstance()), payload), "SAX", SAXException.class); + assertParseFails(() -> consumeXmlReader(strictXMLReader(SecureSAXParserFactory.newInstance()), payload), "SAX", SAXException.class); } /** * Asserts a hardened SAX parse either blocks at parse or completes without leaked content. See {@link #assertDomBlocksOrDoesNotLeak(String)}. */ static void assertSaxBlocksOrDoesNotLeak(final String payload) { - assertNoLeakOrThrows(() -> captureCharacters(strictXMLReader(HardeningSAXParserFactory.newInstance()), payload), "SAX", SAXException.class); + assertNoLeakOrThrows(() -> captureCharacters(strictXMLReader(SecureSAXParserFactory.newInstance()), payload), "SAX", SAXException.class); } /** * Asserts a hardened SAX parse completes without throwing and without leaked content. * - * <p>{@link XMLReader#parse(InputSource)} on a parser from {@link HardeningSAXParserFactory#newInstance()}; use this when the hardening guarantee is "the parse + * <p>{@link XMLReader#parse(InputSource)} on a parser from {@link SecureSAXParserFactory#newInstance()}; use this when the hardening guarantee is "the parse * succeeds but never resolves the external resource", for example, when the ignore-all resolver floor resolves the external subset to empty content.</p> */ static void assertSaxDoesNotLeak(final String payload) { - assertNoLeakStrict(() -> captureCharacters(strictXMLReader(HardeningSAXParserFactory.newInstance()), payload), "SAX"); + assertNoLeakStrict(() -> captureCharacters(strictXMLReader(SecureSAXParserFactory.newInstance()), payload), "SAX"); } /** * Asserts a hardened SAX parse succeeds. * - * <p>{@link XMLReader#parse(InputSource)} on a parser from {@link HardeningSAXParserFactory#newInstance()}; positive control for DOCTYPE-only payloads.</p> + * <p>{@link XMLReader#parse(InputSource)} on a parser from {@link SecureSAXParserFactory#newInstance()}; positive control for DOCTYPE-only payloads.</p> */ static void assertSaxParses(final String payload) { - assertParseSucceeds(() -> consumeXmlReader(strictXMLReader(HardeningSAXParserFactory.newInstance()), payload), "SAX"); + assertParseSucceeds(() -> consumeXmlReader(strictXMLReader(SecureSAXParserFactory.newInstance()), payload), "SAX"); } /** @@ -691,7 +691,7 @@ static void assertValidatorValidates(final String xml) { /** * Asserts a hardened-in-place XMLReader parse of the payload throws. * - * <p>{@link XMLReader#parse(InputSource)} on a raw reader hardened via {@link HardeningSAXParserFactory#harden(XMLReader)}; only a thrown exception passes.</p> + * <p>{@link XMLReader#parse(InputSource)} on a raw reader hardened via {@link SecureSAXParserFactory#harden(XMLReader)}; only a thrown exception passes.</p> */ static void assertXmlReaderBlocks(final String payload) { assertParseFails(() -> consumeXmlReader(rawHardenedReader(), payload), "XMLReader", SAXException.class); @@ -707,7 +707,7 @@ static void assertXmlReaderBlocksOrDoesNotLeak(final String payload) { /** * Asserts a hardened-in-place XMLReader parse completes without throwing and without leaked content. * - * <p>{@link XMLReader#parse(InputSource)} on a raw reader hardened via {@link HardeningSAXParserFactory#harden(XMLReader)}; use this when the hardening contract + * <p>{@link XMLReader#parse(InputSource)} on a raw reader hardened via {@link SecureSAXParserFactory#harden(XMLReader)}; use this when the hardening contract * guarantees the parse succeeds but never resolves the external resource.</p> */ static void assertXmlReaderDoesNotLeak(final String payload) { @@ -717,7 +717,7 @@ static void assertXmlReaderDoesNotLeak(final String payload) { /** * Asserts a hardened-in-place XMLReader parse succeeds. * - * <p>{@link XMLReader#parse(InputSource)} on a raw reader hardened via {@link HardeningSAXParserFactory#harden(XMLReader)}; positive control for DOCTYPE-only + * <p>{@link XMLReader#parse(InputSource)} on a raw reader hardened via {@link SecureSAXParserFactory#harden(XMLReader)}; positive control for DOCTYPE-only * payloads.</p> */ static void assertXmlReaderParses(final String payload) { @@ -926,13 +926,13 @@ private static boolean probeDomResolvesInternalEntities() { } } - /** Builds a raw {@link XMLReader} from a deliberately permissive {@link SAXParserFactory} and hardens it via {@link HardeningSAXParserFactory#harden(XMLReader)}. */ + /** Builds a raw {@link XMLReader} from a deliberately permissive {@link SAXParserFactory} and hardens it via {@link SecureSAXParserFactory#harden(XMLReader)}. */ private static XMLReader rawHardenedReader() throws Exception { final SAXParserFactory factory = SAXParserFactory.newInstance(); if (!IS_ANDROID) { factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false); } - return HardeningSAXParserFactory.harden(factory.newSAXParser().getXMLReader()); + return SecureSAXParserFactory.harden(factory.newSAXParser().getXMLReader()); } /** Opens the named test resource as a {@link StreamSource} preserving its system id, so relative includes/imports/redefines resolve normally. */ diff --git a/src/test/java/org/apache/commons/xml/EntityResolverFloorTest.java b/src/test/java/org/apache/commons/xml/EntityResolverFloorTest.java index 57a4d7c..0598109 100644 --- a/src/test/java/org/apache/commons/xml/EntityResolverFloorTest.java +++ b/src/test/java/org/apache/commons/xml/EntityResolverFloorTest.java @@ -132,7 +132,7 @@ private static DocumentBuilder hardenedBuilder() throws Exception { } private static XMLReader hardenedReader() throws Exception { - final XMLReader reader = HardeningSAXParserFactory.newInstance().newSAXParser().getXMLReader(); + final XMLReader reader = SecureSAXParserFactory.newInstance().newSAXParser().getXMLReader(); reader.setErrorHandler(AttackTestSupport.STRICT_REPORTER); return reader; } @@ -177,7 +177,7 @@ private static DocumentBuilder xIncludeAwareBuilder() throws Exception { } private static XMLReader xIncludeAwareReader() throws Exception { - final SAXParserFactory factory = HardeningSAXParserFactory.newInstance(); + final SAXParserFactory factory = SecureSAXParserFactory.newInstance(); factory.setNamespaceAware(true); AttackTestSupport.assumeDoesNotThrow(() -> factory.setXIncludeAware(true)); final XMLReader reader = factory.newSAXParser().getXMLReader(); @@ -227,7 +227,7 @@ void domResolvesRelativeXIncludeSibling() throws Exception { void saxParseWithHandlerDoesNotBypass() throws Exception { // SAXParser.parse(source, handler) installs the handler as the reader's entity resolver; the handler does not resolve it (returns null), so the // ignore-all floor must still resolve the external entity to empty rather than letting the parser fetch it. - final SAXParser parser = HardeningSAXParserFactory.newInstance().newSAXParser(); + final SAXParser parser = SecureSAXParserFactory.newInstance().newSAXParser(); final StringBuilder text = new StringBuilder(); try { parser.parse(AttackTestSupport.inputSource(entityPayload(ALLOWED)), AttackTestSupport.capturingHandler(text)); diff --git a/src/test/java/org/apache/commons/xml/HardeningFactoriesSmokeTest.java b/src/test/java/org/apache/commons/xml/HardeningFactoriesSmokeTest.java index a671627..78ef204 100644 --- a/src/test/java/org/apache/commons/xml/HardeningFactoriesSmokeTest.java +++ b/src/test/java/org/apache/commons/xml/HardeningFactoriesSmokeTest.java @@ -59,7 +59,7 @@ class HardeningFactoriesSmokeTest { @Test void publicClassesDoNotExtendTheirJaxpFactoryType() { assertFalse(DocumentBuilderFactory.class.isAssignableFrom(SecureDocumentBuilderFactory.class)); - assertFalse(SAXParserFactory.class.isAssignableFrom(HardeningSAXParserFactory.class)); + assertFalse(SAXParserFactory.class.isAssignableFrom(SecureSAXParserFactory.class)); assertFalse(SchemaFactory.class.isAssignableFrom(HardeningSchemaFactory.class)); assertFalse(TransformerFactory.class.isAssignableFrom(HardeningTransformerFactory.class)); assertFalse(XMLInputFactory.class.isAssignableFrom(HardeningXMLInputFactory.class)); @@ -97,8 +97,8 @@ void newDocumentBuilderFactoryReturnsFreshInstance() { @Test void newSAXParserFactoryReturnsFreshInstance() { - final SAXParserFactory a = HardeningSAXParserFactory.newInstance(); - final SAXParserFactory b = HardeningSAXParserFactory.newInstance(); + final SAXParserFactory a = SecureSAXParserFactory.newInstance(); + final SAXParserFactory b = SecureSAXParserFactory.newInstance(); assertNotSame(a, b); assertFalse(a.isValidating()); assertFalse(a.isXIncludeAware()); @@ -148,7 +148,7 @@ void explicitClassNameDocumentBuilderFactoryIsHardened() throws Exception { @Test void explicitClassNameSAXParserFactoryIsHardened() throws Exception { final Class<?> impl = SAXParserFactory.newInstance().getClass(); - final SAXParserFactory factory = HardeningSAXParserFactory.newInstance(impl.getName(), impl.getClassLoader()); + final SAXParserFactory factory = SecureSAXParserFactory.newInstance(impl.getName(), impl.getClassLoader()); assertTrue(factory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)); } @@ -218,10 +218,10 @@ void newDefaultInstanceDocumentBuilderFactoryIsUsable() throws Exception { @Tag("sax") void newDefaultInstanceSAXParserFactoryIsUsable() throws Exception { if (AttackTestSupport.IS_ANDROID) { - assertThrows(FactoryConfigurationError.class, HardeningSAXParserFactory::newDefaultInstance); + assertThrows(FactoryConfigurationError.class, SecureSAXParserFactory::newDefaultInstance); return; } - final SAXParserFactory factory = HardeningSAXParserFactory.newDefaultInstance(); + final SAXParserFactory factory = SecureSAXParserFactory.newDefaultInstance(); factory.newSAXParser().parse(new InputSource(new StringReader(BENIGN_XML)), new DefaultHandler()); assertTrue(factory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)); } @@ -254,7 +254,7 @@ void newDefaultNSInstanceDocumentBuilderFactoryIsNamespaceAware() throws Excepti @Test @Tag("sax") void newNSInstanceSAXParserFactoryIsNamespaceAware() throws Exception { - final SAXParserFactory factory = HardeningSAXParserFactory.newNSInstance(); + final SAXParserFactory factory = SecureSAXParserFactory.newNSInstance(); assertTrue(factory.isNamespaceAware()); factory.newSAXParser().parse(new InputSource(new StringReader(BENIGN_XML)), new DefaultHandler()); if (!AttackTestSupport.IS_ANDROID) { @@ -266,10 +266,10 @@ void newNSInstanceSAXParserFactoryIsNamespaceAware() throws Exception { @Tag("sax") void newDefaultNSInstanceSAXParserFactoryIsNamespaceAware() throws Exception { if (AttackTestSupport.IS_ANDROID) { - assertThrows(FactoryConfigurationError.class, HardeningSAXParserFactory::newDefaultNSInstance); + assertThrows(FactoryConfigurationError.class, SecureSAXParserFactory::newDefaultNSInstance); return; } - final SAXParserFactory factory = HardeningSAXParserFactory.newDefaultNSInstance(); + final SAXParserFactory factory = SecureSAXParserFactory.newDefaultNSInstance(); assertTrue(factory.isNamespaceAware()); assertTrue(factory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)); } @@ -285,7 +285,7 @@ void explicitClassNameNSDocumentBuilderFactoryIsNamespaceAware() throws Exceptio @Test void explicitClassNameNSSAXParserFactoryIsNamespaceAware() throws Exception { final Class<?> impl = SAXParserFactory.newInstance().getClass(); - final SAXParserFactory factory = HardeningSAXParserFactory.newNSInstance(impl.getName(), impl.getClassLoader()); + final SAXParserFactory factory = SecureSAXParserFactory.newNSInstance(impl.getName(), impl.getClassLoader()); assertTrue(factory.isNamespaceAware()); assertTrue(factory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)); } diff --git a/src/test/java/org/apache/commons/xml/OverrideDefaultParserTest.java b/src/test/java/org/apache/commons/xml/OverrideDefaultParserTest.java index ef67fef..c15ce95 100644 --- a/src/test/java/org/apache/commons/xml/OverrideDefaultParserTest.java +++ b/src/test/java/org/apache/commons/xml/OverrideDefaultParserTest.java @@ -49,7 +49,7 @@ @Tag("schema") class OverrideDefaultParserTest { - private static final String FEATURE = HardeningSAXParserFactory.OVERRIDE_DEFAULT_PARSER; + private static final String FEATURE = SecureSAXParserFactory.OVERRIDE_DEFAULT_PARSER; /** Package prefix of the JDK's built-in parsers, the family a {@code false} feature value pins. */ private static final String JDK_INTERNAL_PREFIX = "com.sun.org.apache.xerces.internal."; @@ -64,10 +64,10 @@ private static String transform(final TransformerFactory factory, final String t @Test void hardenedReaderFollowsFlag() throws Exception { assumeFalse(AttackTestSupport.IS_ANDROID); - final XMLReader pinned = ((HardeningXMLReader) HardeningSAXParserFactory.newHardenedReader(false)).getDelegate(); + final XMLReader pinned = ((HardeningXMLReader) SecureSAXParserFactory.newHardenedReader(false)).getDelegate(); assertTrue(pinned.getClass().getName().startsWith(JDK_INTERNAL_PREFIX), pinned.getClass().getName()); - final XMLReader pluggable = ((HardeningXMLReader) HardeningSAXParserFactory.newHardenedReader(true)).getDelegate(); - final XMLReader lookedUp = ((HardeningXMLReader) HardeningSAXParserFactory.newNSInstance().newSAXParser().getXMLReader()).getDelegate(); + final XMLReader pluggable = ((HardeningXMLReader) SecureSAXParserFactory.newHardenedReader(true)).getDelegate(); + final XMLReader lookedUp = ((HardeningXMLReader) SecureSAXParserFactory.newNSInstance().newSAXParser().getXMLReader()).getDelegate(); assertEquals(lookedUp.getClass(), pluggable.getClass()); if (xercesOnClasspath()) { // The two families genuinely differ only where a third-party parser wins the lookup (the test-jdk-xerces execution). diff --git a/src/test/java/org/apache/commons/xml/ResetHardeningTest.java b/src/test/java/org/apache/commons/xml/ResetHardeningTest.java index b2b2c94..ced11da 100644 --- a/src/test/java/org/apache/commons/xml/ResetHardeningTest.java +++ b/src/test/java/org/apache/commons/xml/ResetHardeningTest.java @@ -72,7 +72,7 @@ void documentBuilderResetKeepsEntityResolverFloor() throws Exception { @Test @Tag("sax") void saxParserResetKeepsEntityResolverFloor() throws Exception { - final SAXParser parser = HardeningSAXParserFactory.newInstance().newSAXParser(); + final SAXParser parser = SecureSAXParserFactory.newInstance().newSAXParser(); // Materialize the hardened reader before the reset, so a stale cached wrapper would be observable. parser.getXMLReader(); AttackTestSupport.assumeDoesNotThrow(parser::reset); diff --git a/src/test/java/org/apache/commons/xml/SaxSurfaceTestSupport.java b/src/test/java/org/apache/commons/xml/SaxSurfaceTestSupport.java index 2f16864..2ab2401 100644 --- a/src/test/java/org/apache/commons/xml/SaxSurfaceTestSupport.java +++ b/src/test/java/org/apache/commons/xml/SaxSurfaceTestSupport.java @@ -39,7 +39,7 @@ final class SaxSurfaceTestSupport { /** Feeds the input's SAX events into the handler through a hardened, namespace-aware reader. */ static void feed(final ContentHandler handler, final InputSource input) throws Exception { - final SAXParserFactory factory = HardeningSAXParserFactory.newInstance(); + final SAXParserFactory factory = SecureSAXParserFactory.newInstance(); factory.setNamespaceAware(true); final XMLReader reader = factory.newSAXParser().getXMLReader(); reader.setContentHandler(handler); diff --git a/src/test/java/org/apache/commons/xml/SchemaLocationPropertyTest.java b/src/test/java/org/apache/commons/xml/SchemaLocationPropertyTest.java index 1b0e909..12a0025 100644 --- a/src/test/java/org/apache/commons/xml/SchemaLocationPropertyTest.java +++ b/src/test/java/org/apache/commons/xml/SchemaLocationPropertyTest.java @@ -93,7 +93,7 @@ private static DocumentBuilder hardenedValidatingDom(final String property, fina private static XMLReader hardenedValidatingSax(final String property, final String value) { return configureOrSkip(() -> { - final SAXParserFactory factory = HardeningSAXParserFactory.newInstance(); + final SAXParserFactory factory = SecureSAXParserFactory.newInstance(); factory.setNamespaceAware(true); factory.setValidating(true); final SAXParser parser = factory.newSAXParser(); diff --git a/src/test/java/org/apache/commons/xml/SchemaLocationSaxTest.java b/src/test/java/org/apache/commons/xml/SchemaLocationSaxTest.java index 0e02342..f8a649b 100644 --- a/src/test/java/org/apache/commons/xml/SchemaLocationSaxTest.java +++ b/src/test/java/org/apache/commons/xml/SchemaLocationSaxTest.java @@ -100,7 +100,7 @@ private static boolean supportsSchemaLanguage() { @Test void hardenedDoesNotFetchExternalSchema() throws Exception { assumeTrue(supportsSchemaLanguage(), "parser does not support JAXP 1.2 schema-language XSD validation"); - final SAXParser parser = newValidatingParser(HardeningSAXParserFactory.newInstance()); + final SAXParser parser = newValidatingParser(SecureSAXParserFactory.newInstance()); // The schemaLocation reference resolves to empty rather than being fetched. Either the empty schema fails the validating parse (acceptable), or the // parse completes but the schema's default leak attribute is never augmented onto the element. Either way the marker must not be observed. final LeakCapturingHandler handler = new LeakCapturingHandler(); diff --git a/src/test/java/org/apache/commons/xml/ShadingFootprintTest.java b/src/test/java/org/apache/commons/xml/ShadingFootprintTest.java index d870d8f..1f31827 100644 --- a/src/test/java/org/apache/commons/xml/ShadingFootprintTest.java +++ b/src/test/java/org/apache/commons/xml/ShadingFootprintTest.java @@ -71,10 +71,10 @@ class ShadingFootprintTest { "FallbackIgnoreEntityResolver2", "SecureException", "SecureSAXParser", - "HardeningSAXParserFactory", - "HardeningSAXParserFactory$1", - "HardeningSAXParserFactory$HardeningExpatXMLReader", - "HardeningSAXParserFactory$Wrapper", + "SecureSAXParserFactory", + "SecureSAXParserFactory$1", + "SecureSAXParserFactory$HardeningExpatXMLReader", + "SecureSAXParserFactory$Wrapper", "HardeningXMLReader", "MethodHandleFactory"); // @formatter:on @@ -90,7 +90,7 @@ class ShadingFootprintTest { // @formatter:on /** - * TrAX, XPath and schema re-harden their sub-parsers through {@link HardeningSAXParserFactory#harden(Source, boolean)}, so each builds on the full SAX closure below; + * TrAX, XPath and schema re-harden their sub-parsers through {@link SecureSAXParserFactory#harden(Source, boolean)}, so each builds on the full SAX closure below; * TrAX additionally parses the Xalan {@code getAssociatedStylesheet} source and XPath its InputSource-taking evaluate calls through the DOM entry point, so * their closures carry that set too. */ @@ -104,10 +104,10 @@ class ShadingFootprintTest { "SecureDocumentBuilderFactory$Wrapper", "SecureException", "SecureSAXParser", - "HardeningSAXParserFactory", - "HardeningSAXParserFactory$1", - "HardeningSAXParserFactory$HardeningExpatXMLReader", - "HardeningSAXParserFactory$Wrapper", + "SecureSAXParserFactory", + "SecureSAXParserFactory$1", + "SecureSAXParserFactory$HardeningExpatXMLReader", + "SecureSAXParserFactory$Wrapper", "HardeningTemplates", "HardeningTemplatesHandler", "HardeningTransformer", @@ -134,10 +134,10 @@ class ShadingFootprintTest { "MethodHandleFactory", "SecureException", "SecureSAXParser", - "HardeningSAXParserFactory", - "HardeningSAXParserFactory$1", - "HardeningSAXParserFactory$HardeningExpatXMLReader", - "HardeningSAXParserFactory$Wrapper", + "SecureSAXParserFactory", + "SecureSAXParserFactory$1", + "SecureSAXParserFactory$HardeningExpatXMLReader", + "SecureSAXParserFactory$Wrapper", "HardeningXMLReader", "HardeningXPath", "HardeningXPathExpression", @@ -156,10 +156,10 @@ class ShadingFootprintTest { "FallbackIgnoreLSResourceResolver", "SecureException", "SecureSAXParser", - "HardeningSAXParserFactory", - "HardeningSAXParserFactory$1", - "HardeningSAXParserFactory$HardeningExpatXMLReader", - "HardeningSAXParserFactory$Wrapper", + "SecureSAXParserFactory", + "SecureSAXParserFactory$1", + "SecureSAXParserFactory$HardeningExpatXMLReader", + "SecureSAXParserFactory$Wrapper", "HardeningSchema", "HardeningSchemaFactory", "HardeningSchemaFactory$1", @@ -177,7 +177,7 @@ class ShadingFootprintTest { /** * Entry points reported by the {@link #reportFootprint()} diagnostic, most-focused first, ending with the whole library. */ - private static final String[] REPORTED = {"SecureDocumentBuilderFactory", "HardeningSAXParserFactory", "HardeningXMLInputFactory", + private static final String[] REPORTED = {"SecureDocumentBuilderFactory", "SecureSAXParserFactory", "HardeningXMLInputFactory", "HardeningTransformerFactory", "HardeningXPathFactory", "HardeningSchemaFactory"}; private static Clazzpath clazzpath; @@ -274,7 +274,7 @@ void rootClosureMatchesDocumentBuilderFootprint() { @Test void saxParserFactoryFootprint() { - assertEquals(SAX_PARSER_FACTORY, closureOf("HardeningSAXParserFactory")); + assertEquals(SAX_PARSER_FACTORY, closureOf("SecureSAXParserFactory")); } @Test diff --git a/src/test/java/org/apache/commons/xml/UnsupportedXmlImplementationTest.java b/src/test/java/org/apache/commons/xml/UnsupportedXmlImplementationTest.java index 3e4fc5b..002c482 100644 --- a/src/test/java/org/apache/commons/xml/UnsupportedXmlImplementationTest.java +++ b/src/test/java/org/apache/commons/xml/UnsupportedXmlImplementationTest.java @@ -103,7 +103,7 @@ void hardenRejectsUnsecurableFactory() { void hardenRejectsUnsecurableSaxFactory() { final IllegalStateException thrown = assertThrows( IllegalStateException.class, - () -> HardeningSAXParserFactory.harden(new FakeSAXParserFactory())); + () -> SecureSAXParserFactory.harden(new FakeSAXParserFactory())); assertNotNull(thrown.getMessage()); assertTrue(thrown.getMessage().contains(FakeSAXParserFactory.class.getName()), "Exception message must name the unsupported class: " + thrown.getMessage()); diff --git a/src/test/java/org/apache/commons/xml/XIncludeTest.java b/src/test/java/org/apache/commons/xml/XIncludeTest.java index 7a952d2..3306c46 100644 --- a/src/test/java/org/apache/commons/xml/XIncludeTest.java +++ b/src/test/java/org/apache/commons/xml/XIncludeTest.java @@ -263,7 +263,7 @@ void hardenedDomWithAllowListResolvesParseXml() throws Exception { void hardenedSaxBlocksParseText() throws Exception { final String input = xiIncludeXml(REFERENCED_TEXT, "text"); - final SAXParserFactory factory = HardeningSAXParserFactory.newInstance(); + final SAXParserFactory factory = SecureSAXParserFactory.newInstance(); factory.setNamespaceAware(true); assumeXIncludeAware(factory); final String captured = captureCharacters(factory.newSAXParser().getXMLReader(), input); @@ -276,7 +276,7 @@ void hardenedSaxBlocksParseText() throws Exception { void hardenedSaxBlocksParseXml() throws Exception { final InputSource input = inputSource(xiIncludeXml(REFERENCED_XML, "xml")); - final SAXParserFactory factory = HardeningSAXParserFactory.newInstance(); + final SAXParserFactory factory = SecureSAXParserFactory.newInstance(); factory.setNamespaceAware(true); assumeXIncludeAware(factory); assertThrows(SAXException.class, () -> { @@ -290,7 +290,7 @@ void hardenedSaxBlocksParseXml() throws Exception { void hardenedSaxNullResolverDoesNotLeak() throws Exception { final InputSource input = inputSource(xiIncludeXml(REFERENCED_XML, "xml")); - final SAXParserFactory factory = HardeningSAXParserFactory.newInstance(); + final SAXParserFactory factory = SecureSAXParserFactory.newInstance(); factory.setNamespaceAware(true); assumeXIncludeAware(factory); final XMLReader reader = factory.newSAXParser().getXMLReader(); @@ -304,7 +304,7 @@ void hardenedSaxNullResolverDoesNotLeak() throws Exception { void hardenedSaxWithAllowListResolvesParseText() throws Exception { final String input = xiIncludeXml(REFERENCED_TEXT, "text"); - final SAXParserFactory factory = HardeningSAXParserFactory.newInstance(); + final SAXParserFactory factory = SecureSAXParserFactory.newInstance(); factory.setNamespaceAware(true); assumeXIncludeAware(factory); final XMLReader reader = factory.newSAXParser().getXMLReader(); @@ -319,7 +319,7 @@ void hardenedSaxWithAllowListResolvesParseText() throws Exception { void hardenedSaxWithAllowListResolvesParseXml() throws Exception { final String input = xiIncludeXml(REFERENCED_XML, "xml"); - final SAXParserFactory factory = HardeningSAXParserFactory.newInstance(); + final SAXParserFactory factory = SecureSAXParserFactory.newInstance(); factory.setNamespaceAware(true); assumeXIncludeAware(factory); final XMLReader reader = factory.newSAXParser().getXMLReader(); @@ -341,7 +341,7 @@ void hardenReaderAllowListResolvesParseXml() throws Exception { final SAXParserFactory unhardenedFactory = SAXParserFactory.newInstance(); unhardenedFactory.setNamespaceAware(true); assumeXIncludeAware(unhardenedFactory); - final XMLReader reader = HardeningSAXParserFactory.harden(unhardenedFactory.newSAXParser().getXMLReader()); + final XMLReader reader = SecureSAXParserFactory.harden(unhardenedFactory.newSAXParser().getXMLReader()); reader.setEntityResolver(new AllowListResolver()); final String captured = captureCharacters(reader, input); assertEquals(RESOLVED_MARKER, captured.trim(), @@ -356,7 +356,7 @@ void hardenReaderBlocksParseText() throws Exception { final SAXParserFactory unhardenedFactory = SAXParserFactory.newInstance(); unhardenedFactory.setNamespaceAware(true); assumeXIncludeAware(unhardenedFactory); - final XMLReader reader = HardeningSAXParserFactory.harden(unhardenedFactory.newSAXParser().getXMLReader()); + final XMLReader reader = SecureSAXParserFactory.harden(unhardenedFactory.newSAXParser().getXMLReader()); final String captured = captureCharacters(reader, input); assertFalse(captured.contains(LEAKED_MARKER), "hardenReader parse=text must resolve the include to empty, not leak; got: " + captured); @@ -371,7 +371,7 @@ void hardenReaderBlocksParseXml() throws Exception { final SAXParserFactory unhardenedFactory = SAXParserFactory.newInstance(); unhardenedFactory.setNamespaceAware(true); assumeXIncludeAware(unhardenedFactory); - final XMLReader reader = HardeningSAXParserFactory.harden(unhardenedFactory.newSAXParser().getXMLReader()); + final XMLReader reader = SecureSAXParserFactory.harden(unhardenedFactory.newSAXParser().getXMLReader()); assertThrows(SAXException.class, () -> reader.parse(input), "hardenReader should block XInclude parse=xml on reader with XInclude already enabled"); }
