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 4299d437cb3bfeda1074f654acbc352b48e914fb Author: Gary Gregory <[email protected]> AuthorDate: Fri Aug 28 13:17:30 2026 -0400 Rename HardeningSchemaFactory to SecureSchemaFactory. --- ...SchemaFactory.java => SecureSchemaFactory.java} | 8 +++---- src/site/markdown/index.md | 2 +- .../org/apache/commons/xml/AttackTestSupport.java | 28 +++++++++++----------- .../commons/xml/EntityResolverFloorTest.java | 6 ++--- .../commons/xml/HardeningFactoriesSmokeTest.java | 10 ++++---- .../commons/xml/OverrideDefaultParserTest.java | 2 +- .../org/apache/commons/xml/ResetHardeningTest.java | 2 +- .../commons/xml/SchemaFactoryLanguageTest.java | 4 ++-- .../apache/commons/xml/ShadingFootprintTest.java | 10 ++++---- 9 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/main/java/org/apache/commons/xml/HardeningSchemaFactory.java b/src/main/java/org/apache/commons/xml/SecureSchemaFactory.java similarity index 97% rename from src/main/java/org/apache/commons/xml/HardeningSchemaFactory.java rename to src/main/java/org/apache/commons/xml/SecureSchemaFactory.java index 5d1e500..5e8bf10 100644 --- a/src/main/java/org/apache/commons/xml/HardeningSchemaFactory.java +++ b/src/main/java/org/apache/commons/xml/SecureSchemaFactory.java @@ -56,7 +56,7 @@ * * @see org.apache.commons.xml */ -public final class HardeningSchemaFactory { +public final class SecureSchemaFactory { /** Class name of the JDK's built-in default implementation, the Java 8 fallback for {@link #newDefaultInstance()}. */ private static final String JDK_SCHEMA_FACTORY = "com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory"; @@ -137,18 +137,18 @@ public static SchemaFactory newInstance(final String schemaLanguage, final Strin return harden(SchemaFactory.newInstance(schemaLanguage, factoryClassName, classLoader)); } - private HardeningSchemaFactory() { + private SecureSchemaFactory() { // static only } /** * Capability-driven hardening wrapper for any {@link SchemaFactory} on the classpath, the same recipe for every implementation. It is the entry point reached - * by {@link HardeningSchemaFactory#newInstance(String)}; there is no per-implementation branching, no {@code FEATURE_SECURE_PROCESSING} and no limit configuration on the + * by {@link SecureSchemaFactory#newInstance(String)}; there is no per-implementation branching, no {@code FEATURE_SECURE_PROCESSING} and no limit configuration on the * factory itself. * * <p>Three layers cooperate:</p> * <ol> - * <li>{@link HardeningSchemaFactory} installs an ignore-all {@link FallbackIgnoreLSResourceResolver} floor on the factory (blocking + * <li>{@link SecureSchemaFactory} 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 SecureSAXParserFactory#harden(Source, boolean)}.</li> * <li>{@link SecureSchema} wraps every Validator/ValidatorHandler the inner Schema produces and re-installs the floor on each (blocking diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md index 8c1c0ee..ccf71dc 100644 --- a/src/site/markdown/index.md +++ b/src/site/markdown/index.md @@ -138,7 +138,7 @@ NodeList hits = (NodeList) HardeningXPathFactory.newInstance() ```java import javax.xml.XMLConstants; import javax.xml.transform.stream.StreamSource; -import org.apache.commons.xml.HardeningSchemaFactory; +import org.apache.commons.xml.SecureSchemaFactory; HardeningSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI) .newSchema(new StreamSource(xsdStream)) diff --git a/src/test/java/org/apache/commons/xml/AttackTestSupport.java b/src/test/java/org/apache/commons/xml/AttackTestSupport.java index d802a2f..fdf7755 100644 --- a/src/test/java/org/apache/commons/xml/AttackTestSupport.java +++ b/src/test/java/org/apache/commons/xml/AttackTestSupport.java @@ -479,10 +479,10 @@ static void assertSaxParses(final String payload) { /** * Asserts a hardened Schema compilation throws. * - * <p>{@link SchemaFactory#newSchema(Source)} via {@link HardeningSchemaFactory#newInstance(String)}; only a thrown exception passes.</p> + * <p>{@link SchemaFactory#newSchema(Source)} via {@link SecureSchemaFactory#newInstance(String)}; only a thrown exception passes.</p> */ static void assertSchemaBlocks(final Source xsd) { - assertParseFails(() -> strictSchema(HardeningSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI), xsd), "Schema compile", SAXException.class, SecurityException.class); + assertParseFails(() -> strictSchema(SecureSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI), xsd), "Schema compile", SAXException.class, SecurityException.class); } /** @@ -491,7 +491,7 @@ static void assertSchemaBlocks(final Source xsd) { */ static void assertSchemaBlocksOrDoesNotLeak(final Source xsd) { assertNoLeakOrThrows(() -> { - strictSchema(HardeningSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI), xsd); + strictSchema(SecureSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI), xsd); return ""; }, "Schema compile", SAXException.class, SecurityException.class); } @@ -499,21 +499,21 @@ static void assertSchemaBlocksOrDoesNotLeak(final Source xsd) { /** * Asserts a hardened Schema compilation succeeds. * - * <p>{@link SchemaFactory#newSchema(Source)} via {@link HardeningSchemaFactory#newInstance(String)}; positive control for DOCTYPE-only payloads.</p> + * <p>{@link SchemaFactory#newSchema(Source)} via {@link SecureSchemaFactory#newInstance(String)}; positive control for DOCTYPE-only payloads.</p> */ static void assertSchemaCompiles(final Source xsd) { - assertParseSucceeds(() -> strictSchema(HardeningSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI), xsd), "Schema compile"); + assertParseSucceeds(() -> strictSchema(SecureSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI), xsd), "Schema compile"); } /** * Asserts a hardened Schema compilation completes without throwing. * - * <p>{@link SchemaFactory#newSchema(Source)} via {@link HardeningSchemaFactory#newInstance(String)}; use this when the hardening contract guarantees the compile + * <p>{@link SchemaFactory#newSchema(Source)} via {@link SecureSchemaFactory#newInstance(String)}; use this when the hardening contract guarantees the compile * succeeds but never resolves the external resource (for example, {@code XERCES_LOAD_EXTERNAL_DTD=false} silently skipping the external subset, with the body's * undeclared entity reference dropped per XML 1.0 ยง4.1).</p> */ static void assertSchemaDoesNotLeak(final Source xsd) { - assertParseSucceeds(() -> strictSchema(HardeningSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI), xsd), "Schema compile"); + assertParseSucceeds(() -> strictSchema(SecureSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI), xsd), "Schema compile"); } /** @@ -643,12 +643,12 @@ static void assertTransformerTransforms(final String payload) { /** * Asserts a hardened Validator validation throws. * - * <p>{@link Validator#validate(Source)} on a validator from {@link #BENIGN_SCHEMA} compiled via {@link HardeningSchemaFactory#newInstance(String)}; only a thrown + * <p>{@link Validator#validate(Source)} on a validator from {@link #BENIGN_SCHEMA} compiled via {@link SecureSchemaFactory#newInstance(String)}; only a thrown * exception passes (the schema is benign; the attack lives in the instance document).</p> */ static void assertValidatorBlocks(final String xml) { assertParseFails( - () -> strictValidator(strictSchema(HardeningSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI), streamSource(BENIGN_SCHEMA))).validate(streamSource(xml)), + () -> strictValidator(strictSchema(SecureSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI), streamSource(BENIGN_SCHEMA))).validate(streamSource(xml)), "Validator", SAXException.class, SecurityException.class); } @@ -659,7 +659,7 @@ static void assertValidatorBlocks(final String xml) { */ static void assertValidatorBlocksOrDoesNotLeak(final String xml) { assertNoLeakOrThrows(() -> { - strictValidator(strictSchema(HardeningSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI), streamSource(BENIGN_SCHEMA))).validate(streamSource(xml)); + strictValidator(strictSchema(SecureSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI), streamSource(BENIGN_SCHEMA))).validate(streamSource(xml)); return ""; }, "Validator", SAXException.class, SecurityException.class, IOException.class); } @@ -667,24 +667,24 @@ static void assertValidatorBlocksOrDoesNotLeak(final String xml) { /** * Asserts a hardened Validator validation completes without throwing. * - * <p>{@link Validator#validate(Source)} on a validator from {@link #BENIGN_SCHEMA} compiled via {@link HardeningSchemaFactory#newInstance(String)}; use this when the + * <p>{@link Validator#validate(Source)} on a validator from {@link #BENIGN_SCHEMA} compiled via {@link SecureSchemaFactory#newInstance(String)}; use this when the * hardening contract guarantees the validate succeeds but never resolves the external resource.</p> */ static void assertValidatorDoesNotLeak(final String xml) { assertParseSucceeds( - () -> strictValidator(strictSchema(HardeningSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI), streamSource(BENIGN_SCHEMA))).validate(streamSource(xml)), + () -> strictValidator(strictSchema(SecureSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI), streamSource(BENIGN_SCHEMA))).validate(streamSource(xml)), "Validator"); } /** * Asserts a hardened Validator validation succeeds. * - * <p>{@link Validator#validate(Source)} on a validator from {@link #BENIGN_SCHEMA} compiled via {@link HardeningSchemaFactory#newInstance(String)}; positive control + * <p>{@link Validator#validate(Source)} on a validator from {@link #BENIGN_SCHEMA} compiled via {@link SecureSchemaFactory#newInstance(String)}; positive control * for DOCTYPE-only payloads.</p> */ static void assertValidatorValidates(final String xml) { assertParseSucceeds( - () -> strictValidator(strictSchema(HardeningSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI), streamSource(BENIGN_SCHEMA))).validate(streamSource(xml)), + () -> strictValidator(strictSchema(SecureSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI), streamSource(BENIGN_SCHEMA))).validate(streamSource(xml)), "Validator"); } diff --git a/src/test/java/org/apache/commons/xml/EntityResolverFloorTest.java b/src/test/java/org/apache/commons/xml/EntityResolverFloorTest.java index 0598109..bd103b7 100644 --- a/src/test/java/org/apache/commons/xml/EntityResolverFloorTest.java +++ b/src/test/java/org/apache/commons/xml/EntityResolverFloorTest.java @@ -276,7 +276,7 @@ void saxResolvesRelativeXIncludeSibling() throws Exception { @Tag("schema") void schemaDeniesUnlisted() { assertParseFails(() -> { - final SchemaFactory factory = HardeningSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + final SchemaFactory factory = SecureSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); factory.setResourceResolver((type, namespaceURI, publicId, systemId, baseURI) -> null); factory.newSchema(AttackTestSupport.resourceSource("with-import.xsd")); }, "Schema import", SAXException.class, SecurityException.class); @@ -287,7 +287,7 @@ void schemaDeniesUnlisted() { void schemaFetchesIdentifierOnlyOptIn() { // A non-null return is an opt-in even without content: the implementation fetches the named resource itself, mirroring the entity floor's contract. assertParseSucceeds(() -> { - final SchemaFactory factory = HardeningSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + final SchemaFactory factory = SecureSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); factory.setResourceResolver((type, namespaceURI, publicId, systemId, baseURI) -> systemId != null && systemId.endsWith("included.xsd") ? identifierOnlyLsInput(ALLOWED_SCHEMA) : null); factory.newSchema(AttackTestSupport.resourceSource("with-import.xsd")); @@ -299,7 +299,7 @@ void schemaFetchesIdentifierOnlyOptIn() { void schemaResolvesAllowListed() { // with-import.xsd references an element defined only in the imported included.xsd, so it compiles only if the import is resolved. assertParseSucceeds(() -> { - final SchemaFactory factory = HardeningSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + final SchemaFactory factory = SecureSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); factory.setResourceResolver(SCHEMA_ALLOW_LIST); factory.newSchema(AttackTestSupport.resourceSource("with-import.xsd")); }, "Schema import via caller resolver"); diff --git a/src/test/java/org/apache/commons/xml/HardeningFactoriesSmokeTest.java b/src/test/java/org/apache/commons/xml/HardeningFactoriesSmokeTest.java index 78ef204..97bc1ab 100644 --- a/src/test/java/org/apache/commons/xml/HardeningFactoriesSmokeTest.java +++ b/src/test/java/org/apache/commons/xml/HardeningFactoriesSmokeTest.java @@ -60,7 +60,7 @@ class HardeningFactoriesSmokeTest { void publicClassesDoNotExtendTheirJaxpFactoryType() { assertFalse(DocumentBuilderFactory.class.isAssignableFrom(SecureDocumentBuilderFactory.class)); assertFalse(SAXParserFactory.class.isAssignableFrom(SecureSAXParserFactory.class)); - assertFalse(SchemaFactory.class.isAssignableFrom(HardeningSchemaFactory.class)); + assertFalse(SchemaFactory.class.isAssignableFrom(SecureSchemaFactory.class)); assertFalse(TransformerFactory.class.isAssignableFrom(HardeningTransformerFactory.class)); assertFalse(XMLInputFactory.class.isAssignableFrom(HardeningXMLInputFactory.class)); assertFalse(XPathFactory.class.isAssignableFrom(HardeningXPathFactory.class)); @@ -106,8 +106,8 @@ void newSAXParserFactoryReturnsFreshInstance() { @Test void newSchemaFactoryReturnsFreshInstance() throws Exception { - final SchemaFactory a = HardeningSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - final SchemaFactory b = HardeningSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + final SchemaFactory a = SecureSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + final SchemaFactory b = SecureSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); assertNotSame(a, b); assertTrue(a.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)); } @@ -155,7 +155,7 @@ void explicitClassNameSAXParserFactoryIsHardened() throws Exception { @Test void explicitClassNameSchemaFactoryIsHardened() throws Exception { final Class<?> impl = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).getClass(); - final SchemaFactory factory = HardeningSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI, impl.getName(), impl.getClassLoader()); + final SchemaFactory factory = SecureSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI, impl.getName(), impl.getClassLoader()); assertTrue(factory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)); } @@ -292,7 +292,7 @@ void explicitClassNameNSSAXParserFactoryIsNamespaceAware() throws Exception { @Test void newDefaultInstanceSchemaFactoryIsHardened() throws Exception { - final SchemaFactory factory = HardeningSchemaFactory.newDefaultInstance(); + final SchemaFactory factory = SecureSchemaFactory.newDefaultInstance(); 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 ea1ceb6..5d9c2a0 100644 --- a/src/test/java/org/apache/commons/xml/OverrideDefaultParserTest.java +++ b/src/test/java/org/apache/commons/xml/OverrideDefaultParserTest.java @@ -78,7 +78,7 @@ void hardenedReaderFollowsFlag() throws Exception { @Test void schemaFactoryReadsFeatureAtCreation() throws Exception { assumeFalse(AttackTestSupport.IS_ANDROID); - final SchemaFactory factory = HardeningSchemaFactory.newDefaultInstance(); + final SchemaFactory factory = SecureSchemaFactory.newDefaultInstance(); assertFalse(factory.getFeature(FEATURE)); assertFalse(((SecureSchema) factory.newSchema(AttackTestSupport.streamSource(AttackTestSupport.BENIGN_SCHEMA))).overrideDefaultParser); factory.setFeature(FEATURE, true); diff --git a/src/test/java/org/apache/commons/xml/ResetHardeningTest.java b/src/test/java/org/apache/commons/xml/ResetHardeningTest.java index ced11da..bcdccb4 100644 --- a/src/test/java/org/apache/commons/xml/ResetHardeningTest.java +++ b/src/test/java/org/apache/commons/xml/ResetHardeningTest.java @@ -107,7 +107,7 @@ void transformerResetKeepsUriResolverFloor() throws Exception { void validatorResetKeepsResourceResolverFloor() throws Exception { // A Schema built without sources validates against the instance's xsi:schemaLocation hints, so the resolver floor is the only barrier between the // validator and the external schema fetch. - final Validator validator = HardeningSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema().newValidator(); + final Validator validator = SecureSchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema().newValidator(); AttackTestSupport.assumeDoesNotThrow(validator::reset); validator.setErrorHandler(AttackTestSupport.STRICT_REPORTER); // schema-location-instance.xml hints at schema-location.xsd, which declares its root: a validator whose floor was stripped fetches it and validates diff --git a/src/test/java/org/apache/commons/xml/SchemaFactoryLanguageTest.java b/src/test/java/org/apache/commons/xml/SchemaFactoryLanguageTest.java index 584c703..513eaff 100644 --- a/src/test/java/org/apache/commons/xml/SchemaFactoryLanguageTest.java +++ b/src/test/java/org/apache/commons/xml/SchemaFactoryLanguageTest.java @@ -23,7 +23,7 @@ import org.junit.jupiter.api.Test; /** - * Checks that {@link HardeningSchemaFactory#newInstance(String)} passes the schema language through to {@link javax.xml.validation.SchemaFactory#newInstance}. + * Checks that {@link SecureSchemaFactory#newInstance(String)} passes the schema language through to {@link javax.xml.validation.SchemaFactory#newInstance}. * * <p>The working W3C XML Schema path is exercised by the whole schema suite; this test covers only the language-selection contract.</p> */ @@ -32,7 +32,7 @@ class SchemaFactoryLanguageTest { @Test void unknownSchemaLanguageThrows() { - assertThrows(IllegalArgumentException.class, () -> HardeningSchemaFactory.newInstance("urn:example:unknown-schema-language"), + assertThrows(IllegalArgumentException.class, () -> SecureSchemaFactory.newInstance("urn:example:unknown-schema-language"), "an unsupported schema language should surface SchemaFactory.newInstance's IllegalArgumentException"); } } diff --git a/src/test/java/org/apache/commons/xml/ShadingFootprintTest.java b/src/test/java/org/apache/commons/xml/ShadingFootprintTest.java index e8c469f..25e97a5 100644 --- a/src/test/java/org/apache/commons/xml/ShadingFootprintTest.java +++ b/src/test/java/org/apache/commons/xml/ShadingFootprintTest.java @@ -161,9 +161,9 @@ class ShadingFootprintTest { "SecureSAXParserFactory$HardeningExpatXMLReader", "SecureSAXParserFactory$Wrapper", "SecureSchema", - "HardeningSchemaFactory", - "HardeningSchemaFactory$1", - "HardeningSchemaFactory$Wrapper", + "SecureSchemaFactory", + "SecureSchemaFactory$1", + "SecureSchemaFactory$Wrapper", "HardeningValidator", "HardeningValidatorHandler", "HardeningXMLReader"); @@ -178,7 +178,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", "SecureSAXParserFactory", "HardeningXMLInputFactory", - "HardeningTransformerFactory", "HardeningXPathFactory", "HardeningSchemaFactory"}; + "HardeningTransformerFactory", "HardeningXPathFactory", "SecureSchemaFactory"}; private static Clazzpath clazzpath; private static Path classesDir; @@ -279,7 +279,7 @@ void saxParserFactoryFootprint() { @Test void schemaFactoryFootprint() { - assertEquals(SCHEMA_FACTORY, closureOf("HardeningSchemaFactory")); + assertEquals(SCHEMA_FACTORY, closureOf("SecureSchemaFactory")); } @Test
