@@ -617,10 +617,12 @@ private Set<ClassPathManifestEntry> getClassPathManifestEntries() {
617617 private Set <ClassPathManifestEntry > getClassPathManifestEntriesFromJar (File jar ) throws IOException {
618618 URL base = jar .toURI ().toURL ();
619619 File parent = jar .getAbsoluteFile ().getParentFile ();
620+
620621 try (JarFile jarFile = new JarFile (jar )) {
621622 Manifest manifest = jarFile .getManifest ();
622623 Attributes attributes = (manifest != null ? manifest .getMainAttributes () : null );
623624 String classPath = (attributes != null ? attributes .getValue (Name .CLASS_PATH ) : null );
625+
624626 Set <ClassPathManifestEntry > manifestEntries = new LinkedHashSet <>();
625627 if (StringUtils .hasLength (classPath )) {
626628 StringTokenizer tokenizer = new StringTokenizer (classPath );
@@ -631,14 +633,14 @@ private Set<ClassPathManifestEntry> getClassPathManifestEntriesFromJar(File jar)
631633 continue ;
632634 }
633635
634- // Handle absolute paths correctly - don't use parent for absolute paths
636+ // Handle absolute paths correctly: do not apply parent to absolute paths.
635637 File pathFile = new File (path );
636- File candidate = pathFile .isAbsolute () ? pathFile : new File (parent , path );
638+ File candidate = ( pathFile .isAbsolute () ? pathFile : new File (parent , path ) );
637639
638- // For relative paths, enforce security check ( must be under parent)
639- // For absolute paths, just verify file exists (matching JVM behavior)
640- if (candidate .isFile () &&
641- ( pathFile . isAbsolute () || candidate .getCanonicalPath ().contains (parent .getCanonicalPath ()))) {
640+ // For relative paths, enforce security check: must be under parent.
641+ // For absolute paths, just verify file exists (matching JVM behavior).
642+ if (candidate .isFile () && ( pathFile . isAbsolute () ||
643+ candidate .getCanonicalPath ().contains (parent .getCanonicalPath ()))) {
642644 manifestEntries .add (ClassPathManifestEntry .of (candidate , this .useCaches ));
643645 }
644646 }
0 commit comments