|
|
|
@ -617,10 +617,12 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol |
|
|
|
private Set<ClassPathManifestEntry> getClassPathManifestEntriesFromJar(File jar) throws IOException { |
|
|
|
private Set<ClassPathManifestEntry> getClassPathManifestEntriesFromJar(File jar) throws IOException { |
|
|
|
URL base = jar.toURI().toURL(); |
|
|
|
URL base = jar.toURI().toURL(); |
|
|
|
File parent = jar.getAbsoluteFile().getParentFile(); |
|
|
|
File parent = jar.getAbsoluteFile().getParentFile(); |
|
|
|
|
|
|
|
|
|
|
|
try (JarFile jarFile = new JarFile(jar)) { |
|
|
|
try (JarFile jarFile = new JarFile(jar)) { |
|
|
|
Manifest manifest = jarFile.getManifest(); |
|
|
|
Manifest manifest = jarFile.getManifest(); |
|
|
|
Attributes attributes = (manifest != null ? manifest.getMainAttributes() : null); |
|
|
|
Attributes attributes = (manifest != null ? manifest.getMainAttributes() : null); |
|
|
|
String classPath = (attributes != null ? attributes.getValue(Name.CLASS_PATH) : null); |
|
|
|
String classPath = (attributes != null ? attributes.getValue(Name.CLASS_PATH) : null); |
|
|
|
|
|
|
|
|
|
|
|
Set<ClassPathManifestEntry> manifestEntries = new LinkedHashSet<>(); |
|
|
|
Set<ClassPathManifestEntry> manifestEntries = new LinkedHashSet<>(); |
|
|
|
if (StringUtils.hasLength(classPath)) { |
|
|
|
if (StringUtils.hasLength(classPath)) { |
|
|
|
StringTokenizer tokenizer = new StringTokenizer(classPath); |
|
|
|
StringTokenizer tokenizer = new StringTokenizer(classPath); |
|
|
|
@ -631,14 +633,14 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Handle absolute paths correctly - don't use parent for absolute paths
|
|
|
|
// Handle absolute paths correctly: do not apply parent to absolute paths.
|
|
|
|
File pathFile = new File(path); |
|
|
|
File pathFile = new File(path); |
|
|
|
File candidate = pathFile.isAbsolute() ? pathFile : new File(parent, path); |
|
|
|
File candidate = (pathFile.isAbsolute() ? pathFile : new File(parent, path)); |
|
|
|
|
|
|
|
|
|
|
|
// For relative paths, enforce security check (must be under parent)
|
|
|
|
// For relative paths, enforce security check: must be under parent.
|
|
|
|
// For absolute paths, just verify file exists (matching JVM behavior)
|
|
|
|
// For absolute paths, just verify file exists (matching JVM behavior).
|
|
|
|
if (candidate.isFile() && |
|
|
|
if (candidate.isFile() && (pathFile.isAbsolute() || |
|
|
|
(pathFile.isAbsolute() || candidate.getCanonicalPath().contains(parent.getCanonicalPath()))) { |
|
|
|
candidate.getCanonicalPath().contains(parent.getCanonicalPath()))) { |
|
|
|
manifestEntries.add(ClassPathManifestEntry.of(candidate, this.useCaches)); |
|
|
|
manifestEntries.add(ClassPathManifestEntry.of(candidate, this.useCaches)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|