# HG changeset patch # User igerasim # Date 1528408819 25200 # Node ID 93b2632a22c71fa6432cba01afd09d69d5ac8882 # Parent 3c5c596ee0fdaa650d91dc0fada818d68d505e6b 8195874: Improve jar specification adherence Summary: Also reviewed by Chris Ries Reviewed-by: alanb, mchung, rriggs diff -r 3c5c596ee0fd -r 93b2632a22c7 src/share/classes/sun/misc/URLClassPath.java --- 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; + } } /*