From dfcea0547e7756a546fcf57855d99d46ecfb1925 Mon Sep 17 00:00:00 2001 From: Justin Lu Date: Mon, 23 Jun 2025 14:26:02 +0000 Subject: [PATCH] 8358729: jdk/internal/loader/URLClassPath/ClassnameCharTest.java depends on Applet Reviewed-by: jpai, lancea --- .../URLClassPath/ClassnameCharTest.java | 180 ++++-------------- .../loader/URLClassPath/testclasses.jar | Bin 1173 -> 0 bytes 2 files changed, 41 insertions(+), 139 deletions(-) delete mode 100644 test/jdk/jdk/internal/loader/URLClassPath/testclasses.jar diff --git a/test/jdk/jdk/internal/loader/URLClassPath/ClassnameCharTest.java b/test/jdk/jdk/internal/loader/URLClassPath/ClassnameCharTest.java index 85987ef6f5e..8208e8d9cba 100644 --- a/test/jdk/jdk/internal/loader/URLClassPath/ClassnameCharTest.java +++ b/test/jdk/jdk/internal/loader/URLClassPath/ClassnameCharTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -22,62 +22,43 @@ */ /* @test - * @bug 4957669 5017871 + * @bug 4957669 5017871 8358729 * @summary cannot load class names containing some JSR 202 characters; * plugin does not escape unicode character in http request * @modules java.base/sun.net.www * jdk.httpserver - * @compile -XDignore.symbol.file=true ClassnameCharTest.java - * @run main ClassnameCharTest + * @run junit ClassnameCharTest */ import java.io.*; +import java.lang.classfile.ClassFile; +import java.lang.constant.ClassDesc; 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.net.www.ParseUtil; -public class ClassnameCharTest { - static String FNPrefix = System.getProperty("test.src", ".") + File.separator; - static File classesJar = new File(FNPrefix + "testclasses.jar"); - static HttpServer server; +import org.junit.jupiter.api.Test; - public static void realMain(String[] args) throws Exception { +public class ClassnameCharTest { + + private static HttpServer server; + private static final byte[] bytes = + ClassFile.of().build(ClassDesc.of("fo o"), _ -> {}); + + @Test + void testClassName() throws IOException { + // Build the server and set the context server = HttpServer.create(new InetSocketAddress(0), 0); - server.createContext("/", new HttpHandler() { - @Override - public void handle(HttpExchange exchange) { - try { - String filename = exchange.getRequestURI().getPath(); - System.out.println("getRequestURI = " + exchange.getRequestURI()); - System.out.println("filename = " + filename); - try (FileInputStream fis = new FileInputStream(classesJar); - JarInputStream jis = new JarInputStream(fis)) { - JarEntry entry; - while ((entry = jis.getNextJarEntry()) != null) { - if (filename.endsWith(entry.getName())) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - byte[] buf = new byte[8092]; - int count = 0; - while ((count = jis.read(buf)) != -1) - baos.write(buf, 0, count); - exchange.sendResponseHeaders(200, baos.size()); - try (OutputStream os = exchange.getResponseBody()) { - baos.writeTo(os); - } - return; - } - } - fail("Failed to find " + filename); - } - } catch (IOException e) { - unexpected(e); - } + server.createContext("/", exchange -> { + String filename = exchange.getRequestURI().getPath(); + System.out.println("getRequestURI = " + exchange.getRequestURI()); + System.out.println("filename = " + filename); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + baos.write(bytes, 0, bytes.length); + exchange.sendResponseHeaders(200, baos.size()); + try (OutputStream os = exchange.getResponseBody()) { + baos.writeTo(os); } }); server.start(); @@ -87,7 +68,6 @@ public class ClassnameCharTest { MyURLClassLoader acl = new MyURLClassLoader(base); Class class1 = acl.findClass("fo o"); System.out.println("class1 = " + class1); - pass(); // can't test the following class unless platform in unicode locale // Class class2 = acl.findClass("\u624b\u518c"); // System.out.println("class2 = "+class2); @@ -99,17 +79,15 @@ public class ClassnameCharTest { static class MyURLClassLoader extends URLClassLoader { private URL base; /* 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 { + public Class findClass(String name) { int index = name.indexOf(';'); String cookie = ""; if(index != -1) { @@ -117,46 +95,29 @@ public class ClassnameCharTest { 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(); + final String path = encodedName + ".class" + cookie; + Exception exc = null; + // try block used for checked exceptions as well as ClassFormatError + // from defineClass call 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) { + 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()) { + byte[] b = getBytes(finalURL); return defineClass(name, b, 0, b.length, codesource); - } else { - throw new ClassNotFoundException(name); } - } catch (PrivilegedActionException e) { - throw new ClassNotFoundException(name, e.getException()); + // protocol/host/port mismatch, fail with RuntimeException + } catch (Exception underlyingE) { + exc = underlyingE; // Most likely CFE from defineClass } + // Fail if there was either a protocol/host/port mismatch + // or an exception was thrown (which is propagated) + throw new RuntimeException(name, exc); } /* @@ -186,63 +147,4 @@ public class ClassnameCharTest { return b; } } - - //--------------------- Infrastructure --------------------------- - static volatile int passed = 0, failed = 0; - - static boolean pass() { - passed++; - return true; - } - - static boolean fail() { - failed++; - if (server != null) { - server.stop(0); - } - Thread.dumpStack(); - return false; - } - - static boolean fail(String msg) { - System.out.println(msg); - return fail(); - } - - static void unexpected(Throwable t) { - failed++; - if (server != null) { - server.stop(0); - } - t.printStackTrace(); - } - - static boolean check(boolean cond) { - if (cond) { - pass(); - } else { - fail(); - } - return cond; - } - - static boolean equal(Object x, Object y) { - if (x == null ? y == null : x.equals(y)) { - return pass(); - } else { - return fail(x + " not equal to " + y); - } - } - - public static void main(String[] args) throws Throwable { - try { - realMain(args); - } catch (Throwable t) { - unexpected(t); - } - System.out.println("\nPassed = " + passed + " failed = " + failed); - if (failed > 0) { - throw new AssertionError("Some tests failed"); - } - } } diff --git a/test/jdk/jdk/internal/loader/URLClassPath/testclasses.jar b/test/jdk/jdk/internal/loader/URLClassPath/testclasses.jar deleted file mode 100644 index 0069eee84a063e559916268140dda69e15837779..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1173 zcmWIWW@Zs#-~hrO1sw(qNPv@pg~8V~#8KDN&rSc|DFy~+h5&DN4v-2asImZ@nni#r z;F^6M{XE@VgG2Ou-9G!CIql=Et9OytTUYDcne&^246YbIcv__A<*VcAd$DvC3#Y_O zNzDwF>CZHOq^XHN6%QAizT}yhcEvN**O{M+J{B>8U9oEM-5eL79UzQw#f_dy6fXz? zWe+bq)Oo1;@X|wVhkEpqa}tY-a|2F$9d;10y}U(o_OWf-u9dTv=L$aFr_`aq;n?c& z{j$}GDJGmRUB0lhT%3QgwTs*S!2b*91@hfCNT(OdKc81D|M}zJZ+r>jv-xsDPOn(_ zE`gD^eUaL6CHL-w_kt&0`ppxz+&V!+?wI(bh0j)d%uAWP(C7S71C=EvSCy{v_z9%H z^pIOAv!>?m-THfWZ+ebSEjVa+eB+ZONo|?cde=6*OJdHI`gA%u*;aip$*XL8il$rrG`TAkAJ~5^?%8a6 z;;7uS$7lDL8~^?H^AA%&Q!|5|R%%Ef_lCYIhrs6K=EWx;%zqVf+n7!N4Uc4(__H{} zkl$9J*Sk}eY_hiO;?z95_Kc3RfkAi98og4!Y3j#jJYHEdg-J$RW;Rpwjb}FmZycR> zz%FWurD5*jfb+kVEN34*<@WrX;T0K)(_a*&Y|gLs$`IVVz-jY)ty?bJXZpQ8kmjXk z+jh*}fO-DY$T>p#Z}e63-GWWG*_O|!x}*}#v);;CW|2$$r2R}0`z&u7rRsj_sag4( z@0%0jUGHn<3*5`TuK#)>knv-e(|6u^-y0uI3S5{sNilQ2#hieLZEOEBfihF$g4cId zfZ;k79JY*1A`GZ`5th+Fc@Y)BGZ!dl26&@tMa~_doQMFnKqg!(Qocks0hEi7BOR2B r5a2M7iJ7O6^@EZIvd2J40|E4aenKRa0B=?{kQ@sTeg)E9%pe{B#59*-