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