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