diff --git a/jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java b/jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java index b61e334c131..aa93bcb368d 100644 --- a/jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java +++ b/jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java @@ -481,6 +481,8 @@ class ZipEntry implements ZipConstants, Cloneable { } break; case EXTID_NTFS: + if (sz < 32) // reserved 4 bytes + tag 2 bytes + size 2 bytes + break; // m[a|c]time 24 bytes int pos = off + 4; // reserved 4 bytes if (get16(extra, pos) != 0x0001 || get16(extra, pos + 2) != 24) break; diff --git a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java index d5cd4cf1125..17acf262266 100644 --- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java +++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java @@ -2271,6 +2271,8 @@ class ZipFileSystem extends FileSystem { } break; case EXTID_NTFS: + if (sz < 32) + break; pos += 4; // reserved 4 bytes if (SH(extra, pos) != 0x0001) break; diff --git a/jdk/test/java/util/zip/TestExtraTime.java b/jdk/test/java/util/zip/TestExtraTime.java index 20d9e36cc79..666121cdbfe 100644 --- a/jdk/test/java/util/zip/TestExtraTime.java +++ b/jdk/test/java/util/zip/TestExtraTime.java @@ -23,7 +23,7 @@ /** * @test - * @bug 4759491 6303183 7012868 8015666 8023713 8068790 + * @bug 4759491 6303183 7012868 8015666 8023713 8068790 8076641 * @summary Test ZOS and ZIS timestamp in extra field correctly */ @@ -40,7 +40,6 @@ import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; - public class TestExtraTime { public static void main(String[] args) throws Throwable{ @@ -71,6 +70,7 @@ public class TestExtraTime { } testNullHandling(); + testTagOnlyHandling(); testTimeConversions(); } @@ -208,4 +208,42 @@ public class TestExtraTime { } } } + + static void check(ZipEntry ze, byte[] extra) { + if (extra != null) { + byte[] extra1 = ze.getExtra(); + if (extra1 == null || extra1.length < extra.length || + !Arrays.equals(Arrays.copyOfRange(extra1, + extra1.length - extra.length, + extra1.length), + extra)) { + throw new RuntimeException("Timestamp: storing extra field failed!"); + } + } + } + + static void testTagOnlyHandling() throws Throwable { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] extra = new byte[] { 0x0a, 0, 4, 0, 0, 0, 0, 0 }; + try (ZipOutputStream zos = new ZipOutputStream(baos)) { + ZipEntry ze = new ZipEntry("TestExtraTime.java"); + ze.setExtra(extra); + zos.putNextEntry(ze); + zos.write(new byte[] { 1,2 ,3, 4}); + } + try (ZipInputStream zis = new ZipInputStream( + new ByteArrayInputStream(baos.toByteArray()))) { + ZipEntry ze = zis.getNextEntry(); + check(ze, extra); + } + Path zpath = Paths.get(System.getProperty("test.dir", "."), + "TestExtraTime.zip"); + Files.copy(new ByteArrayInputStream(baos.toByteArray()), zpath); + try (ZipFile zf = new ZipFile(zpath.toFile())) { + ZipEntry ze = zf.getEntry("TestExtraTime.java"); + check(ze, extra); + } finally { + Files.delete(zpath); + } + } }