--- old/test/jdk/sun/misc/URLClassPath/ClassnameCharTest.java 2018-07-02 06:32:04.000000000 -0700 +++ new/test/jdk/sun/misc/URLClassPath/ClassnameCharTest.java 2018-07-02 06:32:04.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ * @bug 4957669 5017871 * @summary cannot load class names containing some JSR 202 characters; * plugin does not escape unicode character in http request - * @modules java.desktop/sun.applet + * @modules java.base/sun.net.www * jdk.httpserver * @compile -XDignore.symbol.file=true ClassnameCharTest.java * @run main ClassnameCharTest @@ -33,9 +33,14 @@ import java.io.*; import java.net.*; +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.CodeSource; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; import java.util.jar.*; import com.sun.net.httpserver.*; -import sun.applet.AppletClassLoader; +import sun.net.www.ParseUtil; public class ClassnameCharTest { static String FNPrefix = System.getProperty("test.src", ".") + File.separator; @@ -79,7 +84,7 @@ try { URL base = new URL("http://localhost:" + server.getAddress().getPort()); System.out.println ("Server: listening on " + base); - MyAppletClassLoader acl = new MyAppletClassLoader(base); + MyURLClassLoader acl = new MyURLClassLoader(base); Class class1 = acl.findClass("fo o"); System.out.println("class1 = " + class1); pass(); @@ -91,14 +96,94 @@ } } - static class MyAppletClassLoader extends AppletClassLoader { - MyAppletClassLoader(URL base) { - super(base); + static class MyURLClassLoader extends URLClassLoader { + private URL base; /* applet code base URL */ + private CodeSource codesource; /* codesource for the base URL */ + private AccessControlContext acc; + MyURLClassLoader(URL base) { + super(new URL[0]); + this.base = base; + this.codesource = + new CodeSource(base, (java.security.cert.Certificate[]) null); + acc = AccessController.getContext(); } @Override public Class findClass(String name) throws ClassNotFoundException { - return super.findClass(name); + int index = name.indexOf(';'); + String cookie = ""; + if(index != -1) { + cookie = name.substring(index, name.length()); + name = name.substring(0, index); + } + + // check loaded JAR files + try { + return super.findClass(name); + } catch (ClassNotFoundException e) { + } + + // Otherwise, try loading the class from the code base URL + // final String path = name.replace('.', '/').concat(".class").concat(cookie); + String encodedName = ParseUtil.encodePath(name.replace('.', '/'), false); + final String path = (new StringBuffer(encodedName)).append(".class").append(cookie).toString(); + try { + byte[] b = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public byte[] run() throws IOException { + try { + URL finalURL = new URL(base, path); + + // Make sure the codebase won't be modified + if (base.getProtocol().equals(finalURL.getProtocol()) && + base.getHost().equals(finalURL.getHost()) && + base.getPort() == finalURL.getPort()) { + return getBytes(finalURL); + } + else { + return null; + } + } catch (Exception e) { + return null; + } + } + }, acc); + + if (b != null) { + return defineClass(name, b, 0, b.length, codesource); + } else { + throw new ClassNotFoundException(name); + } + } catch (PrivilegedActionException e) { + throw new ClassNotFoundException(name, e.getException()); + } + } + + /* + * Returns the contents of the specified URL as an array of bytes. + */ + private static byte[] getBytes(URL url) throws IOException { + URLConnection uc = url.openConnection(); + if (uc instanceof java.net.HttpURLConnection) { + java.net.HttpURLConnection huc = (java.net.HttpURLConnection) uc; + int code = huc.getResponseCode(); + if (code >= java.net.HttpURLConnection.HTTP_BAD_REQUEST) { + throw new IOException("open HTTP connection failed."); + } + } + int len = uc.getContentLength(); + + InputStream in = new BufferedInputStream(uc.getInputStream()); + + byte[] b; + try { + b = in.readAllBytes(); + if (len != -1 && b.length != len) + throw new EOFException("Expected:" + len + ", read:" + b.length); + } finally { + in.close(); + } + return b; } }