1 /* 2 * Copyright (c) 2014, 2015, 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 parsers; 25 26 import java.io.File; 27 import java.io.InputStream; 28 29 import javax.xml.XMLConstants; 30 import javax.xml.parsers.DocumentBuilder; 31 import javax.xml.parsers.DocumentBuilderFactory; 32 import javax.xml.parsers.SAXParser; 33 import javax.xml.parsers.SAXParserFactory; 34 35 import org.testng.Assert; 36 import org.testng.annotations.Test; 37 import org.w3c.dom.Document; 38 import org.xml.sax.SAXParseException; 39 40 /* 41 * @bug 6309988 42 * @summary Test elementAttributeLimit, maxOccurLimit, entityExpansionLimit. 43 */ 44 public class Bug6309988 { 45 46 DocumentBuilderFactory dbf = null; 47 static boolean _isSecureMode = false; 48 static { 49 if (System.getSecurityManager() != null) { 50 _isSecureMode = true; 51 System.out.println("Security Manager is present"); 52 } else { 53 System.out.println("Security Manager is NOT present"); 54 } 55 } 56 57 /* 58 * Given XML document has more than 10000 attributes. Exception is expected 59 */ 60 @Test 61 public void testDOMParserElementAttributeLimit() { 62 try { 63 dbf = DocumentBuilderFactory.newInstance(); 64 DocumentBuilder parser = dbf.newDocumentBuilder(); 65 Document doc = parser.parse(this.getClass().getResourceAsStream("DosTest.xml")); 66 Assert.fail("SAXParserException is expected, as given XML document contains more than 10000 attributes"); 67 } catch (SAXParseException e) { 68 System.out.println(e.getMessage()); 69 } catch (Exception e) { 70 Assert.fail("Exception " + e.getMessage()); 71 } 72 } 73 74 /* 75 * Given XML document has more than 10000 attributes. It should report an 76 * error. 77 */ 78 @Test 79 public void testDOMNSParserElementAttributeLimit() { 80 try { 81 dbf = DocumentBuilderFactory.newInstance(); 82 dbf.setNamespaceAware(true); 83 DocumentBuilder parser = dbf.newDocumentBuilder(); 84 Document doc = parser.parse(this.getClass().getResourceAsStream("DosTest.xml")); 85 Assert.fail("SAXParserException is expected, as given XML document contains more than 10000 attributes"); 86 } catch (SAXParseException e) { 87 System.out.println(e.getMessage()); 88 } catch (Exception e) { 89 Assert.fail("Exception " + e.getMessage()); 90 } 91 } 92 93 /* 94 * Given XML document has more than 10000 attributes. Parsing this XML 95 * document in non-secure mode, should not report any error. 96 */ 97 @Test 98 public void testDOMNSParserElementAttributeLimitWithoutSecureProcessing() { 99 if (_isSecureMode) 100 return; // jaxp secure feature can not be turned off when security 101 // manager is present 102 try { 103 dbf = DocumentBuilderFactory.newInstance(); 104 dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false); 105 dbf.setNamespaceAware(true); 106 DocumentBuilder parser = dbf.newDocumentBuilder(); 107 Document doc = parser.parse(this.getClass().getResourceAsStream("DosTest.xml")); 108 109 } catch (SAXParseException e) { 110 Assert.fail(e.getMessage()); 111 } catch (Exception e) { 112 Assert.fail("Exception " + e.getMessage()); 113 } 114 } 115 116 /* 117 * Before 8014530: Given XML document has 3 attributes and System property 118 * is set to 2. Parsing this XML document in non-secure mode, should not 119 * report an error. 120 * After 8014530: System properties will override FSP, the result of this 121 * test should be the same as 122 * testSystemElementAttributeLimitWithSecureProcessing 123 */ 124 @Test 125 public void testSystemElementAttributeLimitWithoutSecureProcessing() { 126 if (_isSecureMode) 127 return; // jaxp secure feature can not be turned off when security 128 // manager is present 129 try { 130 dbf = DocumentBuilderFactory.newInstance(); 131 dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false); 132 dbf.setNamespaceAware(true); 133 System.setProperty("elementAttributeLimit", "2"); 134 DocumentBuilder parser = dbf.newDocumentBuilder(); 135 Document doc = parser.parse(this.getClass().getResourceAsStream("DosTest3.xml")); 136 137 Assert.fail("SAXParserException is expected, as given XML document contains more than 2 attributes"); 138 } catch (Exception e) { 139 String errMsg = e.getMessage(); 140 Throwable cause = e.getCause(); 141 if (cause != null) { 142 errMsg += cause.getMessage(); 143 } 144 if (errMsg.contains("JAXP0001")) { 145 // expected 146 } else { 147 Assert.fail("Unexpected error: " + e.getMessage()); 148 } 149 } finally { 150 System.clearProperty("elementAttributeLimit"); 151 } 152 } 153 154 /* 155 * Given XML document has 3 attributes and System property is set to 2. 156 * Parsing this XML document in secure mode, should report an error. 157 */ 158 @Test 159 public void testSystemElementAttributeLimitWithSecureProcessing() { 160 try { 161 dbf = DocumentBuilderFactory.newInstance(); 162 dbf.setNamespaceAware(true); 163 System.setProperty("elementAttributeLimit", "2"); 164 DocumentBuilder parser = dbf.newDocumentBuilder(); 165 Document doc = parser.parse(this.getClass().getResourceAsStream("DosTest3.xml")); 166 Assert.fail("SAXParserException is expected, as given XML document contains more than 2 attributes"); 167 } catch (SAXParseException e) { 168 System.out.println(e.getMessage()); 169 } catch (Exception e) { 170 Assert.fail("Exception " + e.getMessage()); 171 } finally { 172 System.setProperty("elementAttributeLimit", ""); 173 } 174 } 175 176 /* 177 * Default value for secure processing feature should be true. 178 */ 179 @Test 180 public void testDOMSecureProcessingDefaultValue() { 181 try { 182 dbf = DocumentBuilderFactory.newInstance(); 183 Assert.assertTrue(dbf.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING), "Default value for secureProcessing feature should be true"); 184 185 } catch (Exception e) { 186 Assert.fail("Exception " + e.getMessage()); 187 } 188 } 189 190 /* 191 * Default value for secure processing feature should be true. 192 */ 193 @Test 194 public void testSAXSecureProcessingDefaultValue() { 195 try { 196 SAXParserFactory spf = SAXParserFactory.newInstance(); 197 Assert.assertTrue(spf.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING), "Default value for secureProcessing feature should be true"); 198 199 } catch (Exception e) { 200 Assert.fail("Exception " + e.getMessage()); 201 } 202 } 203 204 /* 205 * This method sets system property for maxOccurLimit=2 and secure process 206 * feature is off. Given doument contains more than 2 elements and hence an 207 * error should be reported. 208 */ 209 @Test 210 public void testSystemMaxOccurLimitWithoutSecureProcessing() { 211 if (_isSecureMode) 212 return; // jaxp secure feature can not be turned off when security 213 // manager is present 214 try { 215 SAXParserFactory spf = SAXParserFactory.newInstance(); 216 spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false); 217 spf.setValidating(true); 218 System.setProperty("maxOccurLimit", "2"); 219 // Set the properties for Schema Validation 220 String SCHEMA_LANG = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; 221 String SCHEMA_TYPE = "http://www.w3.org/2001/XMLSchema"; 222 // Get the Schema location as a File object 223 File schemaFile = new File(this.getClass().getResource("toys.xsd").toURI()); 224 // Get the parser 225 SAXParser parser = spf.newSAXParser(); 226 parser.setProperty(SCHEMA_LANG, SCHEMA_TYPE); 227 parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", schemaFile); 228 229 InputStream is = this.getClass().getResourceAsStream("toys.xml"); 230 MyErrorHandler eh = new MyErrorHandler(); 231 parser.parse(is, eh); 232 Assert.assertFalse(eh.errorOccured, "Not Expected Error"); 233 System.setProperty("maxOccurLimit", ""); 234 } catch (Exception e) { 235 Assert.fail("Exception occured: " + e.getMessage()); 236 } 237 } 238 239 /* 240 * This test will take longer time to execute( abt 120sec). This method 241 * tries to validate a document. This document contains an element whose 242 * maxOccur is '3002'. Since secure processing feature is off, document 243 * should be parsed without any errors. 244 */ 245 @Test 246 public void testValidMaxOccurLimitWithOutSecureProcessing() { 247 if (_isSecureMode) 248 return; // jaxp secure feature can not be turned off when security 249 // manager is present 250 try { 251 SAXParserFactory spf = SAXParserFactory.newInstance(); 252 spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false); 253 spf.setValidating(true); 254 // Set the properties for Schema Validation 255 String SCHEMA_LANG = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; 256 String SCHEMA_TYPE = "http://www.w3.org/2001/XMLSchema"; 257 // Get the Schema location as a File object 258 File schemaFile = new File(this.getClass().getResource("toys3002.xsd").toURI()); 259 // Get the parser 260 SAXParser parser = spf.newSAXParser(); 261 parser.setProperty(SCHEMA_LANG, SCHEMA_TYPE); 262 parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", schemaFile); 263 264 InputStream is = this.getClass().getResourceAsStream("toys.xml"); 265 MyErrorHandler eh = new MyErrorHandler(); 266 parser.parse(is, eh); 267 Assert.assertFalse(eh.errorOccured, "Expected Error as maxOccurLimit is exceeded"); 268 269 } catch (Exception e) { 270 Assert.fail("Exception occured: " + e.getMessage()); 271 } 272 } 273 274 /* 275 * Before 8014530: System property is set to 2. Given XML document has more 276 * than 2 entity references. Parsing this document in non-secure mode, 277 * should *not* report an error. 278 * After 8014530: System properties will override FSP, the result of this 279 * test should be the same as 280 * testSystemElementAttributeLimitWithSecureProcessing 281 */ 282 @Test 283 public void testSystemEntityExpansionLimitWithOutSecureProcessing() { 284 if (_isSecureMode) 285 return; // jaxp secure feature can not be turned off when security 286 // manager is present 287 try { 288 System.setProperty("entityExpansionLimit", "2"); 289 dbf = DocumentBuilderFactory.newInstance(); 290 dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false); 291 dbf.setValidating(true); 292 DocumentBuilder parser = dbf.newDocumentBuilder(); 293 Document doc = parser.parse(this.getClass().getResourceAsStream("entity.xml")); 294 Assert.fail("SAXParserException is expected, as given XML document contains more 2 entity references"); 295 } catch (Exception e) { 296 String errMsg = e.getMessage(); 297 Throwable cause = e.getCause(); 298 if (cause != null) { 299 errMsg += cause.getMessage(); 300 } 301 if (errMsg.contains("JAXP0001")) { 302 // expected 303 } else { 304 Assert.fail("Unexpected error: " + e.getMessage()); 305 } 306 } finally { 307 System.clearProperty("entityExpansionLimit"); 308 } 309 } 310 311 /* 312 * System property is set to 2. Given XML document has more than 2 entity 313 * references. Parsing this document in secure mode, should report an error. 314 */ 315 @Test 316 public void testSystemEntityExpansionLimitWithSecureProcessing() { 317 try { 318 dbf = DocumentBuilderFactory.newInstance(); 319 dbf.setValidating(true); 320 System.setProperty("entityExpansionLimit", "2"); 321 DocumentBuilder parser = dbf.newDocumentBuilder(); 322 Document doc = parser.parse(this.getClass().getResourceAsStream("entity.xml")); 323 Assert.fail("SAXParserException is expected, as given XML document contains more 2 entity references"); 324 325 } catch (SAXParseException e) { 326 System.out.println(e.getMessage()); 327 } catch (Exception e) { 328 Assert.fail("Exception " + e.getMessage()); 329 } finally { 330 System.setProperty("entityExpansionLimit", ""); 331 } 332 } 333 334 /* 335 * Given XML document has more than 64000 entity references. Parsing this 336 * document in secure mode, should report an error. 337 */ 338 @Test 339 public void testEntityExpansionLimitWithSecureProcessing() { 340 try { 341 dbf = DocumentBuilderFactory.newInstance(); 342 dbf.setValidating(true); 343 DocumentBuilder parser = dbf.newDocumentBuilder(); 344 Document doc = parser.parse(this.getClass().getResourceAsStream("entity64K.xml")); 345 Assert.fail("SAXParserException is expected, as given XML document contains more 2 entity references"); 346 347 } catch (SAXParseException e) { 348 System.out.println(e.getMessage()); 349 } catch (Exception e) { 350 Assert.fail("Exception " + e.getMessage()); 351 } finally { 352 System.setProperty("entityExpansionLimit", ""); 353 } 354 } 355 356 /* 357 * Given XML document has more than 64000 entity references. Parsing this 358 * document in non-secure mode, should not report any error. 359 */ 360 @Test 361 public void testEntityExpansionLimitWithOutSecureProcessing() { 362 if (_isSecureMode) 363 return; // jaxp secure feature can not be turned off when security 364 // manager is present 365 try { 366 dbf = DocumentBuilderFactory.newInstance(); 367 dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false); 368 dbf.setValidating(true); 369 DocumentBuilder parser = dbf.newDocumentBuilder(); 370 Document doc = parser.parse(this.getClass().getResourceAsStream("entity64K.xml")); 371 372 } catch (SAXParseException e) { 373 Assert.fail("Exception " + e.getMessage()); 374 } catch (Exception e) { 375 Assert.fail("Exception " + e.getMessage()); 376 } finally { 377 System.setProperty("entityExpansionLimit", ""); 378 } 379 } 380 }