1 /* 2 * Copyright (c) 2017, 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 catalog; 24 25 import java.io.BufferedOutputStream; 26 import java.io.BufferedReader; 27 import java.io.BufferedWriter; 28 import java.io.File; 29 import java.io.IOException; 30 import java.io.InputStream; 31 import java.io.InputStreamReader; 32 import java.io.OutputStream; 33 import java.io.OutputStreamWriter; 34 import java.net.URI; 35 import java.nio.file.Files; 36 import java.nio.file.Path; 37 import java.nio.file.Paths; 38 import static java.nio.file.StandardOpenOption.APPEND; 39 import static java.nio.file.StandardOpenOption.CREATE; 40 import javax.xml.catalog.Catalog; 41 import javax.xml.catalog.CatalogException; 42 import javax.xml.catalog.CatalogFeatures; 43 import javax.xml.catalog.CatalogManager; 44 import javax.xml.catalog.CatalogResolver; 45 import static jaxp.library.JAXPTestUtilities.getSystemProperty; 46 import jaxp.library.SimpleHttpServer; 47 import org.testng.Assert; 48 import org.testng.annotations.AfterClass; 49 import org.testng.annotations.BeforeClass; 50 import org.testng.annotations.DataProvider; 51 import org.testng.annotations.Listeners; 52 import org.testng.annotations.Test; 53 import org.xml.sax.InputSource; 54 55 /* 56 * @test 57 * @bug 8151154 8171243 58 * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest /test/lib 59 * @run testng/othervm catalog.CatalogFileInputTest 60 * @summary Verifies that the Catalog API accepts valid URIs only; 61 * Verifies that the CatalogFeatures' builder throws 62 * IllegalArgumentException on invalid file inputs. 63 * This test was splitted from CatalogTest.java due to 64 * JDK-8168968, it has to only run without SecurityManager 65 * because an ACE will be thrown for invalid path. 66 */ 67 @Listeners({jaxp.library.FilePolicy.class, jaxp.library.NetAccessPolicy.class}) 68 public class CatalogFileInputTest extends CatalogSupportBase { 69 70 static final CatalogFeatures FEATURES = CatalogFeatures.builder(). 71 with(CatalogFeatures.Feature.PREFER, "system").build(); 72 static String USER_DIR = getSystemProperty("user.dir"); 73 static String CLS_DIR = getSystemProperty("test.classes"); 74 static String SRC_DIR = System.getProperty("test.src"); 75 static String JAR_CONTENT = "META-INF"; 76 final static String SCHEME_JARFILE = "jar:"; 77 static final String REMOTE_FILE_LOCATION = "/jar/META-INF"; 78 static final String DOCROOT = SRC_DIR; 79 static final String TESTCONTEXT = REMOTE_FILE_LOCATION; //mapped to local file path 80 SimpleHttpServer _httpserver; 81 String _remoteFilePath; 82 83 /* 84 * Initializing fields 85 */ 86 @BeforeClass 87 public void setUpClass() throws Exception { 88 super.setUp(); 89 90 // set up HttpServer 91 _httpserver = new SimpleHttpServer(TESTCONTEXT, DOCROOT); 92 _httpserver.start(); 93 _remoteFilePath = _httpserver.getAddress() + REMOTE_FILE_LOCATION; 94 95 } 96 97 @AfterClass 98 protected void tearDown() throws Exception { 99 if (_httpserver != null) { 100 _httpserver.stop(); 101 } 102 } 103 104 /* 105 * Verifies that the Catalog can be created with file system paths including JAR 106 * and http URL, and used to resolve a systemId as expected. 107 */ 108 @Test(dataProvider = "acceptedURI") 109 public void testMatch(String uri, String sysId, String pubId, 110 String expectedId, String msg) throws Exception { 111 CatalogResolver cr = CatalogManager.catalogResolver(FEATURES, URI.create(uri)); 112 InputSource is = cr.resolveEntity(pubId, sysId); 113 Assert.assertNotNull(is, msg); 114 Assert.assertEquals(expectedId, is.getSystemId(), msg); 115 } 116 117 @Test(dataProvider = "invalidCatalog") 118 public void testEmptyCatalog(String uri, String publicId, String msg) { 119 Catalog c = CatalogManager.catalog(FEATURES, uri != null? URI.create(uri) : null); 120 Assert.assertNull(c.matchSystem(publicId), msg); 121 } 122 123 @Test(dataProvider = "invalidCatalog", expectedExceptions = CatalogException.class) 124 public void testCatalogResolverWEmptyCatalog(String uri, String publicId, String msg) { 125 CatalogResolver cr = CatalogManager.catalogResolver( 126 CatalogFeatures.builder().with(CatalogFeatures.Feature.RESOLVE, "strict").build(), 127 uri != null? URI.create(uri) : null); 128 InputSource is = cr.resolveEntity(publicId, ""); 129 } 130 131 @Test(dataProvider = "invalidCatalog") 132 public void testCatalogResolverWEmptyCatalog1(String uri, String publicId, String msg) { 133 CatalogResolver cr = CatalogManager.catalogResolver( 134 CatalogFeatures.builder().with(CatalogFeatures.Feature.RESOLVE, "continue").build(), 135 uri != null? URI.create(uri) : null); 136 Assert.assertNull(cr.resolveEntity(publicId, ""), msg); 137 } 138 139 @Test(dataProvider = "invalidInput", expectedExceptions = IllegalArgumentException.class) 140 public void testFileInput(String file) { 141 CatalogFeatures features = CatalogFeatures.builder() 142 .with(CatalogFeatures.Feature.FILES, file) 143 .build(); 144 } 145 146 @Test(dataProvider = "invalidInput", expectedExceptions = IllegalArgumentException.class) 147 public void testInvalidUri(String file) { 148 CatalogResolver cr = CatalogManager.catalogResolver(FEATURES, file != null? URI.create(file) : null); 149 } 150 151 @Test(dataProvider = "invalidInput", expectedExceptions = IllegalArgumentException.class) 152 public void testInvalidUri1(String file) { 153 Catalog c = CatalogManager.catalog(FEATURES, file != null? URI.create(file) : null); 154 System.err.println("Catalog =" + c); 155 } 156 157 158 @Test(expectedExceptions = NullPointerException.class) 159 public void testNullFileInput() { 160 CatalogFeatures features = CatalogFeatures.builder() 161 .with(CatalogFeatures.Feature.FILES, null) 162 .build(); 163 } 164 165 @Test(expectedExceptions = NullPointerException.class) 166 public void testNullUri() { 167 URI uri = null; 168 CatalogResolver cr = CatalogManager.catalogResolver(FEATURES, uri); 169 } 170 171 @Test(expectedExceptions = NullPointerException.class) 172 public void testNullUri1() { 173 URI uri = null; 174 Catalog c = CatalogManager.catalog(FEATURES, uri); 175 } 176 177 String systemId = "http://www.sys00test.com/rewrite.dtd"; 178 String publicId = "PUB-404"; 179 String expected = "http://www.groupxmlbase.com/dtds/rewrite.dtd"; 180 String errMsg = "Relative rewriteSystem with xml:base at group level failed"; 181 182 /* 183 DataProvider: used to verify CatalogResolver's resolveEntity function. 184 Data columns: 185 catalog, systemId, publicId, expectedUri, msg 186 */ 187 @DataProvider(name = "acceptedURI") 188 Object[][] getData() throws Exception { 189 String filename = "rewriteSystem_id.xml"; 190 String urlFile = getClass().getResource(filename).toExternalForm(); 191 String urlHttp = _remoteFilePath + "/jax-ws-catalog.xml"; 192 String remoteXSD = _remoteFilePath + "/catalog/ws-addr.xsd"; 193 File file = new File(CLS_DIR + "/JDK8171243.jar!/META-INF/jax-ws-catalog.xml"); 194 String jarPath = SCHEME_JARFILE + file.toURI().toString(); 195 String xsd = jarPath.substring(0, jarPath.lastIndexOf("/")) + "/catalog/ws-addr.xsd"; 196 197 // create JAR file 198 try { 199 JarUtils.createJarFile(Paths.get(CLS_DIR + "/JDK8171243.jar"), 200 Paths.get(SRC_DIR + "/jar"), JAR_CONTENT); 201 } catch (IOException ex) { 202 Assert.fail("Failed to create JAR: " + ex.getMessage()); 203 } 204 205 return new Object[][]{ 206 // URL 207 {urlFile, systemId, publicId, expected, errMsg}, 208 {urlHttp, "http://www.w3.org/2006/03/addressing/ws-addr.xsd", "", remoteXSD, "http test failed."}, 209 // JAR file 210 {jarPath, "http://www.w3.org/2006/03/addressing/ws-addr.xsd", "", xsd, "jar file test failed."}, 211 }; 212 } 213 214 /* 215 * DataProvider: invalid catalog result in empty catalog 216 * Note: the difference from invalidInput is that invalidInput is syntactically 217 * rejected with an IAE. 218 */ 219 @DataProvider(name = "invalidCatalog") 220 public Object[][] getInvalidCatalog() throws Exception { 221 String catalogUri = getClass().getResource("catalog_invalid.xml").toExternalForm(); 222 return new Object[][]{ 223 {catalogUri, "-//W3C//DTD XHTML 1.0 Strict//EN", 224 "The catalog is invalid, attempting to match the public entry shall return null."}, 225 {"file:/../../..", "-//W3C//DTD XHTML 1.0 Strict//EN", 226 "The catalog is invalid, attempting to match the public entry shall return null."} 227 }; 228 } 229 230 /* 231 * DataProvider: a list of invalid inputs, expects IAE 232 * Note: exclude null since NPE would have been expected 233 */ 234 @DataProvider(name = "invalidInput") 235 public Object[][] getFiles() throws Exception { 236 String filename = "rewriteSystem_id.xml"; 237 copyFile(Paths.get(SRC_DIR + "/" + filename), Paths.get(filename)); 238 String absolutePath = getClass().getResource(filename).getFile(); 239 240 return new Object[][]{ 241 {""}, 242 {"file:a/b\\c"}, 243 {"c:/te:t"}, 244 {"c:/te?t"}, 245 {"c/te*t"}, 246 {"in|valid.txt"}, 247 {"shema:invalid.txt"}, 248 // relative file path 249 {filename}, 250 // absolute file path 251 {absolutePath} 252 }; 253 } 254 255 /* 256 DataProvider: a list of invalid inputs 257 */ 258 @DataProvider(name = "nullTest") 259 public Object[][] getNull() throws Exception { 260 261 return new Object[][]{ 262 {null}, 263 }; 264 } 265 266 void copyFile(Path src, Path target) throws Exception { 267 268 try (InputStream in = Files.newInputStream(src); 269 BufferedReader reader 270 = new BufferedReader(new InputStreamReader(in)); 271 OutputStream out = new BufferedOutputStream( 272 Files.newOutputStream(target, CREATE, APPEND)); 273 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out))) { 274 String line = null; 275 while ((line = reader.readLine()) != null) { 276 bw.write(line); 277 } 278 } catch (IOException x) { 279 throw new Exception(x.getMessage()); 280 } 281 } 282 }