1108 } 1109 if (i == 0) { 1110 urls = null; 1111 } else if (i != urls.length) { 1112 // Truncate nulls from end of array 1113 urls = Arrays.copyOf(urls, i); 1114 } 1115 return urls; 1116 } 1117 1118 static URL tryResolve(URL base, String input) throws MalformedURLException { 1119 if ("file".equalsIgnoreCase(base.getProtocol())) { 1120 return tryResolveFile(base, input); 1121 } else { 1122 return tryResolveNonFile(base, input); 1123 } 1124 } 1125 1126 /** 1127 * Attempt to return a file URL by resolving input against a base file 1128 * URL. The input is an absolute or relative file URL that encodes a 1129 * file path. 1130 * 1131 * @apiNote Nonsensical input such as a Windows file path with a drive 1132 * letter cannot be disambiguated from an absolute URL so will be rejected 1133 * (by returning null) by this method. 1134 * 1135 * @return the resolved URL or null if the input is an absolute URL with 1136 * a scheme other than file (ignoring case) 1137 * @throws MalformedURLException 1138 */ 1139 static URL tryResolveFile(URL base, String input) throws MalformedURLException { 1140 int index = input.indexOf(':'); 1141 boolean isFile; 1142 if (index >= 0) { 1143 String scheme = input.substring(0, index); 1144 isFile = "file".equalsIgnoreCase(scheme); 1145 } else { 1146 isFile = true; 1147 } 1148 return (isFile) ? new URL(base, input) : null; 1149 } 1150 1151 /** 1152 * Attempt to return a URL by resolving input against a base URL. Returns 1153 * null if the resolved URL is not contained by the base URL. 1154 * 1155 * @return the resolved URL or null 1156 * @throws MalformedURLException 1157 */ 1158 static URL tryResolveNonFile(URL base, String input) throws MalformedURLException { 1159 String child = input.replace(File.separatorChar, '/'); 1160 if (isRelative(child)) { 1161 URL url = new URL(base, child); 1162 String bp = base.getPath(); 1163 String urlp = url.getPath(); 1164 int pos = bp.lastIndexOf('/'); 1165 if (pos == -1) { 1166 pos = bp.length() - 1; 1167 } 1168 if (urlp.regionMatches(0, bp, 0, pos + 1) | 1108 } 1109 if (i == 0) { 1110 urls = null; 1111 } else if (i != urls.length) { 1112 // Truncate nulls from end of array 1113 urls = Arrays.copyOf(urls, i); 1114 } 1115 return urls; 1116 } 1117 1118 static URL tryResolve(URL base, String input) throws MalformedURLException { 1119 if ("file".equalsIgnoreCase(base.getProtocol())) { 1120 return tryResolveFile(base, input); 1121 } else { 1122 return tryResolveNonFile(base, input); 1123 } 1124 } 1125 1126 /** 1127 * Attempt to return a file URL by resolving input against a base file 1128 * URL. 1129 * @return the resolved URL or null if the input is an absolute URL with 1130 * a scheme other than file (ignoring case) 1131 * @throws MalformedURLException 1132 */ 1133 static URL tryResolveFile(URL base, String input) throws MalformedURLException { 1134 URL retVal = new URL(base, input); 1135 if (input.indexOf(':') >= 0 && 1136 !"file".equalsIgnoreCase(retVal.getProtocol())) { 1137 // 'input' contains a ':', which might be a scheme, or might be 1138 // a Windows drive letter. If the protocol for the resolved URL 1139 // isn't "file:", it should be ignored. 1140 return null; 1141 } 1142 return retVal; 1143 } 1144 1145 /** 1146 * Attempt to return a URL by resolving input against a base URL. Returns 1147 * null if the resolved URL is not contained by the base URL. 1148 * 1149 * @return the resolved URL or null 1150 * @throws MalformedURLException 1151 */ 1152 static URL tryResolveNonFile(URL base, String input) throws MalformedURLException { 1153 String child = input.replace(File.separatorChar, '/'); 1154 if (isRelative(child)) { 1155 URL url = new URL(base, child); 1156 String bp = base.getPath(); 1157 String urlp = url.getPath(); 1158 int pos = bp.lastIndexOf('/'); 1159 if (pos == -1) { 1160 pos = bp.length() - 1; 1161 } 1162 if (urlp.regionMatches(0, bp, 0, pos + 1) |