/** * Compare two paths after normalization of them. * @param path1 first path for comparison * @param path2 second path for comparison * @return whether the two paths are equivalent after normalization */ public static boolean pathEquals(String path1, String path2) { return cleanPath(path1).equals(cleanPath(path2)); }
/** * Create a new {@code ClassPathResource} for {@code Class} usage. * The path can be relative to the given class, or absolute within * the classpath via a leading slash. * @param path relative or absolute path within the class path * @param clazz the class to load resources with * @see java.lang.Class#getResourceAsStream */ public ClassPathResource(String path, @Nullable Class<?> clazz) { Assert.notNull(path, "Path must not be null"); this.path = StringUtils.cleanPath(path); this.clazz = clazz; }
/** * Create a new {@code FileSystemResource} from a {@link Path} handle, * performing all file system interactions via NIO.2 instead of {@link File}. * <p>In contrast to {@link PathResource}, this variant strictly follows the * general {@link FileSystemResource} conventions, in particular in terms of * path cleaning and {@link #createRelative(String)} handling. * @param filePath a Path handle to a file * @since 5.1 * @see #FileSystemResource(File) */ public FileSystemResource(Path filePath) { Assert.notNull(filePath, "Path must not be null"); this.path = StringUtils.cleanPath(filePath.toString()); this.file = null; this.filePath = filePath; }
/** * Create a new {@code ClassPathResource} with optional {@code ClassLoader} * and {@code Class}. Only for internal usage. * @param path relative or absolute path within the classpath * @param classLoader the class loader to load the resource with, if any * @param clazz the class to load resources with, if any * @deprecated as of 4.3.13, in favor of selective use of * {@link #ClassPathResource(String, ClassLoader)} vs {@link #ClassPathResource(String, Class)} */ @Deprecated protected ClassPathResource(String path, @Nullable ClassLoader classLoader, @Nullable Class<?> clazz) { this.path = StringUtils.cleanPath(path); this.classLoader = classLoader; this.clazz = clazz; }
/** * Determine a cleaned URL for the given original URL. * @param originalUrl the original URL * @param originalPath the original URL path * @return the cleaned URL (possibly the original URL as-is) * @see org.springframework.util.StringUtils#cleanPath */ private URL getCleanedUrl(URL originalUrl, String originalPath) { String cleanedPath = StringUtils.cleanPath(originalPath); if (!cleanedPath.equals(originalPath)) { try { return new URL(cleanedPath); } catch (MalformedURLException ex) { // Cleaned URL path cannot be converted to URL -> take original URL. } } return originalUrl; }
/** * Create a new {@code FileSystemResource} from a file path. * <p>Note: When building relative resources via {@link #createRelative}, * it makes a difference whether the specified resource base path here * ends with a slash or not. In the case of "C:/dir1/", relative paths * will be built underneath that root: e.g. relative path "dir2" -> * "C:/dir1/dir2". In the case of "C:/dir1", relative paths will apply * at the same directory level: relative path "dir2" -> "C:/dir2". * @param path a file path * @see #FileSystemResource(Path) */ public FileSystemResource(String path) { Assert.notNull(path, "Path must not be null"); this.path = StringUtils.cleanPath(path); this.file = new File(path); this.filePath = this.file.toPath(); }
/** * Create a new {@code FileSystemResource} from a {@link FileSystem} handle, * locating the specified path. * <p>This is an alternative to {@link #FileSystemResource(String)}, * performing all file system interactions via NIO.2 instead of {@link File}. * @param fileSystem the FileSystem to locate the path within * @param path a file path * @since 5.1.1 * @see #FileSystemResource(File) */ public FileSystemResource(FileSystem fileSystem, String path) { Assert.notNull(fileSystem, "FileSystem must not be null"); Assert.notNull(path, "Path must not be null"); this.path = StringUtils.cleanPath(path); this.file = null; this.filePath = fileSystem.getPath(this.path).normalize(); }
/** * Create a new {@code FileSystemResource} from a {@link File} handle. * <p>Note: When building relative resources via {@link #createRelative}, * the relative path will apply <i>at the same directory level</i>: * e.g. new File("C:/dir1"), relative path "dir2" -> "C:/dir2"! * If you prefer to have relative paths built underneath the given root directory, * use the {@link #FileSystemResource(String) constructor with a file path} * to append a trailing slash to the root path: "C:/dir1/", which indicates * this directory as root for all relative paths. * @param file a File handle * @see #FileSystemResource(Path) * @see #getFile() */ public FileSystemResource(File file) { Assert.notNull(file, "File must not be null"); this.path = StringUtils.cleanPath(file.getPath()); this.file = file; this.filePath = file.toPath(); }
/** * Create a new {@code ClassPathResource} for {@code ClassLoader} usage. * A leading slash will be removed, as the ClassLoader resource access * methods will not accept it. * @param path the absolute path within the classpath * @param classLoader the class loader to load the resource with, * or {@code null} for the thread context class loader * @see ClassLoader#getResourceAsStream(String) */ public ClassPathResource(String path, @Nullable ClassLoader classLoader) { Assert.notNull(path, "Path must not be null"); String pathToUse = StringUtils.cleanPath(path); if (pathToUse.startsWith("/")) { pathToUse = pathToUse.substring(1); } this.path = pathToUse; this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader()); }
/** * Create a new ServletContextResource. * <p>The Servlet spec requires that resource paths start with a slash, * even if many containers accept paths without leading slash too. * Consequently, the given path will be prepended with a slash if it * doesn't already start with one. * @param servletContext the ServletContext to load from * @param path the path of the resource */ public ServletContextResource(ServletContext servletContext, String path) { // check ServletContext Assert.notNull(servletContext, "Cannot resolve ServletContextResource without ServletContext"); this.servletContext = servletContext; // check path Assert.notNull(path, "Path is required"); String pathToUse = StringUtils.cleanPath(path); if (!pathToUse.startsWith("/")) { pathToUse = "/" + pathToUse; } this.path = pathToUse; }
private boolean isInvalidPath(String path) { if (path.contains("WEB-INF") || path.contains("META-INF")) { return true; } if (path.contains(":/")) { String relativePath = (path.charAt(0) == '/' ? path.substring(1) : path); if (ResourceUtils.isUrl(relativePath) || relativePath.startsWith("url:")) { return true; } } if (path.contains("..") && StringUtils.cleanPath(path).contains("../")) { return true; } return false; }
private boolean isResourceUnderLocation(Resource resource, Resource location) throws IOException { if (resource.getClass() != location.getClass()) { return false; } String resourcePath; String locationPath; if (resource instanceof UrlResource) { resourcePath = resource.getURL().toExternalForm(); locationPath = StringUtils.cleanPath(location.getURL().toString()); } else if (resource instanceof ClassPathResource) { resourcePath = ((ClassPathResource) resource).getPath(); locationPath = StringUtils.cleanPath(((ClassPathResource) location).getPath()); } else { resourcePath = resource.getURL().getPath(); locationPath = StringUtils.cleanPath(location.getURL().getPath()); } if (locationPath.equals(resourcePath)) { return true; } locationPath = (locationPath.endsWith("/") || locationPath.isEmpty() ? locationPath : locationPath + "/"); return (resourcePath.startsWith(locationPath) && !isInvalidEncodedPath(resourcePath)); }
private boolean isResourceUnderLocation(Resource resource) throws IOException { if (resource.getClass() != this.location.getClass()) { return false; } String resourcePath; String locationPath; if (resource instanceof UrlResource) { resourcePath = resource.getURL().toExternalForm(); locationPath = StringUtils.cleanPath(this.location.getURL().toString()); } else if (resource instanceof ClassPathResource) { resourcePath = ((ClassPathResource) resource).getPath(); locationPath = StringUtils.cleanPath(((ClassPathResource) this.location).getPath()); } else { resourcePath = resource.getURL().getPath(); locationPath = StringUtils.cleanPath(this.location.getURL().getPath()); } if (locationPath.equals(resourcePath)) { return true; } locationPath = (locationPath.endsWith("/") || locationPath.isEmpty() ? locationPath : locationPath + "/"); if (!resourcePath.startsWith(locationPath)) { return false; } if (resourcePath.contains("%") && StringUtils.uriDecode(resourcePath, StandardCharsets.UTF_8).contains("../")) { return false; } return true; }
@Nullable private String decodeAndNormalizePath(@Nullable String path, HttpServletRequest request) { if (path != null) { path = getUrlPathHelper().decodeRequestString(request, path); if (path.charAt(0) != '/') { String requestUri = getUrlPathHelper().getRequestUri(request); path = requestUri.substring(0, requestUri.lastIndexOf('/') + 1) + path; path = StringUtils.cleanPath(path); } } return path; }
private boolean isResourceUnderLocation(Resource resource, Resource location) throws IOException { if (resource.getClass() != location.getClass()) { return false; } String resourcePath; String locationPath; if (resource instanceof UrlResource) { resourcePath = resource.getURL().toExternalForm(); locationPath = StringUtils.cleanPath(location.getURL().toString()); } else if (resource instanceof ClassPathResource) { resourcePath = ((ClassPathResource) resource).getPath(); locationPath = StringUtils.cleanPath(((ClassPathResource) location).getPath()); } else if (resource instanceof ServletContextResource) { resourcePath = ((ServletContextResource) resource).getPath(); locationPath = StringUtils.cleanPath(((ServletContextResource) location).getPath()); } else { resourcePath = resource.getURL().getPath(); locationPath = StringUtils.cleanPath(location.getURL().getPath()); } if (locationPath.equals(resourcePath)) { return true; } locationPath = (locationPath.endsWith("/") || locationPath.isEmpty() ? locationPath : locationPath + "/"); return (resourcePath.startsWith(locationPath) && !isInvalidEncodedPath(resourcePath)); }
/** * Transform the given relative request path to an absolute path, * taking the path of the given request as a point of reference. * The resulting path is also cleaned from sequences like "path/..". * * @param path the relative path to transform * @param exchange the current exchange * @return the absolute request path for the given resource path */ protected String toAbsolutePath(String path, ServerWebExchange exchange) { String requestPath = exchange.getRequest().getURI().getPath(); String absolutePath = (path.startsWith("/") ? path : StringUtils.applyRelativePath(requestPath, path)); return StringUtils.cleanPath(absolutePath); }
/** * Transform the given relative request path to an absolute path, * taking the path of the given request as a point of reference. * The resulting path is also cleaned from sequences like "path/..". * @param path the relative path to transform * @param request the referer request * @return the absolute request path for the given resource path */ protected String toAbsolutePath(String path, HttpServletRequest request) { String absolutePath = path; if (!path.startsWith("/")) { ResourceUrlProvider urlProvider = findResourceUrlProvider(request); Assert.state(urlProvider != null, "No ResourceUrlProvider"); String requestPath = urlProvider.getUrlPathHelper().getRequestUri(request); absolutePath = StringUtils.applyRelativePath(requestPath, path); } return StringUtils.cleanPath(absolutePath); }
@Override public UriComponents normalize() { String normalizedPath = StringUtils.cleanPath(getPath()); FullPathComponent path = new FullPathComponent(normalizedPath); return new HierarchicalUriComponents(getScheme(), getFragment(), this.userInfo, this.host, this.port, path, this.queryParams, this.encodeState, this.variableEncoder); }
@Test public void testPropertyPlaceholderConfigurerWithSystemPropertyInLocation() { StaticApplicationContext ac = new StaticApplicationContext(); MutablePropertyValues pvs = new MutablePropertyValues(); pvs.add("spouse", new RuntimeBeanReference("${ref}")); ac.registerSingleton("tb", TestBean.class, pvs); pvs = new MutablePropertyValues(); pvs.add("location", "${user.dir}/test"); ac.registerSingleton("configurer", PropertyPlaceholderConfigurer.class, pvs); try { ac.refresh(); fail("Should have thrown BeanInitializationException"); } catch (BeanInitializationException ex) { // expected assertTrue(ex.getCause() instanceof FileNotFoundException); // slight hack for Linux/Unix systems String userDir = StringUtils.cleanPath(System.getProperty("user.dir")); if (userDir.startsWith("/")) { userDir = userDir.substring(1); } assertTrue(ex.getMessage().contains(userDir)); } }
@Test public void testPropertyPlaceholderConfigurerWithSystemPropertiesInLocation() { StaticApplicationContext ac = new StaticApplicationContext(); MutablePropertyValues pvs = new MutablePropertyValues(); pvs.add("spouse", new RuntimeBeanReference("${ref}")); ac.registerSingleton("tb", TestBean.class, pvs); pvs = new MutablePropertyValues(); pvs.add("location", "${user.dir}/test/${user.dir}"); ac.registerSingleton("configurer", PropertyPlaceholderConfigurer.class, pvs); try { ac.refresh(); fail("Should have thrown BeanInitializationException"); } catch (BeanInitializationException ex) { // expected assertTrue(ex.getCause() instanceof FileNotFoundException); // slight hack for Linux/Unix systems String userDir = StringUtils.cleanPath(System.getProperty("user.dir")); if (userDir.startsWith("/")) { userDir = userDir.substring(1); } /* the above hack doesn't work since the exception message is created without the leading / stripped so the test fails. Changed 17/11/04. DD */ //assertTrue(ex.getMessage().indexOf(userDir + "/test/" + userDir) != -1); assertTrue(ex.getMessage().contains(userDir + "/test/" + userDir) || ex.getMessage().contains(userDir + "/test//" + userDir)); } }