diff --git a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java index 7b478151c43e8..cecb8b86a2dc8 100644 --- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java +++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java @@ -646,6 +646,8 @@ void setPermissions(byte[] path, Set perms) throws IOExcept } if (perms == null) { e.posixPerms = -1; + } else if (e.posixPerms == -1) { + e.posixPerms = ZipUtils.permsToFlags(perms); } else { e.posixPerms = ZipUtils.permsToFlags(perms) | (e.posixPerms & 0xFE00); // Preserve unrelated bits diff --git a/test/jdk/jdk/nio/zipfs/TestPosix.java b/test/jdk/jdk/nio/zipfs/TestPosix.java index 1fa3bdf2d7b26..179c6a55cfbf1 100644 --- a/test/jdk/jdk/nio/zipfs/TestPosix.java +++ b/test/jdk/jdk/nio/zipfs/TestPosix.java @@ -61,7 +61,7 @@ /** * @test - * @bug 8213031 8273935 + * @bug 8213031 8273935 8324635 * @summary Test POSIX ZIP file operations. * @modules jdk.zipfs * jdk.jartool @@ -719,7 +719,7 @@ public void testJarFile() throws IOException { } /** - * Verify that calling Files.setPosixPermissions with the current + * Verify that calling Files.setPosixFilePermissions with the current * permission set does not change the 'external file attributes' field. * * @throws IOException if an unexpected IOException occurs @@ -733,6 +733,53 @@ public void setPermissionsShouldPreserveRemainingBits() throws IOException { }); } + /** + * Verify that calling Files.setPosixFilePermissions on an MS-DOS entry + * results in only the expected permission bits being set + * + * @throws IOException if an unexpected IOException occurs + */ + @Test + public void setPermissionsShouldConvertToUnix() throws IOException { + // The default environment creates MS-DOS entries, with zero 'external file attributes' + createEmptyZipFile(ZIP_FILE, ENV_DEFAULT); + try (FileSystem fs = FileSystems.newFileSystem(ZIP_FILE, ENV_DEFAULT)) { + Path path = fs.getPath("hello.txt"); + Files.createFile(path); + } + // The CEN header is now as follows: + // + // 004A CENTRAL HEADER #1 02014B50 + // 004E Created Zip Spec 14 '2.0' + // 004F Created OS 00 'MS-DOS' + // 0050 Extract Zip Spec 14 '2.0' + // 0051 Extract OS 00 'MS-DOS' + // [...] + // 0070 Ext File Attributes 00000000 + + // Sanity check that all 'external file attributes' bits are all zero + verifyExternalFileAttribute(Files.readAllBytes(ZIP_FILE), "0"); + + // Convert to a UNIX entry by calling Files.setPosixFilePermissions + try (FileSystem fs = FileSystems.newFileSystem(ZIP_FILE, ENV_POSIX)) { + Path path = fs.getPath("hello.txt"); + Files.setPosixFilePermissions(path, EnumSet.of(OWNER_READ)); + } + + // The CEN header should now be as follows: + // + // 004A CENTRAL HEADER #1 02014B50 + // 004E Created Zip Spec 14 '2.0' + // 004F Created OS 03 'Unix' + // 0050 Extract Zip Spec 14 '2.0' + // 0051 Extract OS 00 'MS-DOS' + // [...] + // 0070 Ext File Attributes 01000000 + + // The first of the nine trailing permission bits should be set + verifyExternalFileAttribute(Files.readAllBytes(ZIP_FILE), "100000000"); + } + /** * Verify that a non-POSIX operation such as Files.setLastModifiedTime * does not change the 'external file attributes' field.