1 /* 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package stream.XMLStreamReaderTest; 25 26 import java.io.File; 27 import java.io.FileInputStream; 28 import java.io.StringReader; 29 import java.util.List; 30 31 import javax.xml.stream.XMLEventReader; 32 import javax.xml.stream.XMLInputFactory; 33 import javax.xml.stream.XMLStreamConstants; 34 import javax.xml.stream.events.Characters; 35 import javax.xml.stream.events.DTD; 36 import javax.xml.stream.events.EntityDeclaration; 37 import javax.xml.stream.events.EntityReference; 38 import javax.xml.stream.events.XMLEvent; 39 40 import org.testng.Assert; 41 import org.testng.annotations.Test; 42 43 /* 44 * @summary Test SUPPORT_DTD and IS_REPLACING_ENTITY_REFERENCES. 45 */ 46 47 /** 48 * 49 * SUPPORT_DTD behavior: 50 * Regardless of supportDTD, always report a DTD event () and throw an 51 * exception if an entity reference is found when supportDTD is false 52 * 53 * The behavior is related to property IS_REPLACING_ENTITY_REFERENCES. 54 * 55 * SUPPORT_DTD Replace Entity DTD ENTITY_REFERENCE 56 * true (default) true (default) yes, has entities no, return Characters 57 * true (default) false yes, has entities yes, can print entity name 58 * false true (default) yes, but no entity Exception: Undeclared general entity 59 * false false yes, but no entity yes, can print entity name 60 * 61 * Two patches related: 62 * sjsxp issue 9: XMLDocumentScannerImpl.java rev 1.6 63 * If the supportDTD property is set to FALSE, external and internal subsets 64 * are now ignored, rather than an error being reported. In particular, with 65 * this property set to FALSE, no error is reported if an external subset cannot 66 * be found. Note that the internal subset is still parsed (and errors could be 67 * reported here) but no events are returned by the parser. This fixes SJSXP 68 * issue 9 from Java.net. 69 * Note: SAX and DOM report fatal errors: 70 * If either SAX or DOM is used, turning on http://apache.org/xml/features/disallow-doctype-decl [1] effectively disables DTD, 71 * according to the spec: A fatal error is thrown if the incoming document contains a DOCTYPE declaration. 72 * The current jaxp implementation actually throws a nullpointexception. A better error message could be used. 73 * 74 */ 75 public class SupportDTDTest { 76 final boolean DEBUG = false; 77 final String _file = "ExternalDTD.xml"; 78 final String XML = "<?xml version='1.0' ?>" + "<!DOCTYPE root [\n" + "<!ENTITY intEnt 'internal entity'>\n" + "<!ENTITY extParsedEnt SYSTEM 'url:dummy'>\n" 79 + "<!NOTATION notation PUBLIC 'notation-public-id'>\n" + "<!NOTATION notation2 SYSTEM 'url:dummy'>\n" 80 + "<!ENTITY extUnparsedEnt SYSTEM 'url:dummy2' NDATA notation>\n" + "]>" + "<root>&intEnt;</root>"; 81 82 final String XML1 = "<?xml version='1.0' encoding ='utf-8'?>" + "<!DOCTYPE document SYSTEM \"" + this.getClass().getResource("ExternalDTD.dtd").getFile() 83 + "\">" + "<document>" + "<name>&mkm;</name>" + "</document>"; 84 85 // 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>" 86 // + "<name>&mkm;</name>" + "</document>"; 87 88 final int ENTITY_INTERNAL_ONLY = 1; 89 final int ENTITY_EXTERNAL_ONLY = 2; 90 final int ENTITY_BOTH = 3; 91 92 boolean _DTDReturned = false; 93 boolean _EntityEventReturned = false; 94 boolean _hasEntityDelaration = false; 95 boolean _exceptionThrown = false; 96 97 /** Creates a new instance of StreamReader */ 98 public SupportDTDTest(String name) { 99 } 100 101 void reset() { 102 _DTDReturned = false; 103 _EntityEventReturned = false; 104 _hasEntityDelaration = false; 105 _exceptionThrown = false; 106 } 107 108 // tests 1-4 test internal entities only 109 @Test 110 public void test1() { 111 supportDTD(true, true, ENTITY_INTERNAL_ONLY); 112 Assert.assertEquals(true, _DTDReturned); 113 Assert.assertEquals(true, _hasEntityDelaration); 114 Assert.assertEquals(false, _EntityEventReturned); 115 } 116 117 @Test 118 public void test2() { 119 supportDTD(true, false, ENTITY_INTERNAL_ONLY); 120 Assert.assertEquals(true, _DTDReturned); 121 Assert.assertEquals(true, _hasEntityDelaration); 122 Assert.assertEquals(true, _EntityEventReturned); 123 } 124 125 @Test 126 public void test3() { 127 supportDTD(false, true, ENTITY_INTERNAL_ONLY); 128 Assert.assertEquals(true, _DTDReturned); 129 Assert.assertEquals(false, _hasEntityDelaration); 130 Assert.assertEquals(true, _exceptionThrown); 131 } 132 133 @Test 134 public void test4() { 135 supportDTD(false, false, ENTITY_INTERNAL_ONLY); 136 Assert.assertEquals(true, _DTDReturned); 137 Assert.assertEquals(false, _hasEntityDelaration); 138 Assert.assertEquals(true, _EntityEventReturned); 139 } 140 141 // tests 5-8 test external entities only 142 @Test 143 public void test5() { 144 supportDTD(true, true, ENTITY_EXTERNAL_ONLY); 145 Assert.assertEquals(true, _DTDReturned); 146 Assert.assertEquals(true, _hasEntityDelaration); 147 Assert.assertEquals(false, _EntityEventReturned); 148 } 149 150 @Test 151 public void test6() { 152 supportDTD(true, false, ENTITY_EXTERNAL_ONLY); 153 Assert.assertEquals(true, _DTDReturned); 154 Assert.assertEquals(true, _hasEntityDelaration); 155 Assert.assertEquals(true, _EntityEventReturned); 156 } 157 158 @Test 159 public void test7() { 160 supportDTD(false, true, ENTITY_EXTERNAL_ONLY); 161 Assert.assertEquals(true, _DTDReturned); 162 Assert.assertEquals(false, _hasEntityDelaration); 163 Assert.assertEquals(true, _exceptionThrown); 164 } 165 166 @Test 167 public void test8() { 168 supportDTD(false, false, ENTITY_EXTERNAL_ONLY); 169 Assert.assertEquals(true, _DTDReturned); 170 Assert.assertEquals(false, _hasEntityDelaration); 171 Assert.assertEquals(true, _EntityEventReturned); 172 } 173 174 // tests 9-12 test both internal and external entities 175 @Test 176 public void test9() { 177 supportDTD(true, true, ENTITY_BOTH); 178 Assert.assertEquals(true, _DTDReturned); 179 Assert.assertEquals(true, _hasEntityDelaration); 180 Assert.assertEquals(false, _EntityEventReturned); 181 } 182 183 @Test 184 public void test10() { 185 supportDTD(true, false, ENTITY_BOTH); 186 Assert.assertEquals(true, _DTDReturned); 187 Assert.assertEquals(true, _hasEntityDelaration); 188 Assert.assertEquals(true, _EntityEventReturned); 189 } 190 191 @Test 192 public void test11() { 193 supportDTD(false, true, ENTITY_BOTH); 194 Assert.assertEquals(true, _DTDReturned); 195 Assert.assertEquals(false, _hasEntityDelaration); 196 Assert.assertEquals(true, _exceptionThrown); 197 } 198 199 @Test 200 public void test12() { 201 supportDTD(false, false, ENTITY_BOTH); 202 Assert.assertEquals(true, _DTDReturned); 203 Assert.assertEquals(false, _hasEntityDelaration); 204 Assert.assertEquals(true, _EntityEventReturned); 205 } 206 207 public void supportDTD(boolean supportDTD, boolean replaceEntity, int inputType) { 208 reset(); 209 print("\n"); 210 print((supportDTD ? "SupportDTD=true" : "SupportDTD=false") + ", " + (replaceEntity ? "replaceEntity=true" : "replaceEntity=false")); 211 try { 212 XMLInputFactory xif = getFactory(supportDTD, replaceEntity); 213 XMLEventReader r = getEventReader(xif, inputType); 214 int eventType = 0; 215 int count = 0; 216 while (r.hasNext()) { 217 XMLEvent event = r.nextEvent(); 218 eventType = event.getEventType(); 219 print("Event " + ++count + ": " + eventType); 220 switch (eventType) { 221 case XMLStreamConstants.DTD: 222 DisplayEntities((DTD) event); 223 _DTDReturned = true; 224 break; 225 case XMLStreamConstants.ENTITY_REFERENCE: 226 print("Entity Name: " + ((EntityReference) event).getName()); 227 _EntityEventReturned = true; 228 break; 229 case XMLStreamConstants.CHARACTERS: 230 print("Text: " + ((Characters) event).getData()); 231 } 232 } 233 234 } catch (Exception e) { 235 _exceptionThrown = true; 236 if (DEBUG) 237 e.printStackTrace(); 238 } 239 } 240 241 XMLInputFactory getFactory(boolean supportDTD, boolean replaceEntity) { 242 XMLInputFactory xif = XMLInputFactory.newInstance(); 243 xif.setProperty(XMLInputFactory.SUPPORT_DTD, (supportDTD) ? Boolean.TRUE : Boolean.FALSE); 244 xif.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, (replaceEntity) ? Boolean.TRUE : Boolean.FALSE); 245 // xif.setProperty(XMLInputFactory.IS_VALIDATING, Boolean.TRUE); 246 return xif; 247 } 248 249 private XMLEventReader getEventReader(XMLInputFactory inputFactory, int input) throws Exception { 250 XMLEventReader er = null; 251 if (input == ENTITY_INTERNAL_ONLY) { 252 er = inputFactory.createXMLEventReader(new StringReader(XML)); 253 } else if (input == ENTITY_EXTERNAL_ONLY) { 254 er = inputFactory.createXMLEventReader(new StringReader(XML1)); 255 } else { 256 File file = new File(this.getClass().getResource(_file).getFile()); 257 FileInputStream inputStream = new FileInputStream(file); 258 // XMLStreamReader r = xif.createXMLStreamReader(inputStream); 259 er = inputFactory.createXMLEventReader(inputStream); 260 } 261 return er; 262 } 263 264 void DisplayEntities(DTD event) { 265 List entities = event.getEntities(); 266 if (entities == null) { 267 _hasEntityDelaration = false; 268 print("No entity found."); 269 } else { 270 _hasEntityDelaration = true; 271 for (int i = 0; i < entities.size(); i++) { 272 EntityDeclaration entity = (EntityDeclaration) entities.get(i); 273 print(entity.getName()); 274 } 275 } 276 277 } 278 279 void print(String s) { 280 if (DEBUG) 281 System.out.println(s); 282 } 283 284 }