Path: blob/master/test/jdk/sun/misc/URLClassPath/ClassnameCharTest.java
41149 views
/*1* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* @test24* @bug 4957669 501787125* @summary cannot load class names containing some JSR 202 characters;26* plugin does not escape unicode character in http request27* @modules java.base/sun.net.www28* jdk.httpserver29* @compile -XDignore.symbol.file=true ClassnameCharTest.java30* @run main ClassnameCharTest31*/3233import java.io.*;34import java.net.*;35import java.security.AccessControlContext;36import java.security.AccessController;37import java.security.CodeSource;38import java.security.PrivilegedActionException;39import java.security.PrivilegedExceptionAction;40import java.util.jar.*;41import com.sun.net.httpserver.*;42import sun.net.www.ParseUtil;4344public class ClassnameCharTest {45static String FNPrefix = System.getProperty("test.src", ".") + File.separator;46static File classesJar = new File(FNPrefix + "testclasses.jar");47static HttpServer server;4849public static void realMain(String[] args) throws Exception {50server = HttpServer.create(new InetSocketAddress(0), 0);51server.createContext("/", new HttpHandler() {52@Override53public void handle(HttpExchange exchange) {54try {55String filename = exchange.getRequestURI().getPath();56System.out.println("getRequestURI = " + exchange.getRequestURI());57System.out.println("filename = " + filename);58try (FileInputStream fis = new FileInputStream(classesJar);59JarInputStream jis = new JarInputStream(fis)) {60JarEntry entry;61while ((entry = jis.getNextJarEntry()) != null) {62if (filename.endsWith(entry.getName())) {63ByteArrayOutputStream baos = new ByteArrayOutputStream();64byte[] buf = new byte[8092];65int count = 0;66while ((count = jis.read(buf)) != -1)67baos.write(buf, 0, count);68exchange.sendResponseHeaders(200, baos.size());69try (OutputStream os = exchange.getResponseBody()) {70baos.writeTo(os);71}72return;73}74}75fail("Failed to find " + filename);76}77} catch (IOException e) {78unexpected(e);79}80}81});82server.start();83try {84URL base = new URL("http://localhost:" + server.getAddress().getPort());85System.out.println ("Server: listening on " + base);86MyURLClassLoader acl = new MyURLClassLoader(base);87Class<?> class1 = acl.findClass("fo o");88System.out.println("class1 = " + class1);89pass();90// can't test the following class unless platform in unicode locale91// Class class2 = acl.findClass("\u624b\u518c");92// System.out.println("class2 = "+class2);93} finally {94server.stop(0);95}96}97// the class loader code was copied from the now deleted AppletClassLoader98static class MyURLClassLoader extends URLClassLoader {99private URL base; /* applet code base URL */100private CodeSource codesource; /* codesource for the base URL */101private AccessControlContext acc;102MyURLClassLoader(URL base) {103super(new URL[0]);104this.base = base;105this.codesource =106new CodeSource(base, (java.security.cert.Certificate[]) null);107acc = AccessController.getContext();108}109110@Override111public Class<?> findClass(String name) throws ClassNotFoundException {112int index = name.indexOf(';');113String cookie = "";114if(index != -1) {115cookie = name.substring(index, name.length());116name = name.substring(0, index);117}118119// check loaded JAR files120try {121return super.findClass(name);122} catch (ClassNotFoundException e) {123}124125// Otherwise, try loading the class from the code base URL126// final String path = name.replace('.', '/').concat(".class").concat(cookie);127String encodedName = ParseUtil.encodePath(name.replace('.', '/'), false);128final String path = (new StringBuffer(encodedName)).append(".class").append(cookie).toString();129try {130byte[] b = AccessController.doPrivileged(131new PrivilegedExceptionAction<byte[]>() {132public byte[] run() throws IOException {133try {134URL finalURL = new URL(base, path);135136// Make sure the codebase won't be modified137if (base.getProtocol().equals(finalURL.getProtocol()) &&138base.getHost().equals(finalURL.getHost()) &&139base.getPort() == finalURL.getPort()) {140return getBytes(finalURL);141}142else {143return null;144}145} catch (Exception e) {146return null;147}148}149}, acc);150151if (b != null) {152return defineClass(name, b, 0, b.length, codesource);153} else {154throw new ClassNotFoundException(name);155}156} catch (PrivilegedActionException e) {157throw new ClassNotFoundException(name, e.getException());158}159}160161/*162* Returns the contents of the specified URL as an array of bytes.163*/164private static byte[] getBytes(URL url) throws IOException {165URLConnection uc = url.openConnection();166if (uc instanceof java.net.HttpURLConnection) {167java.net.HttpURLConnection huc = (java.net.HttpURLConnection) uc;168int code = huc.getResponseCode();169if (code >= java.net.HttpURLConnection.HTTP_BAD_REQUEST) {170throw new IOException("open HTTP connection failed.");171}172}173int len = uc.getContentLength();174175InputStream in = new BufferedInputStream(uc.getInputStream());176177byte[] b;178try {179b = in.readAllBytes();180if (len != -1 && b.length != len)181throw new EOFException("Expected:" + len + ", read:" + b.length);182} finally {183in.close();184}185return b;186}187}188189//--------------------- Infrastructure ---------------------------190static volatile int passed = 0, failed = 0;191192static boolean pass() {193passed++;194return true;195}196197static boolean fail() {198failed++;199if (server != null) {200server.stop(0);201}202Thread.dumpStack();203return false;204}205206static boolean fail(String msg) {207System.out.println(msg);208return fail();209}210211static void unexpected(Throwable t) {212failed++;213if (server != null) {214server.stop(0);215}216t.printStackTrace();217}218219static boolean check(boolean cond) {220if (cond) {221pass();222} else {223fail();224}225return cond;226}227228static boolean equal(Object x, Object y) {229if (x == null ? y == null : x.equals(y)) {230return pass();231} else {232return fail(x + " not equal to " + y);233}234}235236public static void main(String[] args) throws Throwable {237try {238realMain(args);239} catch (Throwable t) {240unexpected(t);241}242System.out.println("\nPassed = " + passed + " failed = " + failed);243if (failed > 0) {244throw new AssertionError("Some tests failed");245}246}247}248249250