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.Listeners; 42 import org.testng.annotations.Test; 43 44 /* 45 * @summary Test SUPPORT_DTD and IS_REPLACING_ENTITY_REFERENCES. 46 */ 47 48 /** 49 * 50 * SUPPORT_DTD behavior: 51 * Regardless of supportDTD, always report a DTD event () and throw an 52 * exception if an entity reference is found when supportDTD is false 53 * 54 * The behavior is related to property IS_REPLACING_ENTITY_REFERENCES. 55 * 56 * SUPPORT_DTD Replace Entity DTD ENTITY_REFERENCE 57 * true (default) true (default) yes, has entities no, return Characters 58 * true (default) false yes, has entities yes, can print entity name 59 * false true (default) yes, but no entity Exception: Undeclared general entity 60 * false false yes, but no entity yes, can print entity name 61 * 62 * Two patches related: 63 * sjsxp issue 9: XMLDocumentScannerImpl.java rev 1.6 64 * If the supportDTD property is set to FALSE, external and internal subsets 65 * are now ignored, rather than an error being reported. In particular, with 66 * this property set to FALSE, no error is reported if an external subset cannot 67 * be found. Note that the internal subset is still parsed (and errors could be 68 * reported here) but no events are returned by the parser. This fixes SJSXP 69 * issue 9 from Java.net. 70 * Note: SAX and DOM report fatal errors: 71 * If either SAX or DOM is used, turning on http://apache.org/xml/features/disallow-doctype-decl [1] effectively disables DTD, 72 * according to the spec: A fatal error is thrown if the incoming document contains a DOCTYPE declaration. 73 * The current jaxp implementation actually throws a nullpointexception. A better error message could be used. 74 * 75 */ 76 @Listeners({jaxp.library.FilePolicy.class}) 77 public class SupportDTDTest { 78 final boolean DEBUG = false; 79 final String _file = "ExternalDTD.xml"; 80 final String XML = "<?xml version='1.0' ?>" + "<!DOCTYPE root [\n" + "<!ENTITY intEnt 'internal entity'>\n" + "<!ENTITY extParsedEnt SYSTEM 'url:dummy'>\n" 81 + "<!NOTATION notation PUBLIC 'notation-public-id'>\n" + "<!NOTATION notation2 SYSTEM 'url:dummy'>\n" 82 + "<!ENTITY extUnparsedEnt SYSTEM 'url:dummy2' NDATA notation>\n" + "]>" + "<root>&intEnt;</root>"; 83 84 final String XML1 = "<?xml version='1.0' encoding ='utf-8'?>" + "<!DOCTYPE document SYSTEM \"" + this.getClass().getResource("ExternalDTD.dtd").getFile() 85 + "\">" + "<document>" + "<name>&mkm;</name>" + "</document>"; 86 87 // 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>" 88 // + "<name>&mkm;</name>" + "</document>"; 89 90 final int ENTITY_INTERNAL_ONLY = 1; 91 final int ENTITY_EXTERNAL_ONLY = 2; 92 final int ENTITY_BOTH = 3; 93 94 boolean _DTDReturned = false; 95 boolean _EntityEventReturned = false; 96 boolean _hasEntityDelaration = false; 97 boolean _exceptionThrown = false; 98 99 /** Creates a new instance of StreamReader */ 100 public SupportDTDTest(String name) { 101 } 102 103 void reset() { 104 _DTDReturned = false; 105 _EntityEventReturned = false; 106 _hasEntityDelaration = false; 107 _exceptionThrown = false; 108 } 109 110 // tests 1-4 test internal entities only 111 @Test 112 public void test1() { 113 supportDTD(true, true, ENTITY_INTERNAL_ONLY); 114 Assert.assertEquals(true, _DTDReturned); 115 Assert.assertEquals(true, _hasEntityDelaration); 116 Assert.assertEquals(false, _EntityEventReturned); 117 } 118 119 @Test 120 public void test2() { 121 supportDTD(true, false, ENTITY_INTERNAL_ONLY); 122 Assert.assertEquals(true, _DTDReturned); 123 Assert.assertEquals(true, _hasEntityDelaration); 124 Assert.assertEquals(true, _EntityEventReturned); 125 } 126 127 @Test 128 public void test3() { 129 supportDTD(false, true, ENTITY_INTERNAL_ONLY); 130 Assert.assertEquals(true, _DTDReturned); 131 Assert.assertEquals(false, _hasEntityDelaration); 132 Assert.assertEquals(true, _exceptionThrown); 133 } 134 135 @Test 136 public void test4() { 137 supportDTD(false, false, ENTITY_INTERNAL_ONLY); 138 Assert.assertEquals(true, _DTDReturned); 139 Assert.assertEquals(false, _hasEntityDelaration); 140 Assert.assertEquals(true, _EntityEventReturned); 141 } 142 143 // tests 5-8 test external entities only 144 @Test 145 public void test5() { 146 supportDTD(true, true, ENTITY_EXTERNAL_ONLY); 147 Assert.assertEquals(true, _DTDReturned); 148 Assert.assertEquals(true, _hasEntityDelaration); 149 Assert.assertEquals(false, _EntityEventReturned); 150 } 151 152 @Test 153 public void test6() { 154 supportDTD(true, false, ENTITY_EXTERNAL_ONLY); 155 Assert.assertEquals(true, _DTDReturned); 156 Assert.assertEquals(true, _hasEntityDelaration); 157 Assert.assertEquals(true, _EntityEventReturned); 158 } 159 160 @Test 161 public void test7() { 162 supportDTD(false, true, ENTITY_EXTERNAL_ONLY); 163 Assert.assertEquals(true, _DTDReturned); 164 Assert.assertEquals(false, _hasEntityDelaration); 165 Assert.assertEquals(true, _exceptionThrown); 166 } 167 168 @Test 169 public void test8() { 170 supportDTD(false, false, ENTITY_EXTERNAL_ONLY); 171 Assert.assertEquals(true, _DTDReturned); 172 Assert.assertEquals(false, _hasEntityDelaration); 173 Assert.assertEquals(true, _EntityEventReturned); 174 } 175 176 // tests 9-12 test both internal and external entities 177 @Test 178 public void test9() { 179 supportDTD(true, true, ENTITY_BOTH); 180 Assert.assertEquals(true, _DTDReturned); 181 Assert.assertEquals(true, _hasEntityDelaration); 182 Assert.assertEquals(false, _EntityEventReturned); 183 } 184 185 @Test 186 public void test10() { 187 supportDTD(true, false, ENTITY_BOTH); 188 Assert.assertEquals(true, _DTDReturned); 189 Assert.assertEquals(true, _hasEntityDelaration); 190 Assert.assertEquals(true, _EntityEventReturned); 191 } 192 193 @Test 194 public void test11() { 195 supportDTD(false, true, ENTITY_BOTH); 196 Assert.assertEquals(true, _DTDReturned); 197 Assert.assertEquals(false, _hasEntityDelaration); 198 Assert.assertEquals(true, _exceptionThrown); 199 } 200 201 @Test 202 public void test12() { 203 supportDTD(false, false, ENTITY_BOTH); 204 Assert.assertEquals(true, _DTDReturned); 205 Assert.assertEquals(false, _hasEntityDelaration); 206 Assert.assertEquals(true, _EntityEventReturned); 207 } 208 209 public void supportDTD(boolean supportDTD, boolean replaceEntity, int inputType) { 210 reset(); 211 print("\n"); 212 print((supportDTD ? "SupportDTD=true" : "SupportDTD=false") + ", " + (replaceEntity ? "replaceEntity=true" : "replaceEntity=false")); 213 try { 214 XMLInputFactory xif = getFactory(supportDTD, replaceEntity); 215 XMLEventReader r = getEventReader(xif, inputType); 216 int eventType = 0; 217 int count = 0; 218 while (r.hasNext()) { 219 XMLEvent event = r.nextEvent(); 220 eventType = event.getEventType(); 221 print("Event " + ++count + ": " + eventType); 222 switch (eventType) { 223 case XMLStreamConstants.DTD: 224 DisplayEntities((DTD) event); 225 _DTDReturned = true; 226 break; 227 case XMLStreamConstants.ENTITY_REFERENCE: 228 print("Entity Name: " + ((EntityReference) event).getName()); 229 _EntityEventReturned = true; 230 break; 231 case XMLStreamConstants.CHARACTERS: 232 print("Text: " + ((Characters) event).getData()); 233 } 234 } 235 236 } catch (Exception e) { 237 _exceptionThrown = true; 238 if (DEBUG) 239 e.printStackTrace(); 240 } 241 } 242 243 XMLInputFactory getFactory(boolean supportDTD, boolean replaceEntity) { 244 XMLInputFactory xif = XMLInputFactory.newInstance(); 245 xif.setProperty(XMLInputFactory.SUPPORT_DTD, (supportDTD) ? Boolean.TRUE : Boolean.FALSE); 246 xif.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, (replaceEntity) ? Boolean.TRUE : Boolean.FALSE); 247 // xif.setProperty(XMLInputFactory.IS_VALIDATING, Boolean.TRUE); 248 return xif; 249 } 250 251 private XMLEventReader getEventReader(XMLInputFactory inputFactory, int input) throws Exception { 252 XMLEventReader er = null; 253 if (input == ENTITY_INTERNAL_ONLY) { 254 er = inputFactory.createXMLEventReader(new StringReader(XML)); 255 } else if (input == ENTITY_EXTERNAL_ONLY) { 256 er = inputFactory.createXMLEventReader(new StringReader(XML1)); 257 } else { 258 File file = new File(this.getClass().getResource(_file).getFile()); 259 FileInputStream inputStream = new FileInputStream(file); 260 // XMLStreamReader r = xif.createXMLStreamReader(inputStream); 261 er = inputFactory.createXMLEventReader(inputStream); 262 } 263 return er; 264 } 265 266 void DisplayEntities(DTD event) { 267 List entities = event.getEntities(); 268 if (entities == null) { 269 _hasEntityDelaration = false; 270 print("No entity found."); 271 } else { 272 _hasEntityDelaration = true; 273 for (int i = 0; i < entities.size(); i++) { 274 EntityDeclaration entity = (EntityDeclaration) entities.get(i); 275 print(entity.getName()); 276 } 277 } 278 279 } 280 281 void print(String s) { 282 if (DEBUG) 283 System.out.println(s); 284 } 285 286 }