TestSaxProperties.java
package wstxtest.sax;
import java.io.StringReader;
import javax.xml.XMLConstants;
import javax.xml.parsers.SAXParser;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import com.ctc.wstx.sax.WstxSAXParserFactory;
import wstxtest.BaseWstxTest;
import wstxtest.sax.TestBasicSax.MyHandler;
import org.junit.jupiter.api.Test;
public class TestSaxProperties extends BaseWstxTest
{
private final static String EXTERNAL_GENERAL_ENTITIES = "http://xml.org/sax/features/external-general-entities";
private final static String EXTERNAL_PARAMETER_ENTITIES = "http://xml.org/sax/features/external-parameter-entities";
/**
* Document that pulls in an external parameter entity from the internal DTD
* subset. The referenced file really does exist and declares a defaulted
* attribute, so that:
*<ul>
* <li>a successful parse is observable ({@code MyHandler._attrs} becomes 1
* only if the external subset was actually read), and
* </li>
* <li>a failed parse can only be due to the feature being disabled, not due
* to the system id being unresolvable
* </li>
*</ul>
*/
private static String docWithExternalPE() {
String systemId = TestSaxProperties.class.getResource("external-pe.dtd").toString();
return "<!DOCTYPE root [ <!ENTITY % pe SYSTEM \""+systemId+"\"> %pe; ]><root />";
}
// [woodstox-core#77]: Don't barf on "secure processing" setting
@Test
public void testSecureProcessingFactory() throws Exception
{
WstxSAXParserFactory f = new WstxSAXParserFactory();
// default setting is `false`
assertFalse(f.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
// but may change
f.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
assertTrue(f.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
// as well as revert
f.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false);
assertFalse(f.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
}
@Test
public void testSecureProcessingReader() throws Exception
{
WstxSAXParserFactory f = new WstxSAXParserFactory();
f.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
SAXParser sp = f.newSAXParser();
// 13-Jul-2019, tatu: as far as I can see, there is no way to set or get
// feature setting via parser instance (only "properties", not "features",
// accessible). So... can't verify or change
// assertNull(sp.getProperty(XMLConstants.FEATURE_SECURE_PROCESSING));
// so let's simply check that basic parsing still works:
MyHandler h = new MyHandler();
InputSource src = new InputSource(new StringReader("<root></root>"));
sp.parse(src, h);
}
// Same feature is settable via the XMLReader the parser exposes
@Test
public void testSecureProcessingXmlReader() throws Exception
{
XMLReader r = new WstxSAXParserFactory().newSAXParser().getXMLReader();
assertFalse(r.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
r.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
assertTrue(r.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
r.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false);
assertFalse(r.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
}
// Positive control for the two tests below: with the feature left at its
// default, the external parameter entity really is resolved and the
// declarations it contains take effect
@Test
public void testExternalParameterEntitiesEnabled() throws Exception
{
WstxSAXParserFactory f = new WstxSAXParserFactory();
// enabled by default, like external general entities
assertTrue(f.getFeature(EXTERNAL_PARAMETER_ENTITIES));
assertTrue(f.getFeature(EXTERNAL_GENERAL_ENTITIES));
MyHandler h = new MyHandler();
f.newSAXParser().parse(new InputSource(new StringReader(docWithExternalPE())), h);
assertEquals("Should have parsed the root element", 1, h._elems);
// and the defaulted attribute only exists if the external subset was read
assertEquals("Should have defaulted attribute from external parameter entity",
1, h._attrs);
}
@Test
public void testExternalParameterEntitiesFactory() throws Exception
{
WstxSAXParserFactory f = new WstxSAXParserFactory();
// enabled by default, like external general entities
assertTrue(f.getFeature(EXTERNAL_PARAMETER_ENTITIES));
f.setFeature(EXTERNAL_PARAMETER_ENTITIES, false);
assertFalse(f.getFeature(EXTERNAL_PARAMETER_ENTITIES));
assertFalse(f.getFeature(EXTERNAL_GENERAL_ENTITIES));
try {
f.newSAXParser().parse(new InputSource(new StringReader(docWithExternalPE())),
new MyHandler());
fail("Should not resolve external parameter entity");
} catch (SAXException e) {
verifyException(e, "isSupportingExternalEntities");
}
}
@Test
public void testExternalParameterEntitiesXmlReader() throws Exception
{
XMLReader r = new WstxSAXParserFactory().newSAXParser().getXMLReader();
assertTrue(r.getFeature(EXTERNAL_PARAMETER_ENTITIES));
r.setFeature(EXTERNAL_PARAMETER_ENTITIES, false);
assertFalse(r.getFeature(EXTERNAL_PARAMETER_ENTITIES));
assertFalse(r.getFeature(EXTERNAL_GENERAL_ENTITIES));
r.setContentHandler(new MyHandler());
try {
r.parse(new InputSource(new StringReader(docWithExternalPE())));
fail("Should not resolve external parameter entity");
} catch (SAXException e) {
verifyException(e, "isSupportingExternalEntities");
}
}
}