1 /* 2 * Copyright (c) 2003, 2016, 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 package test.auctionportal; 24 25 import static jaxp.library.JAXPTestUtilities.setSystemProperty; 26 27 import static javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING; 28 import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; 29 import static jaxp.library.JAXPTestUtilities.USER_DIR; 30 import static jaxp.library.JAXPTestUtilities.compareDocumentWithGold; 31 import static org.testng.Assert.assertFalse; 32 import static org.testng.Assert.assertTrue; 33 import static test.auctionportal.HiBidConstants.GOLDEN_DIR; 34 import static test.auctionportal.HiBidConstants.JAXP_SCHEMA_LANGUAGE; 35 import static test.auctionportal.HiBidConstants.JAXP_SCHEMA_SOURCE; 36 import static test.auctionportal.HiBidConstants.SP_ENTITY_EXPANSION_LIMIT; 37 import static test.auctionportal.HiBidConstants.SP_MAX_OCCUR_LIMIT; 38 import static test.auctionportal.HiBidConstants.XML_DIR; 39 40 import java.io.File; 41 import java.io.FileInputStream; 42 import java.io.FileOutputStream; 43 import java.io.InputStream; 44 45 import javax.xml.parsers.DocumentBuilder; 46 import javax.xml.parsers.DocumentBuilderFactory; 47 import javax.xml.parsers.SAXParser; 48 import javax.xml.parsers.SAXParserFactory; 49 import javax.xml.transform.TransformerFactory; 50 import javax.xml.transform.dom.DOMSource; 51 import javax.xml.transform.stream.StreamResult; 52 53 import org.testng.annotations.Listeners; 54 import org.testng.annotations.Test; 55 import org.w3c.dom.Document; 56 import org.xml.sax.SAXParseException; 57 58 /** 59 * This is a test class for the Auction portal HiBid.com. 60 */ 61 /* 62 * @test 63 * @library /javax/xml/jaxp/libs 64 * @run testng/othervm -DrunSecMngr=true test.auctionportal.AuctionItemRepository 65 * @run testng/othervm test.auctionportal.AuctionItemRepository 66 */ 67 @Listeners({jaxp.library.FilePolicy.class}) 68 public class AuctionItemRepository { 69 /** 70 * XML file for parsing. 71 */ 72 private final static String ENTITY_XML = XML_DIR + "entity.xml"; 73 74 /** 75 * Feature name. 76 */ 77 private final static String FEATURE_NAME = "http://xml.org/sax/features/namespace-prefixes"; 78 79 /** 80 * Setting the EntityExpansion Limit to 128000 and checks if the XML 81 * document that has more than two levels of entity expansion is parsed or 82 * not. Previous system property was changed to jdk.xml.entityExpansionLimit 83 * see http://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html. 84 * 85 * @throws Exception If any errors occur. 86 */ 87 @Test 88 public void testEntityExpansionSAXPos() throws Exception { 89 SAXParserFactory factory = SAXParserFactory.newInstance(); 90 // Secure processing will limit XML processing to conform to 91 // implementation limits. 92 factory.setFeature(FEATURE_SECURE_PROCESSING, true); 93 // Set entityExpansionLimit as 2 should expect fatalError 94 setSystemProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(128000)); 95 SAXParser parser = factory.newSAXParser(); 96 97 MyErrorHandler fatalHandler = new MyErrorHandler(); 98 parser.parse(new File(ENTITY_XML), fatalHandler); 99 assertFalse(fatalHandler.isAnyError()); 100 } 101 /** 102 * Setting the EntityExpansion Limit to 2 and checks if the XML 103 * document that has more than two levels of entity expansion is parsed or 104 * not. Previous system property was changed to jdk.xml.entityExpansionLimit 105 * see http://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html. 106 * 107 * @throws Exception If any errors occur. 108 */ 109 @Test(expectedExceptions = SAXParseException.class) 110 public void testEntityExpansionSAXNeg() throws Exception { 111 SAXParserFactory factory = SAXParserFactory.newInstance(); 112 // Secure processing will limit XML processing to conform to 113 // implementation limits. 114 factory.setFeature(FEATURE_SECURE_PROCESSING, true); 115 // Set entityExpansionLimit as 2 should expect SAXParseException. 116 setSystemProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(2)); 117 118 SAXParser parser = factory.newSAXParser(); 119 MyErrorHandler fatalHandler = new MyErrorHandler(); 120 parser.parse(new File(ENTITY_XML), fatalHandler); 121 } 122 123 /** 124 * Testing set MaxOccursLimit to 10000 in the secure processing enabled for 125 * SAXParserFactory. 126 * 127 * @throws Exception If any errors occur. 128 */ 129 @Test 130 public void testMaxOccurLimitPos() throws Exception { 131 String schema_file = XML_DIR + "toys.xsd"; 132 String xml_file = XML_DIR + "toys.xml"; 133 SAXParserFactory factory = SAXParserFactory.newInstance(); 134 factory.setValidating(true); 135 factory.setFeature(FEATURE_SECURE_PROCESSING, true); 136 setSystemProperty(SP_MAX_OCCUR_LIMIT, String.valueOf(10000)); 137 SAXParser parser = factory.newSAXParser(); 138 parser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); 139 parser.setProperty(JAXP_SCHEMA_SOURCE, new File(schema_file)); 140 try (InputStream is = new FileInputStream(xml_file)) { 141 MyErrorHandler eh = new MyErrorHandler(); 142 parser.parse(is, eh); 143 assertFalse(eh.isAnyError()); 144 } 145 } 146 147 /** 148 * Use a DocumentBuilder to create a DOM object and see if Secure Processing 149 * feature affects the entity expansion. 150 * 151 * @throws Exception If any errors occur. 152 */ 153 @Test 154 public void testEntityExpansionDOMPos() throws Exception { 155 DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); 156 dfactory.setFeature(FEATURE_SECURE_PROCESSING, true); 157 setSystemProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(10000)); 158 DocumentBuilder dBuilder = dfactory.newDocumentBuilder(); 159 MyErrorHandler eh = new MyErrorHandler(); 160 dBuilder.setErrorHandler(eh); 161 dBuilder.parse(ENTITY_XML); 162 assertFalse(eh.isAnyError()); 163 } 164 165 /** 166 * Use a DocumentBuilder to create a DOM object and see how does the Secure 167 * Processing feature and entityExpansionLimit value affects output. 168 * Negative test that when entityExpansionLimit is too small. 169 * 170 * @throws Exception If any errors occur. 171 */ 172 @Test(expectedExceptions = SAXParseException.class) 173 public void testEntityExpansionDOMNeg() throws Exception { 174 DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); 175 dfactory.setFeature(FEATURE_SECURE_PROCESSING, true); 176 setSystemProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(2)); 177 DocumentBuilder dBuilder = dfactory.newDocumentBuilder(); 178 MyErrorHandler eh = new MyErrorHandler(); 179 dBuilder.setErrorHandler(eh); 180 dBuilder.parse(ENTITY_XML); 181 } 182 183 /** 184 * Test xi:include with a SAXParserFactory. 185 * 186 * @throws Exception If any errors occur. 187 */ 188 @Test(groups = {"readWriteLocalFiles"}) 189 public void testXIncludeSAXPos() throws Exception { 190 String resultFile = USER_DIR + "doc_xinclude.out"; 191 String goldFile = GOLDEN_DIR + "doc_xincludeGold.xml"; 192 String xmlFile = XML_DIR + "doc_xinclude.xml"; 193 194 try(FileOutputStream fos = new FileOutputStream(resultFile)) { 195 XInclHandler xh = new XInclHandler(fos, null); 196 SAXParserFactory spf = SAXParserFactory.newInstance(); 197 spf.setNamespaceAware(true); 198 spf.setXIncludeAware(true); 199 spf.setFeature(FEATURE_NAME, true); 200 spf.newSAXParser().parse(new File(xmlFile), xh); 201 } 202 assertTrue(compareDocumentWithGold(goldFile, resultFile)); 203 } 204 205 /** 206 * Test the simple case of including a document using xi:include using a 207 * DocumentBuilder. 208 * 209 * @throws Exception If any errors occur. 210 */ 211 @Test(groups = {"readWriteLocalFiles"}) 212 public void testXIncludeDOMPos() throws Exception { 213 String resultFile = USER_DIR + "doc_xincludeDOM.out"; 214 String goldFile = GOLDEN_DIR + "doc_xincludeGold.xml"; 215 String xmlFile = XML_DIR + "doc_xinclude.xml"; 216 try (FileOutputStream fos = new FileOutputStream(resultFile)) { 217 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 218 dbf.setXIncludeAware(true); 219 dbf.setNamespaceAware(true); 220 Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); 221 doc.setXmlStandalone(true); 222 TransformerFactory.newInstance().newTransformer(). 223 transform(new DOMSource(doc), new StreamResult(fos)); 224 } 225 assertTrue(compareDocumentWithGold(goldFile, resultFile)); 226 } 227 228 /** 229 * Test the simple case of including a document using xi:include within a 230 * xi:fallback using a DocumentBuilder. 231 * 232 * @throws Exception If any errors occur. 233 */ 234 @Test(groups = {"readWriteLocalFiles"}) 235 public void testXIncludeFallbackDOMPos() throws Exception { 236 String resultFile = USER_DIR + "doc_fallbackDOM.out"; 237 String goldFile = GOLDEN_DIR + "doc_fallbackGold.xml"; 238 String xmlFile = XML_DIR + "doc_fallback.xml"; 239 try (FileOutputStream fos = new FileOutputStream(resultFile)) { 240 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 241 dbf.setXIncludeAware(true); 242 dbf.setNamespaceAware(true); 243 244 Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); 245 doc.setXmlStandalone(true); 246 TransformerFactory.newInstance().newTransformer() 247 .transform(new DOMSource(doc), new StreamResult(fos)); 248 } 249 assertTrue(compareDocumentWithGold(goldFile, resultFile)); 250 } 251 252 /** 253 * Test for xi:fallback where the fall back text is parsed as text. This 254 * test uses a nested xi:include for the fallback test. 255 * 256 * @throws Exception If any errors occur. 257 */ 258 @Test(groups = {"readWriteLocalFiles"}) 259 public void testXIncludeFallbackTextPos() throws Exception { 260 String resultFile = USER_DIR + "doc_fallback_text.out"; 261 String goldFile = GOLDEN_DIR + "doc_fallback_textGold.xml"; 262 String xmlFile = XML_DIR + "doc_fallback_text.xml"; 263 try (FileOutputStream fos = new FileOutputStream(resultFile)) { 264 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 265 dbf.setXIncludeAware(true); 266 dbf.setNamespaceAware(true); 267 268 Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); 269 doc.setXmlStandalone(true); 270 TransformerFactory.newInstance().newTransformer() 271 .transform(new DOMSource(doc), new StreamResult(fos)); 272 } 273 assertTrue(compareDocumentWithGold(goldFile, resultFile)); 274 } 275 276 /** 277 * Test the XPointer element() framework with XInclude. 278 * 279 * @throws Exception If any errors occur. 280 */ 281 @Test(groups = {"readWriteLocalFiles"}) 282 public void testXpointerElementPos() throws Exception { 283 String resultFile = USER_DIR + "doc_xpointer_element.out"; 284 String goldFile = GOLDEN_DIR + "doc_xpointerGold.xml"; 285 String xmlFile = XML_DIR + "doc_xpointer_element.xml"; 286 try (FileOutputStream fos = new FileOutputStream(resultFile)) { 287 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 288 dbf.setXIncludeAware(true); 289 dbf.setNamespaceAware(true); 290 291 DocumentBuilder db = dbf.newDocumentBuilder(); 292 293 TransformerFactory.newInstance().newTransformer() 294 .transform(new DOMSource(db.parse(new File(xmlFile))), 295 new StreamResult(fos)); 296 } 297 assertTrue(compareDocumentWithGold(goldFile, resultFile)); 298 } 299 300 /** 301 * Test the XPointer framework with a SAX object. 302 * 303 * @throws Exception If any errors occur. 304 */ 305 @Test(groups = {"readWriteLocalFiles"}) 306 public void testXPointerPos() throws Exception { 307 String resultFile = USER_DIR + "doc_xpointer.out"; 308 String goldFile = GOLDEN_DIR + "doc_xpointerGold.xml"; 309 String xmlFile = XML_DIR + "doc_xpointer.xml"; 310 311 try (FileOutputStream fos = new FileOutputStream(resultFile)) { 312 SAXParserFactory spf = SAXParserFactory.newInstance(); 313 spf.setNamespaceAware(true); 314 spf.setXIncludeAware(true); 315 spf.setFeature(FEATURE_NAME, true); 316 // parse the file 317 spf.newSAXParser().parse(new File(xmlFile), new XInclHandler(fos, null)); 318 } 319 assertTrue(compareDocumentWithGold(goldFile, resultFile)); 320 } 321 322 /** 323 * Test if xi:include may reference the doc containing the include if the 324 * parse type is text. 325 * 326 * @throws Exception If any errors occur. 327 */ 328 @Test(groups = {"readWriteLocalFiles"}) 329 public void testXIncludeLoopPos() throws Exception { 330 String resultFile = USER_DIR + "doc_xinc_loops.out"; 331 String goldFile = GOLDEN_DIR + "doc_xinc_loopGold.xml"; 332 String xmlFile = XML_DIR + "doc_xinc_loops.xml"; 333 334 try (FileOutputStream fos = new FileOutputStream(resultFile)) { 335 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 336 dbf.setXIncludeAware(true); 337 dbf.setNamespaceAware(true); 338 DocumentBuilder db = dbf.newDocumentBuilder(); 339 Document doc = db.parse(new File(xmlFile)); 340 doc.normalizeDocument(); 341 doc.setXmlStandalone(true); 342 343 TransformerFactory.newInstance().newTransformer() 344 .transform(new DOMSource(doc), new StreamResult(fos)); 345 } 346 assertTrue(compareDocumentWithGold(goldFile, resultFile)); 347 } 348 349 /** 350 * Test if two non nested xi:include elements can include the same document 351 * with an xi:include statement. 352 * 353 * @throws Exception If any errors occur. 354 */ 355 @Test(groups = {"readWriteLocalFiles"}) 356 public void testXIncludeNestedPos() throws Exception { 357 String resultFile = USER_DIR + "schedule.out"; 358 String goldFile = GOLDEN_DIR + "scheduleGold.xml"; 359 String xmlFile = XML_DIR + "schedule.xml"; 360 361 try (FileOutputStream fos = new FileOutputStream(resultFile)) { 362 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 363 dbf.setXIncludeAware(true); 364 dbf.setNamespaceAware(true); 365 366 Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); 367 doc.setXmlStandalone(true); 368 TransformerFactory.newInstance().newTransformer() 369 .transform(new DOMSource(doc), new StreamResult(fos)); 370 } 371 assertTrue(compareDocumentWithGold(goldFile, resultFile)); 372 } 373 } 374 375