< prev index next >

src/share/classes/sun/misc/URLClassPath.java

Print this page
rev 13657 : 8216401: Allow "file:" URLs in Class-Path of local JARs
Reviewed-by: alanb, mchung
   1 /*
   2  * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


1212 
1213         /*
1214          * parse the standard extension dependencies
1215          */
1216         private void  parseExtensionsDependencies() throws IOException {
1217             ExtensionDependency.checkExtensionsDependencies(jar);
1218         }
1219 
1220         /*
1221          * Parses value of the Class-Path manifest attribute and returns
1222          * an array of URLs relative to the specified base URL.
1223          */
1224         private URL[] parseClassPath(URL base, String value)
1225             throws MalformedURLException
1226         {
1227             StringTokenizer st = new StringTokenizer(value);
1228             URL[] urls = new URL[st.countTokens()];
1229             int i = 0;
1230             while (st.hasMoreTokens()) {
1231                 String path = st.nextToken();
1232                 URL url = DISABLE_CP_URL_CHECK ? new URL(base, path) : safeResolve(base, path);
1233                 if (url != null) {
1234                     urls[i] = url;
1235                     i++;





1236                 }
1237             }
1238             if (i == 0) {
1239                 urls = null;
1240             } else if (i != urls.length) {
1241                 // Truncate nulls from end of array
1242                 urls = Arrays.copyOf(urls, i);
1243             }
1244             return urls;
1245         }
1246 
1247         /*
1248          * Return a URL for the given path resolved against the base URL, or
1249          * null if the resulting URL is invalid.




































1250          */
1251         static URL safeResolve(URL base, String path) {
1252             String child = path.replace(File.separatorChar, '/');
1253             try {
1254                 if (!URI.create(child).isAbsolute()) {
1255                     URL url = new URL(base, child);
1256                     if (base.getProtocol().equalsIgnoreCase("file")) {
1257                         return url;
1258                     } else {
1259                         String bp = base.getPath();
1260                         String urlp = url.getPath();
1261                         int pos = bp.lastIndexOf('/');
1262                         if (pos == -1) {
1263                             pos = bp.length() - 1;
1264                         }
1265                         if (urlp.regionMatches(0, bp, 0, pos + 1)
1266                             && urlp.indexOf("..", pos) == -1) {
1267                             return url;
1268                         }
1269                     }

1270                 }
1271             } catch (MalformedURLException | IllegalArgumentException e) {}
1272             if (DEBUG_CP_URL_CHECK) {
1273                 System.err.println("Class-Path entry: \"" + path + "\" ignored in JAR file " + base);






1274             }
1275             return null;
1276         }
1277     }
1278 
1279     /*
1280      * Inner class used to represent a loader of classes and resources
1281      * from a file URL that refers to a directory.
1282      */
1283     private static class FileLoader extends Loader {
1284         /* Canonicalized File */
1285         private File dir;
1286 
1287         FileLoader(URL url) throws IOException {
1288             super(url);
1289             if (!"file".equals(url.getProtocol())) {
1290                 throw new IllegalArgumentException("url");
1291             }
1292             String path = url.getFile().replace('/', File.separatorChar);
1293             path = ParseUtil.decode(path);
1294             dir = (new File(path)).getCanonicalFile();
1295         }


   1 /*
   2  * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


1212 
1213         /*
1214          * parse the standard extension dependencies
1215          */
1216         private void  parseExtensionsDependencies() throws IOException {
1217             ExtensionDependency.checkExtensionsDependencies(jar);
1218         }
1219 
1220         /*
1221          * Parses value of the Class-Path manifest attribute and returns
1222          * an array of URLs relative to the specified base URL.
1223          */
1224         private URL[] parseClassPath(URL base, String value)
1225             throws MalformedURLException
1226         {
1227             StringTokenizer st = new StringTokenizer(value);
1228             URL[] urls = new URL[st.countTokens()];
1229             int i = 0;
1230             while (st.hasMoreTokens()) {
1231                 String path = st.nextToken();
1232                 URL url = DISABLE_CP_URL_CHECK ? new URL(base, path) : tryResolve(base, path);
1233                 if (url != null) {
1234                     urls[i] = url;
1235                     i++;
1236                 } else {
1237                     if (DEBUG_CP_URL_CHECK) {
1238                         System.err.println("Class-Path entry: \"" + path
1239                                            + "\" ignored in JAR file " + base);
1240                     }
1241                 }
1242             }
1243             if (i == 0) {
1244                 urls = null;
1245             } else if (i != urls.length) {
1246                 // Truncate nulls from end of array
1247                 urls = Arrays.copyOf(urls, i);
1248             }
1249             return urls;
1250         }
1251 
1252         static URL tryResolve(URL base, String input) throws MalformedURLException {
1253             if ("file".equalsIgnoreCase(base.getProtocol())) {
1254                 return tryResolveFile(base, input);
1255             } else {
1256                 return tryResolveNonFile(base, input);
1257             }
1258         }
1259 
1260         /**
1261          * Attempt to return a file URL by resolving input against a base file
1262          * URL. The input is an absolute or relative file URL that encodes a
1263          * file path.
1264          *
1265          * @apiNote Nonsensical input such as a Windows file path with a drive
1266          * letter cannot be disambiguated from an absolute URL so will be rejected
1267          * (by returning null) by this method.
1268          *
1269          * @return the resolved URL or null if the input is an absolute URL with
1270          *         a scheme other than file (ignoring case)
1271          * @throws MalformedURLException
1272          */
1273         static URL tryResolveFile(URL base, String input) throws MalformedURLException {
1274             int index = input.indexOf(':');
1275             boolean isFile;
1276             if (index >= 0) {
1277                 String scheme = input.substring(0, index);
1278                 isFile = "file".equalsIgnoreCase(scheme);
1279             } else {
1280                 isFile = true;
1281             }
1282             return (isFile) ? new URL(base, input) : null;
1283         }
1284 
1285         /**
1286          * Attempt to return a URL by resolving input against a base URL. Returns
1287          * null if the resolved URL is not contained by the base URL.
1288          *
1289          * @return the resolved URL or null
1290          * @throws MalformedURLException
1291          */
1292         static URL tryResolveNonFile(URL base, String input) throws MalformedURLException {
1293             String child = input.replace(File.separatorChar, '/');
1294             if (isRelative(child)) {

1295                 URL url = new URL(base, child);



1296                 String bp = base.getPath();
1297                 String urlp = url.getPath();
1298                 int pos = bp.lastIndexOf('/');
1299                 if (pos == -1) {
1300                     pos = bp.length() - 1;
1301                 }
1302                 if (urlp.regionMatches(0, bp, 0, pos + 1)
1303                         && urlp.indexOf("..", pos) == -1) {
1304                     return url;
1305                 }
1306             }
1307             return null;
1308         }
1309 
1310         /**
1311          * Returns true if the given input is a relative URI.
1312          */
1313         static boolean isRelative(String child) {
1314             try {
1315                 return !URI.create(child).isAbsolute();
1316             } catch (IllegalArgumentException e) {
1317                 return false;
1318             }

1319         }
1320     }
1321 
1322     /*
1323      * Inner class used to represent a loader of classes and resources
1324      * from a file URL that refers to a directory.
1325      */
1326     private static class FileLoader extends Loader {
1327         /* Canonicalized File */
1328         private File dir;
1329 
1330         FileLoader(URL url) throws IOException {
1331             super(url);
1332             if (!"file".equals(url.getProtocol())) {
1333                 throw new IllegalArgumentException("url");
1334             }
1335             String path = url.getFile().replace('/', File.separatorChar);
1336             path = ParseUtil.decode(path);
1337             dir = (new File(path)).getCanonicalFile();
1338         }


< prev index next >