8195874: Improve jar specification adherence
Summary: Also reviewed by Chris Ries <chris.ries@oracle.com>
Reviewed-by: alanb, mchung, rriggs
--- a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java Fri May 18 13:34:42 2018 +0530
+++ b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java Tue May 29 10:27:45 2018 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, 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
@@ -34,6 +34,7 @@
import java.net.HttpURLConnection;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
+import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
@@ -88,6 +89,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 {
Properties props = GetPropertyAction.privilegedGetProperties();
@@ -98,6 +101,12 @@
p = props.getProperty("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 = props.getProperty("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. */
@@ -1081,11 +1090,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 | IllegalArgumentException e) {}
+ if (DEBUG_CP_URL_CHECK) {
+ System.err.println("Class-Path entry: \"" + path + "\" ignored in JAR file " + base);
+ }
+ return null;
+ }
}
/*