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