changeset 1831:93b2632a22c7

8195874: Improve jar specification adherence Summary: Also reviewed by Chris Ries <chris.ries@oracle.com> Reviewed-by: alanb, mchung, rriggs
author igerasim
date Thu, 07 Jun 2018 15:00:19 -0700
parents 3c5c596ee0fd
children 610c2a0fbf7c
files src/share/classes/sun/misc/URLClassPath.java
diffstat 1 files changed, 54 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/misc/URLClassPath.java	Sat Mar 24 20:21:43 2018 -0700
+++ b/src/share/classes/sun/misc/URLClassPath.java	Thu Jun 07 15:00:19 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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,17 +25,7 @@
 
 package sun.misc;
 
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.Hashtable;
-import java.util.NoSuchElementException;
-import java.util.Stack;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.StringTokenizer;
-import java.util.ArrayList;
-import java.util.Iterator;
+import java.util.*;
 import java.util.jar.JarFile;
 import sun.misc.JarIndex;
 import sun.misc.InvalidJarIndexException;
@@ -47,6 +37,7 @@
 import java.util.jar.Attributes.Name;
 import java.net.JarURLConnection;
 import java.net.MalformedURLException;
+import java.net.URI;
 import java.net.URL;
 import java.net.URLConnection;
 import java.net.HttpURLConnection;
@@ -81,6 +72,8 @@
     private static final boolean DEBUG;
     private static final boolean DISABLE_JAR_CHECKING;
     private static final boolean DISABLE_ACC_CHECKING;
+    private static final boolean DISABLE_CP_URL_CHECK;
+    private static final boolean DEBUG_CP_URL_CHECK;
 
     static {
         JAVA_VERSION = java.security.AccessController.doPrivileged(
@@ -94,6 +87,13 @@
         p = AccessController.doPrivileged(
             new GetPropertyAction("jdk.net.URLClassPath.disableRestrictedPermissions"));
         DISABLE_ACC_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
+
+        // This property will be removed in a later release
+        p = AccessController.doPrivileged(
+            new sun.security.action.GetPropertyAction("jdk.net.URLClassPath.disableClassPathURLCheck"));
+
+        DISABLE_CP_URL_CHECK = p != null ? p.equals("true") || p.isEmpty() : false;
+        DEBUG_CP_URL_CHECK = "debug".equals(p);
     }
 
     /* The original search path of URLs. */
@@ -999,11 +999,51 @@
             int i = 0;
             while (st.hasMoreTokens()) {
                 String path = st.nextToken();
-                urls[i] = new URL(base, path);
-                i++;
+                URL url = DISABLE_CP_URL_CHECK ? new URL(base, path) : safeResolve(base, path);
+                if (url != null) {
+                    urls[i] = url;
+                    i++;
+                }
+            }
+            if (i == 0) {
+                urls = null;
+            } else if (i != urls.length) {
+                // Truncate nulls from end of array
+                urls = Arrays.copyOf(urls, i);
             }
             return urls;
         }
+
+        /*
+         * Return a URL for the given path resolved against the base URL, or
+         * null if the resulting URL is invalid.
+         */
+        static URL safeResolve(URL base, String path) {
+            String child = path.replace(File.separatorChar, '/');
+            try {
+                if (!URI.create(child).isAbsolute()) {
+                    URL url = new URL(base, child);
+                    if (base.getProtocol().equalsIgnoreCase("file")) {
+                        return url;
+                    } else {
+                        String bp = base.getPath();
+                        String urlp = url.getPath();
+                        int pos = bp.lastIndexOf('/');
+                        if (pos == -1) {
+                            pos = bp.length() - 1;
+                        }
+                        if (urlp.regionMatches(0, bp, 0, pos + 1)
+                            && urlp.indexOf("..", pos) == -1) {
+                            return url;
+                        }
+                    }
+                }
+            } catch (MalformedURLException e) {} catch (IllegalArgumentException e) {}
+            if (DEBUG_CP_URL_CHECK) {
+                System.err.println("Class-Path entry: \"" + path + "\" ignored in JAR file " + base);
+            }
+            return null;
+        }
     }
 
     /*