From cd371f8bc5b00a1e642c8e1dec6a9a3c49fc8adb Mon Sep 17 00:00:00 2001 From: claudemamo <823038+claudemamo@users.noreply.github.com> Date: Thu, 18 Mar 2021 09:17:29 +0100 Subject: [PATCH] refactor: map SAX external-general-entities feature to new custom parameter meant for retaining entities instead of misusing the StAX XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES feature Refs: FasterXML/aalto-xml#65 --- .../fasterxml/aalto/AaltoInputProperties.java | 10 ++++++++++ .../com/fasterxml/aalto/impl/CommonConfig.java | 2 +- .../com/fasterxml/aalto/in/ReaderConfig.java | 9 ++++++++- .../com/fasterxml/aalto/in/ReaderScanner.java | 2 +- .../aalto/sax/SAXParserFactoryImpl.java | 11 +++++------ .../com/fasterxml/aalto/sax/SAXParserImpl.java | 3 +++ .../java/com/fasterxml/aalto/sax/SAXUtil.java | 2 -- .../fasterxml/aalto/sax/TestEntityResolver.java | 8 +++----- .../aalto/sax/TestSAXParserFactoryImpl.java | 17 +++++++++++++++++ 9 files changed, 48 insertions(+), 16 deletions(-) create mode 100644 src/main/java/com/fasterxml/aalto/AaltoInputProperties.java create mode 100644 src/test/java/com/fasterxml/aalto/sax/TestSAXParserFactoryImpl.java diff --git a/src/main/java/com/fasterxml/aalto/AaltoInputProperties.java b/src/main/java/com/fasterxml/aalto/AaltoInputProperties.java new file mode 100644 index 0000000..035dab1 --- /dev/null +++ b/src/main/java/com/fasterxml/aalto/AaltoInputProperties.java @@ -0,0 +1,10 @@ +package com.fasterxml.aalto; + +/** + * Class that contains constant for property names used to configure + * cursor and event readers produced by Aalto implementation of + * {@link javax.xml.stream.XMLInputFactory}. + */ +public final class AaltoInputProperties { + public final static String EXPAND_GENERAL_ENTITIES = "com.fasterxml.aalto.expandGeneralEntities"; +} diff --git a/src/main/java/com/fasterxml/aalto/impl/CommonConfig.java b/src/main/java/com/fasterxml/aalto/impl/CommonConfig.java index 1f679fd..37a24a4 100644 --- a/src/main/java/com/fasterxml/aalto/impl/CommonConfig.java +++ b/src/main/java/com/fasterxml/aalto/impl/CommonConfig.java @@ -7,7 +7,7 @@ /** * Base class for reader and writer-side configuration/context objects */ -public abstract class CommonConfig +public abstract class CommonConfig implements XMLStreamProperties { /* /********************************************************************** diff --git a/src/main/java/com/fasterxml/aalto/in/ReaderConfig.java b/src/main/java/com/fasterxml/aalto/in/ReaderConfig.java index eddbc7f..3480773 100644 --- a/src/main/java/com/fasterxml/aalto/in/ReaderConfig.java +++ b/src/main/java/com/fasterxml/aalto/in/ReaderConfig.java @@ -5,6 +5,7 @@ import javax.xml.stream.*; +import com.fasterxml.aalto.AaltoInputProperties; import org.codehaus.stax2.XMLInputFactory2; import com.fasterxml.aalto.impl.CommonConfig; @@ -41,6 +42,7 @@ public final class ReaderConfig final static int F_AUTO_CLOSE_INPUT = 0x2000; // Custom flags: + final static int F_EXPAND_GENERAL_ENTITIES = 0x3000; /** * These are the default settigs for XMLInputFactory. @@ -56,6 +58,7 @@ public final class ReaderConfig // and will report CDATA as such (and not as CHARACTERS) | F_REPORT_CDATA | F_PRESERVE_LOCATION + | F_EXPAND_GENERAL_ENTITIES ; private final static HashMap sProperties; @@ -98,7 +101,8 @@ public final class ReaderConfig // !!! Not really implemented, but let's recognize it sProperties.put(XMLInputFactory2.P_DTD_OVERRIDE, null); - // Custom ones? + // Custom ones + sProperties.put(AaltoInputProperties.EXPAND_GENERAL_ENTITIES, Integer.valueOf(F_EXPAND_GENERAL_ENTITIES)); } /** @@ -412,6 +416,9 @@ public boolean willParseLazily() { public boolean hasInternNsURIsBeenEnabled() { return hasExplicitFlag(F_INTERN_NS_URIS); } + // // // Custom properties + + public boolean willExpandGeneralEntities() { return hasFlag(F_EXPAND_GENERAL_ENTITIES); } /* /********************************************************************** diff --git a/src/main/java/com/fasterxml/aalto/in/ReaderScanner.java b/src/main/java/com/fasterxml/aalto/in/ReaderScanner.java index b2e596e..bccf9ea 100644 --- a/src/main/java/com/fasterxml/aalto/in/ReaderScanner.java +++ b/src/main/java/com/fasterxml/aalto/in/ReaderScanner.java @@ -896,7 +896,7 @@ private final int collectValue(int attrPtr, char quoteChar, PName attrName) throwUnexpectedChar(c, "'<' not allowed in attribute value"); case XmlCharTypes.CT_AMP: { - if (_config.willExpandEntities()) { + if (_config.willExpandGeneralEntities()) { int d = handleEntityInText(false); if (d == 0) { // unexpanded general entity... not good reportUnexpandedEntityInAttr(attrName, false); diff --git a/src/main/java/com/fasterxml/aalto/sax/SAXParserFactoryImpl.java b/src/main/java/com/fasterxml/aalto/sax/SAXParserFactoryImpl.java index 5fc3380..56c24ca 100644 --- a/src/main/java/com/fasterxml/aalto/sax/SAXParserFactoryImpl.java +++ b/src/main/java/com/fasterxml/aalto/sax/SAXParserFactoryImpl.java @@ -18,6 +18,7 @@ import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import com.fasterxml.aalto.AaltoInputProperties; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; @@ -36,11 +37,6 @@ public class SAXParserFactoryImpl extends SAXParserFactory { final InputFactoryImpl mStaxFactory; - - public SAXParserFactoryImpl(InputFactoryImpl inputFactory) - { - mStaxFactory = inputFactory; - } public SAXParserFactoryImpl() { @@ -73,6 +69,8 @@ public boolean getFeature(String name) switch (stdFeat) { case IS_STANDALONE: // read-only, but only during parsing return true; + case EXTERNAL_GENERAL_ENTITIES: + return ((Boolean) mStaxFactory.getProperty(AaltoInputProperties.EXPAND_GENERAL_ENTITIES)).booleanValue(); default: } } else { @@ -100,7 +98,8 @@ public void setFeature(String name, boolean enabled) switch (stdFeat) { case EXTERNAL_GENERAL_ENTITIES: - ok = !enabled; + mStaxFactory.setProperty(AaltoInputProperties.EXPAND_GENERAL_ENTITIES, enabled); + ok = true; break; case EXTERNAL_PARAMETER_ENTITIES: ok = !enabled; diff --git a/src/main/java/com/fasterxml/aalto/sax/SAXParserImpl.java b/src/main/java/com/fasterxml/aalto/sax/SAXParserImpl.java index cfbed04..270b3a7 100644 --- a/src/main/java/com/fasterxml/aalto/sax/SAXParserImpl.java +++ b/src/main/java/com/fasterxml/aalto/sax/SAXParserImpl.java @@ -22,6 +22,7 @@ import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; +import com.fasterxml.aalto.AaltoInputProperties; import org.xml.sax.*; import org.xml.sax.ext.Attributes2; import org.xml.sax.ext.DeclHandler; @@ -262,6 +263,8 @@ public boolean getFeature(String name) case IS_STANDALONE: // read-only, but only during parsing // !!! TBI return true; + case EXTERNAL_GENERAL_ENTITIES: + return ((Boolean) _staxFactory.getProperty(AaltoInputProperties.EXPAND_GENERAL_ENTITIES)).booleanValue(); default: } } else { diff --git a/src/main/java/com/fasterxml/aalto/sax/SAXUtil.java b/src/main/java/com/fasterxml/aalto/sax/SAXUtil.java index 57a77aa..be9db8f 100644 --- a/src/main/java/com/fasterxml/aalto/sax/SAXUtil.java +++ b/src/main/java/com/fasterxml/aalto/sax/SAXUtil.java @@ -71,8 +71,6 @@ public static SAXProperty findStdProperty(String featURI) public static Boolean getFixedStdFeatureValue(SAXFeature stdFeat) { switch (stdFeat) { - case EXTERNAL_GENERAL_ENTITIES: // not yet implemented - return Boolean.FALSE; case EXTERNAL_PARAMETER_ENTITIES: // not yet implemented return Boolean.FALSE; case IS_STANDALONE: // read-only, but only during parsing diff --git a/src/test/java/com/fasterxml/aalto/sax/TestEntityResolver.java b/src/test/java/com/fasterxml/aalto/sax/TestEntityResolver.java index 18d9db2..7666a20 100644 --- a/src/test/java/com/fasterxml/aalto/sax/TestEntityResolver.java +++ b/src/test/java/com/fasterxml/aalto/sax/TestEntityResolver.java @@ -67,11 +67,9 @@ public void testRetainAttributeEntityReference() } catch (SAXException e) { verifyException(e, "General entity reference (&replace-me;) encountered in entity expanding mode: operation not (yet) implemented\n at [row,col {unknown-source}]: [2,22]"); } - - InputFactoryImpl inputFactory = new InputFactoryImpl(); - inputFactory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false); - SAXParserFactoryImpl spfKeepEntityReferences = new SAXParserFactoryImpl(inputFactory); - spfKeepEntityReferences.setNamespaceAware(true); + + SAXParserFactoryImpl spfKeepEntityReferences = new SAXParserFactoryImpl(); + spfKeepEntityReferences.setFeature("http://xml.org/sax/features/external-general-entities", false); SAXParser spKeepEntityReferences = spfKeepEntityReferences.newSAXParser(); final CountDownLatch countDownLatch = new CountDownLatch(1); diff --git a/src/test/java/com/fasterxml/aalto/sax/TestSAXParserFactoryImpl.java b/src/test/java/com/fasterxml/aalto/sax/TestSAXParserFactoryImpl.java new file mode 100644 index 0000000..2c3c438 --- /dev/null +++ b/src/test/java/com/fasterxml/aalto/sax/TestSAXParserFactoryImpl.java @@ -0,0 +1,17 @@ +package com.fasterxml.aalto.sax; + +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; + +public class TestSAXParserFactoryImpl extends base.BaseTestCase { + + public void testSetGetFeatureExternalGeneralEntities() throws SAXNotRecognizedException, SAXNotSupportedException { + SAXParserFactoryImpl saxParserFactory = new SAXParserFactoryImpl(); + saxParserFactory.setFeature("http://xml.org/sax/features/external-general-entities", false); + assertFalse(saxParserFactory.getFeature("http://xml.org/sax/features/external-general-entities")); + + saxParserFactory.setFeature("http://xml.org/sax/features/external-general-entities", true); + assertTrue(saxParserFactory.getFeature("http://xml.org/sax/features/external-general-entities")); + } + +}