blob: bfdfb76e06f3250fd3a398fc6a99cc5c32ef0b16 [file] [log] [blame]
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package stream.XMLStreamReaderTest;
import java.io.File;
import java.io.FileInputStream;
import java.io.StringReader;
import java.util.List;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.DTD;
import javax.xml.stream.events.EntityDeclaration;
import javax.xml.stream.events.EntityReference;
import javax.xml.stream.events.XMLEvent;
import org.testng.Assert;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
/*
* @test
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true stream.XMLStreamReaderTest.SupportDTDTest
* @run testng/othervm stream.XMLStreamReaderTest.SupportDTDTest
* @summary Test SUPPORT_DTD and IS_REPLACING_ENTITY_REFERENCES.
*/
/**
*
* SUPPORT_DTD behavior:
* Regardless of supportDTD, always report a DTD event () and throw an
* exception if an entity reference is found when supportDTD is false
*
* The behavior is related to property IS_REPLACING_ENTITY_REFERENCES.
*
* SUPPORT_DTD Replace Entity DTD ENTITY_REFERENCE
* true (default) true (default) yes, has entities no, return Characters
* true (default) false yes, has entities yes, can print entity name
* false true (default) yes, but no entity Exception: Undeclared general entity
* false false yes, but no entity yes, can print entity name
*
* Two patches related:
* sjsxp issue 9: XMLDocumentScannerImpl.java rev 1.6
* If the supportDTD property is set to FALSE, external and internal subsets
* are now ignored, rather than an error being reported. In particular, with
* this property set to FALSE, no error is reported if an external subset cannot
* be found. Note that the internal subset is still parsed (and errors could be
* reported here) but no events are returned by the parser. This fixes SJSXP
* issue 9 from Java.net.
* Note: SAX and DOM report fatal errors:
* If either SAX or DOM is used, turning on http://apache.org/xml/features/disallow-doctype-decl [1] effectively disables DTD,
* according to the spec: A fatal error is thrown if the incoming document contains a DOCTYPE declaration.
* The current jaxp implementation actually throws a nullpointexception. A better error message could be used.
*
*/
@Listeners({jaxp.library.FilePolicy.class})
public class SupportDTDTest {
final boolean DEBUG = false;
final String _file = "ExternalDTD.xml";
final String XML = "<?xml version='1.0' ?>" + "<!DOCTYPE root [\n" + "<!ENTITY intEnt 'internal entity'>\n" + "<!ENTITY extParsedEnt SYSTEM 'url:dummy'>\n"
+ "<!NOTATION notation PUBLIC 'notation-public-id'>\n" + "<!NOTATION notation2 SYSTEM 'url:dummy'>\n"
+ "<!ENTITY extUnparsedEnt SYSTEM 'url:dummy2' NDATA notation>\n" + "]>" + "<root>&intEnt;</root>";
final String XML1 = "<?xml version='1.0' encoding ='utf-8'?>" + "<!DOCTYPE document SYSTEM \"" + this.getClass().getResource("ExternalDTD.dtd").getFile()
+ "\">" + "<document>" + "<name>&mkm;</name>" + "</document>";
// final String XML1 = "<?xml version='1.0' encoding ='utf-8'?>" + "<!DOCTYPE document SYSTEM \"/home/oracle/repo/xmlwork/dev/jdk/test/javax/xml/jaxp/unittest/javax/xml/stream/XMLStreamReaderTest/ExternalDTD.dtd\">" + "<document>"
// + "<name>&mkm;</name>" + "</document>";
final int ENTITY_INTERNAL_ONLY = 1;
final int ENTITY_EXTERNAL_ONLY = 2;
final int ENTITY_BOTH = 3;
boolean _DTDReturned = false;
boolean _EntityEventReturned = false;
boolean _hasEntityDelaration = false;
boolean _exceptionThrown = false;
/** Creates a new instance of StreamReader */
public SupportDTDTest(String name) {
}
void reset() {
_DTDReturned = false;
_EntityEventReturned = false;
_hasEntityDelaration = false;
_exceptionThrown = false;
}
// tests 1-4 test internal entities only
@Test
public void test1() {
supportDTD(true, true, ENTITY_INTERNAL_ONLY);
Assert.assertEquals(true, _DTDReturned);
Assert.assertEquals(true, _hasEntityDelaration);
Assert.assertEquals(false, _EntityEventReturned);
}
@Test
public void test2() {
supportDTD(true, false, ENTITY_INTERNAL_ONLY);
Assert.assertEquals(true, _DTDReturned);
Assert.assertEquals(true, _hasEntityDelaration);
Assert.assertEquals(true, _EntityEventReturned);
}
@Test
public void test3() {
supportDTD(false, true, ENTITY_INTERNAL_ONLY);
Assert.assertEquals(true, _DTDReturned);
Assert.assertEquals(false, _hasEntityDelaration);
Assert.assertEquals(true, _exceptionThrown);
}
@Test
public void test4() {
supportDTD(false, false, ENTITY_INTERNAL_ONLY);
Assert.assertEquals(true, _DTDReturned);
Assert.assertEquals(false, _hasEntityDelaration);
Assert.assertEquals(true, _EntityEventReturned);
}
// tests 5-8 test external entities only
@Test
public void test5() {
supportDTD(true, true, ENTITY_EXTERNAL_ONLY);
Assert.assertEquals(true, _DTDReturned);
Assert.assertEquals(true, _hasEntityDelaration);
Assert.assertEquals(false, _EntityEventReturned);
}
@Test
public void test6() {
supportDTD(true, false, ENTITY_EXTERNAL_ONLY);
Assert.assertEquals(true, _DTDReturned);
Assert.assertEquals(true, _hasEntityDelaration);
Assert.assertEquals(true, _EntityEventReturned);
}
@Test
public void test7() {
supportDTD(false, true, ENTITY_EXTERNAL_ONLY);
Assert.assertEquals(true, _DTDReturned);
Assert.assertEquals(false, _hasEntityDelaration);
Assert.assertEquals(true, _exceptionThrown);
}
@Test
public void test8() {
supportDTD(false, false, ENTITY_EXTERNAL_ONLY);
Assert.assertEquals(true, _DTDReturned);
Assert.assertEquals(false, _hasEntityDelaration);
Assert.assertEquals(true, _EntityEventReturned);
}
// tests 9-12 test both internal and external entities
@Test
public void test9() {
supportDTD(true, true, ENTITY_BOTH);
Assert.assertEquals(true, _DTDReturned);
Assert.assertEquals(true, _hasEntityDelaration);
Assert.assertEquals(false, _EntityEventReturned);
}
@Test
public void test10() {
supportDTD(true, false, ENTITY_BOTH);
Assert.assertEquals(true, _DTDReturned);
Assert.assertEquals(true, _hasEntityDelaration);
Assert.assertEquals(true, _EntityEventReturned);
}
@Test
public void test11() {
supportDTD(false, true, ENTITY_BOTH);
Assert.assertEquals(true, _DTDReturned);
Assert.assertEquals(false, _hasEntityDelaration);
Assert.assertEquals(true, _exceptionThrown);
}
@Test
public void test12() {
supportDTD(false, false, ENTITY_BOTH);
Assert.assertEquals(true, _DTDReturned);
Assert.assertEquals(false, _hasEntityDelaration);
Assert.assertEquals(true, _EntityEventReturned);
}
public void supportDTD(boolean supportDTD, boolean replaceEntity, int inputType) {
reset();
print("\n");
print((supportDTD ? "SupportDTD=true" : "SupportDTD=false") + ", " + (replaceEntity ? "replaceEntity=true" : "replaceEntity=false"));
try {
XMLInputFactory xif = getFactory(supportDTD, replaceEntity);
XMLEventReader r = getEventReader(xif, inputType);
int eventType = 0;
int count = 0;
while (r.hasNext()) {
XMLEvent event = r.nextEvent();
eventType = event.getEventType();
print("Event " + ++count + ": " + eventType);
switch (eventType) {
case XMLStreamConstants.DTD:
DisplayEntities((DTD) event);
_DTDReturned = true;
break;
case XMLStreamConstants.ENTITY_REFERENCE:
print("Entity Name: " + ((EntityReference) event).getName());
_EntityEventReturned = true;
break;
case XMLStreamConstants.CHARACTERS:
print("Text: " + ((Characters) event).getData());
}
}
} catch (Exception e) {
_exceptionThrown = true;
if (DEBUG)
e.printStackTrace();
}
}
XMLInputFactory getFactory(boolean supportDTD, boolean replaceEntity) {
XMLInputFactory xif = XMLInputFactory.newInstance();
xif.setProperty(XMLInputFactory.SUPPORT_DTD, (supportDTD) ? Boolean.TRUE : Boolean.FALSE);
xif.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, (replaceEntity) ? Boolean.TRUE : Boolean.FALSE);
// xif.setProperty(XMLInputFactory.IS_VALIDATING, Boolean.TRUE);
return xif;
}
private XMLEventReader getEventReader(XMLInputFactory inputFactory, int input) throws Exception {
XMLEventReader er = null;
if (input == ENTITY_INTERNAL_ONLY) {
er = inputFactory.createXMLEventReader(new StringReader(XML));
} else if (input == ENTITY_EXTERNAL_ONLY) {
er = inputFactory.createXMLEventReader(new StringReader(XML1));
} else {
File file = new File(this.getClass().getResource(_file).getFile());
FileInputStream inputStream = new FileInputStream(file);
// XMLStreamReader r = xif.createXMLStreamReader(inputStream);
er = inputFactory.createXMLEventReader(inputStream);
}
return er;
}
void DisplayEntities(DTD event) {
List entities = event.getEntities();
if (entities == null) {
_hasEntityDelaration = false;
print("No entity found.");
} else {
_hasEntityDelaration = true;
for (int i = 0; i < entities.size(); i++) {
EntityDeclaration entity = (EntityDeclaration) entities.get(i);
print(entity.getName());
}
}
}
void print(String s) {
if (DEBUG)
System.out.println(s);
}
}