changeset 57328:336885e766af

8235361: JAR Class-Path no longer accepts relative URLs encoding absolute Windows paths (e.g "/C:/...") Reviewed-by: alanb, mchung
author bchristi
date Tue, 10 Dec 2019 11:56:26 -0800
parents 05b884481924
children 4a601cb7a903
files src/java.base/share/classes/jdk/internal/loader/URLClassPath.java test/jdk/jdk/internal/loader/URLClassPath/JarClassPathFileEntry.java
diffstat 2 files changed, 24 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java	Tue Dec 10 19:12:57 2019 +0000
+++ b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java	Tue Dec 10 11:56:26 2019 -0800
@@ -1125,27 +1125,21 @@
 
         /**
          * Attempt to return a file URL by resolving input against a base file
-         * URL. The input is an absolute or relative file URL that encodes a
-         * file path.
-         *
-         * @apiNote Nonsensical input such as a Windows file path with a drive
-         * letter cannot be disambiguated from an absolute URL so will be rejected
-         * (by returning null) by this method.
-         *
+         * URL.
          * @return the resolved URL or null if the input is an absolute URL with
          *         a scheme other than file (ignoring case)
          * @throws MalformedURLException
          */
         static URL tryResolveFile(URL base, String input) throws MalformedURLException {
-            int index = input.indexOf(':');
-            boolean isFile;
-            if (index >= 0) {
-                String scheme = input.substring(0, index);
-                isFile = "file".equalsIgnoreCase(scheme);
-            } else {
-                isFile = true;
+            URL retVal = new URL(base, input);
+            if (input.indexOf(':') >= 0 &&
+                    !"file".equalsIgnoreCase(retVal.getProtocol())) {
+                // 'input' contains a ':', which might be a scheme, or might be
+                // a Windows drive letter.  If the protocol for the resolved URL
+                // isn't "file:", it should be ignored.
+                return null;
             }
-            return (isFile) ? new URL(base, input) : null;
+            return retVal;
         }
 
         /**
--- a/test/jdk/jdk/internal/loader/URLClassPath/JarClassPathFileEntry.java	Tue Dec 10 19:12:57 2019 +0000
+++ b/test/jdk/jdk/internal/loader/URLClassPath/JarClassPathFileEntry.java	Tue Dec 10 11:56:26 2019 -0800
@@ -33,8 +33,8 @@
 
 /*
  * @test
- * @bug 8216401
- * @summary Test loading of JAR Class-Path entry with file: scheme
+ * @bug 8216401 8235361
+ * @summary Test classloading via JAR Class-Path entries
  * @library /test/lib
  *
  * @run main/othervm JarClassPathFileEntry
@@ -52,6 +52,19 @@
     private final static Path CONTEXT_JAR_PATH = Paths.get(TEST_CLASSES, "Context.jar");
 
     public static void main(String[] args) throws Throwable {
+        String fileScheme = "file:" + (IS_WINDOWS ? toUnixPath(OTHER_JAR_PATH.toString())
+                                                      :        OTHER_JAR_PATH.toString());
+        doTest(fileScheme);
+
+        if (IS_WINDOWS) {
+            // Relative URL encoding of absolute path, e.g. /C:\\path\\to\\file.jar
+            String driveLetter = "/" + OTHER_JAR_PATH;
+            doTest(driveLetter);
+        }
+    }
+
+    /* Load a class from Other.jar via the given Class-Path entry */
+    private static void doTest(String classPathEntry) throws Throwable {
         // Create Other.class in OTHER_DIR, off the default classpath
         byte klassbuf[] = InMemoryJavaCompiler.compile("Other",
                                                        "public class Other {}");
@@ -72,8 +85,6 @@
         Attributes attrs = mf.getMainAttributes();
         attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0");
 
-        String classPathEntry = "file:" + (IS_WINDOWS ? toUnixPath(OTHER_JAR_PATH.toString())
-                                                      :            OTHER_JAR_PATH.toString());
         attrs.put(Attributes.Name.CLASS_PATH, classPathEntry);
 
         System.out.println("Creating Context.jar with Class-Path: " + classPathEntry);