diff --git a/src/changes/changes.xml b/src/changes/changes.xml index ad224f7239f..73cf48cdcff 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -185,6 +185,11 @@ The type attribute can be add,update,fix,remove. allocation to avoid OOM when dealing some giant 7z archives. Github Pull Request #120. + + ZipArchiveInputStream should throw an exception if a corrputed + zip64 extra field is met. + diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java index a0ace8de73c..66fd17b9161 100644 --- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java +++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java @@ -429,6 +429,11 @@ private void processZip64Extra(final ZipLong size, final ZipLong cSize) throws Z if (!current.hasDataDescriptor) { if (z64 != null // same as current.usesZip64 but avoids NPE warning && (ZipLong.ZIP64_MAGIC.equals(cSize) || ZipLong.ZIP64_MAGIC.equals(size)) ) { + if (z64.getCompressedSize() == null || z64.getSize() == null) { + // avoid NPE if it's a corrupted zip archive + throw new ZipException("archive contains corrupted zip64 extra field"); + } + current.entry.setCompressedSize(z64.getCompressedSize().getLongValue()); current.entry.setSize(z64.getSize().getLongValue()); } else if (cSize != null && size != null) { diff --git a/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java b/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java index 9e47fcd3aad..23b695a2aaf 100644 --- a/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java +++ b/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java @@ -710,6 +710,15 @@ public void throwsIfThereIsNoEocd() throws Exception { }); } + @Test(expected = IOException.class) + public void throwsIOExceptionIfThereIsCorruptedZip64Extra() throws IOException { + try (InputStream fis = new FileInputStream(getFile("COMPRESS-546.zip")); + ZipArchiveInputStream zipInputStream = new ZipArchiveInputStream(fis);) { + while (zipInputStream.getNextZipEntry() != null) { + } + } + } + private static byte[] readEntry(final ZipArchiveInputStream zip, final ZipArchiveEntry zae) throws IOException { final int len = (int)zae.getSize(); final byte[] buff = new byte[len]; diff --git a/src/test/resources/COMPRESS-546.zip b/src/test/resources/COMPRESS-546.zip new file mode 100644 index 00000000000..0fad172e25e Binary files /dev/null and b/src/test/resources/COMPRESS-546.zip differ