OpenJDK / jdk / hs
changeset 29815:a50c9d80a80f
8076641: getNextEntry throws ArrayIndexOutOfBoundsException when unzipping file
Summary: to add extra sanity check for entry extra data
Reviewed-by: alanb
author | sherman |
---|---|
date | Mon, 06 Apr 2015 13:41:10 -0700 |
parents | 9ad0fcf27b36 |
children | 43ad6bf3975b |
files | jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java jdk/test/java/util/zip/TestExtraTime.java |
diffstat | 3 files changed, 44 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java Fri Apr 03 16:37:06 2015 -0700 +++ b/jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java Mon Apr 06 13:41:10 2015 -0700 @@ -481,6 +481,8 @@ } 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;
--- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java Fri Apr 03 16:37:06 2015 -0700 +++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java Mon Apr 06 13:41:10 2015 -0700 @@ -2271,6 +2271,8 @@ } break; case EXTID_NTFS: + if (sz < 32) + break; pos += 4; // reserved 4 bytes if (SH(extra, pos) != 0x0001) break;
--- a/jdk/test/java/util/zip/TestExtraTime.java Fri Apr 03 16:37:06 2015 -0700 +++ b/jdk/test/java/util/zip/TestExtraTime.java Mon Apr 06 13:41:10 2015 -0700 @@ -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.ZipInputStream; import java.util.zip.ZipOutputStream; - public class TestExtraTime { public static void main(String[] args) throws Throwable{ @@ -71,6 +70,7 @@ } testNullHandling(); + testTagOnlyHandling(); testTimeConversions(); } @@ -208,4 +208,42 @@ } } } + + 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); + } + } }