8211385: (zipfs) ZipDirectoryStream yields a stream of absolute paths when directory is relative
Reviewed-by: alanb, lancea
--- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipDirectoryStream.java Wed Oct 03 19:30:49 2018 +0000
+++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipDirectoryStream.java Wed Oct 03 12:54:54 2018 -0700
@@ -41,21 +41,21 @@
class ZipDirectoryStream implements DirectoryStream<Path> {
private final ZipFileSystem zipfs;
- private final byte[] path;
+ private final ZipPath dir;
private final DirectoryStream.Filter<? super Path> filter;
private volatile boolean isClosed;
private volatile Iterator<Path> itr;
- ZipDirectoryStream(ZipPath zipPath,
+ ZipDirectoryStream(ZipPath dir,
DirectoryStream.Filter<? super java.nio.file.Path> 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;
}
-
}
--- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java Wed Oct 03 19:30:49 2018 +0000
+++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java Wed Oct 03 12:54:54 2018 -0700
@@ -399,23 +399,32 @@
}
// returns the list of child paths of "path"
- Iterator<Path> iteratorOf(byte[] path,
+ Iterator<Path> iteratorOf(ZipPath dir,
DirectoryStream.Filter<? super Path> 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<Path> 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();
--- a/test/jdk/jdk/nio/zipfs/Basic.java Wed Oct 03 19:30:49 2018 +0000
+++ b/test/jdk/jdk/nio/zipfs/Basic.java Wed Oct 03 12:54:54 2018 -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<Path> 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<Path> 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<Path> 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