--- old/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipDirectoryStream.java 2018-10-03 11:40:56.499924836 -0700 +++ new/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipDirectoryStream.java 2018-10-03 11:40:56.091887736 -0700 @@ -41,21 +41,21 @@ class ZipDirectoryStream implements DirectoryStream { private final ZipFileSystem zipfs; - private final byte[] path; + private final ZipPath dir; private final DirectoryStream.Filter filter; private volatile boolean isClosed; private volatile Iterator itr; - ZipDirectoryStream(ZipPath zipPath, + ZipDirectoryStream(ZipPath dir, DirectoryStream.Filter filter) throws IOException { - this.zipfs = zipPath.getFileSystem(); - this.path = zipPath.getResolvedPath(); + this.zipfs = dir.getFileSystem(); + this.dir = dir; this.filter = filter; // sanity check - if (!zipfs.isDirectory(path)) - throw new NotDirectoryException(zipPath.toString()); + if (!zipfs.isDirectory(dir.getResolvedPath())) + throw new NotDirectoryException(dir.toString()); } @Override @@ -66,7 +66,7 @@ throw new IllegalStateException("Iterator has already been returned"); try { - itr = zipfs.iteratorOf(path, filter); + itr = zipfs.iteratorOf(dir, filter); } catch (IOException e) { throw new IllegalStateException(e); } @@ -98,5 +98,4 @@ isClosed = true; } - } --- old/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java 2018-10-03 11:40:57.387005492 -0700 +++ new/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java 2018-10-03 11:40:56.995969938 -0700 @@ -399,23 +399,32 @@ } // returns the list of child paths of "path" - Iterator iteratorOf(byte[] path, + Iterator iteratorOf(ZipPath dir, DirectoryStream.Filter filter) throws IOException { beginWrite(); // iteration of inodes needs exclusive lock try { ensureOpen(); + byte[] path = dir.getResolvedPath(); IndexNode inode = getInode(path); if (inode == null) throw new NotDirectoryException(getString(path)); List list = new ArrayList<>(); IndexNode child = inode.child; while (child != null) { - // assume all path from zip file itself is "normalized" - ZipPath zp = new ZipPath(this, child.name, true); - if (filter == null || filter.accept(zp)) - list.add(zp); + // (1) assume all path from zip file itself is "normalized" + // (2) IndexNode.name is absolute. see IndexNode(byte[],int,int) + // (3) if parent "dir" is relative when ZipDirectoryStream + // is created, the returned child path needs to be relative + // as well. + byte[] cname = child.name; + if (!dir.isAbsolute()) { + cname = Arrays.copyOfRange(cname, 1, cname.length); + } + ZipPath zpath = new ZipPath(this, cname, true); + if (filter == null || filter.accept(zpath)) + list.add(zpath); child = child.sibling; } return list.iterator(); --- old/test/jdk/jdk/nio/zipfs/Basic.java 2018-10-03 11:40:58.287087330 -0700 +++ new/test/jdk/jdk/nio/zipfs/Basic.java 2018-10-03 11:40:57.904052504 -0700 @@ -43,7 +43,7 @@ import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; /** * @test - * @bug 8038500 8040059 8150366 8150496 8147539 + * @bug 8038500 8040059 8150366 8150496 8147539 8211385 * @summary Basic test for zip provider * * @modules jdk.zipfs @@ -89,16 +89,30 @@ // Test: DirectoryStream found = false; + try (DirectoryStream stream = Files.newDirectoryStream(fs.getPath("/"))) { for (Path entry: stream) { found = entry.toString().equals("/META-INF"); if (found) break; } } - if (!found) throw new RuntimeException("Expected file not found"); + try (DirectoryStream stream = Files.newDirectoryStream(fs.getPath("META-INF"))) { + for (Path entry: stream) { + if (entry.toString().equals("/META-INF/services")) + throw new RuntimeException("child path should be relative"); + } + } + + try (DirectoryStream stream = Files.newDirectoryStream(fs.getPath("/META-INF"))) { + for (Path entry: stream) { + if (entry.toString().equals("META-INF/services")) + throw new RuntimeException("child path should be absolute"); + } + } + // Test: copy file from zip file to current (scratch) directory Path source = fs.getPath("/META-INF/services/java.nio.file.spi.FileSystemProvider"); if (Files.exists(source)) { @@ -133,6 +147,8 @@ try { fs.provider().checkAccess(fs.getPath("/missing"), AccessMode.READ); } catch (ClosedFileSystemException x) { } + + Files.deleteIfExists(jarFile); } // FileVisitor that pretty prints a file tree