< prev index next >

src/java.base/share/classes/jdk/internal/loader/URLClassPath.java

Print this page


   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


1075                             return parseClassPath(csu, value);
1076                         }
1077                     }
1078                 }
1079             }
1080             return null;
1081         }
1082 
1083         /*
1084          * Parses value of the Class-Path manifest attribute and returns
1085          * an array of URLs relative to the specified base URL.
1086          */
1087         private static URL[] parseClassPath(URL base, String value)
1088             throws MalformedURLException
1089         {
1090             StringTokenizer st = new StringTokenizer(value);
1091             URL[] urls = new URL[st.countTokens()];
1092             int i = 0;
1093             while (st.hasMoreTokens()) {
1094                 String path = st.nextToken();
1095                 URL url = DISABLE_CP_URL_CHECK ? new URL(base, path) : safeResolve(base, path);
1096                 if (url != null) {
1097                     urls[i] = url;
1098                     i++;





1099                 }
1100             }
1101             if (i == 0) {
1102                 urls = null;
1103             } else if (i != urls.length) {
1104                 // Truncate nulls from end of array
1105                 urls = Arrays.copyOf(urls, i);
1106             }
1107             return urls;
1108         }
1109 
1110         /*
1111          * Return a URL for the given path resolved against the base URL, or
1112          * null if the resulting URL is invalid.





































1113          */
1114         static URL safeResolve(URL base, String path) {
1115             String child = path.replace(File.separatorChar, '/');
1116             try {
1117                 if (!URI.create(child).isAbsolute()) {
1118                     URL url = new URL(base, child);
1119                     if (base.getProtocol().equalsIgnoreCase("file")) {
1120                         return url;
1121                     } else {
1122                         String bp = base.getPath();
1123                         String urlp = url.getPath();
1124                         int pos = bp.lastIndexOf('/');
1125                         if (pos == -1) {
1126                             pos = bp.length() - 1;
1127                         }
1128                         if (urlp.regionMatches(0, bp, 0, pos + 1)
1129                             && urlp.indexOf("..", pos) == -1) {
1130                             return url;
1131                         }
1132                     }

1133                 }
1134             } catch (MalformedURLException | IllegalArgumentException e) {}
1135             if (DEBUG_CP_URL_CHECK) {
1136                 System.err.println("Class-Path entry: \"" + path + "\" ignored in JAR file " + base);






1137             }
1138             return null;
1139         }
1140     }
1141 
1142     /*
1143      * Nested class used to represent a loader of classes and resources
1144      * from a file URL that refers to a directory.
1145      */
1146     private static class FileLoader extends Loader {
1147         /* Canonicalized File */
1148         private File dir;
1149 
1150         FileLoader(URL url) throws IOException {
1151             super(url);
1152             if (!"file".equals(url.getProtocol())) {
1153                 throw new IllegalArgumentException("url");
1154             }
1155             String path = url.getFile().replace('/', File.separatorChar);
1156             path = ParseUtil.decode(path);
1157             dir = (new File(path)).getCanonicalFile();
1158         }


   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


1075                             return parseClassPath(csu, value);
1076                         }
1077                     }
1078                 }
1079             }
1080             return null;
1081         }
1082 
1083         /*
1084          * Parses value of the Class-Path manifest attribute and returns
1085          * an array of URLs relative to the specified base URL.
1086          */
1087         private static URL[] parseClassPath(URL base, String value)
1088             throws MalformedURLException
1089         {
1090             StringTokenizer st = new StringTokenizer(value);
1091             URL[] urls = new URL[st.countTokens()];
1092             int i = 0;
1093             while (st.hasMoreTokens()) {
1094                 String path = st.nextToken();
1095                 URL url = DISABLE_CP_URL_CHECK ? new URL(base, path) : tryResolve(base, path);
1096                 if (url != null) {
1097                     urls[i] = url;
1098                     i++;
1099                 } else {
1100                     if (DEBUG_CP_URL_CHECK) {
1101                         System.err.println("Class-Path entry: \"" + path
1102                                            + "\" ignored in JAR file " + base);
1103                     }
1104                 }
1105             }
1106             if (i == 0) {
1107                 urls = null;
1108             } else if (i != urls.length) {
1109                 // Truncate nulls from end of array
1110                 urls = Arrays.copyOf(urls, i);
1111             }
1112             return urls;
1113         }
1114 
1115 
1116         static URL tryResolve(URL base, String input) throws MalformedURLException {
1117             if ("file".equalsIgnoreCase(base.getProtocol())) {
1118                 return tryResolveFile(base, input);
1119             } else {
1120                 return tryResolveNonFile(base, input);
1121             }
1122         }
1123 
1124         /**
1125          * Attempt to return a file URL by resolving input against a base file
1126          * URL. The input is an absolute or relative file URL that encodes a
1127          * file path.
1128          *
1129          * @apiNote Nonsensical input such as a Windows file path with a drive
1130          * letter cannot be disambiguated from an absolute URL so will be rejected
1131          * (by returning null) by this method.
1132          *
1133          * @return the resolved URL or null if the input is an absolute URL with
1134          *         a scheme other than file (ignoring case)
1135          * @throws MalformedURLException
1136          */
1137         static URL tryResolveFile(URL base, String input) throws MalformedURLException {
1138             int index = input.indexOf(':');
1139             boolean isFile;
1140             if (index >= 0) {
1141                 String scheme = input.substring(0, index);
1142                 isFile = "file".equalsIgnoreCase(scheme);
1143             } else {
1144                 isFile = true;
1145             }
1146             return (isFile) ? new URL(base, input) : null;
1147         }
1148 
1149         /**
1150          * Attempt to return a URL by resolving input against a base URL. Returns
1151          * null if the resolved URL is not contained by the base URL.
1152          *
1153          * @return the resolved URL or null
1154          * @throws MalformedURLException
1155          */
1156         static URL tryResolveNonFile(URL base, String input) throws MalformedURLException {
1157             String child = input.replace(File.separatorChar, '/');            
1158             if (isRelative(child)) {

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



1160                 String bp = base.getPath();
1161                 String urlp = url.getPath();
1162                 int pos = bp.lastIndexOf('/');
1163                 if (pos == -1) {
1164                     pos = bp.length() - 1;
1165                 }
1166                 if (urlp.regionMatches(0, bp, 0, pos + 1)
1167                         && urlp.indexOf("..", pos) == -1) {
1168                     return url;
1169                 }
1170             }
1171             return null;
1172         }
1173 
1174         /**
1175          * Returns true if the given input is a relative URI.
1176          */
1177         static boolean isRelative(String child) {
1178             try {
1179                 return !URI.create(child).isAbsolute();
1180             } catch (IllegalArgumentException e) {
1181                 return false;
1182             }

1183         }
1184     }
1185 
1186     /*
1187      * Nested class used to represent a loader of classes and resources
1188      * from a file URL that refers to a directory.
1189      */
1190     private static class FileLoader extends Loader {
1191         /* Canonicalized File */
1192         private File dir;
1193 
1194         FileLoader(URL url) throws IOException {
1195             super(url);
1196             if (!"file".equals(url.getProtocol())) {
1197                 throw new IllegalArgumentException("url");
1198             }
1199             String path = url.getFile().replace('/', File.separatorChar);
1200             path = ParseUtil.decode(path);
1201             dir = (new File(path)).getCanonicalFile();
1202         }


< prev index next >