Fix for CFH detect in ZipArchiveInputStream
The problem has been fixed in commit 86bb35a. This commit just add a
test for it, and document it in changes.xml.
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index c55b876..13c8b5d 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -236,6 +236,12 @@
Github Pull Request #127.
</action>
<action type="update" due-to="Dependabot" date="2020-09-08">Update actions/setup-java from v1.4.1 to v1.4.2 #133.</action>
+ <action type="fix" date="2020-09-24" dev="PeterLee">
+ Fix for the CFH signature detect in ZipArchiveInputStream.
+ The problem could be reproduced by a zip archive with Data
+ Descriptor and STORED, and without the Data Descriptor
+ signature.
+ </action>
</release>
<release version="1.20" date="2020-02-08"
description="Release 1.20 (Java 7)">
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 9175476..c1112bc 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
@@ -29,6 +29,7 @@
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
@@ -37,6 +38,7 @@
import java.nio.channels.Channels;
import java.nio.channels.SeekableByteChannel;
import java.util.Arrays;
+import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import org.apache.commons.compress.archivers.ArchiveEntry;
@@ -728,6 +730,15 @@
}
}
+ @Test
+ public void testZipUsingStoredWithDDAndNoDDSignature() throws IOException {
+ try (InputStream inputStream = forgeZipInputStream();
+ ZipArchiveInputStream zipInputStream = new ZipArchiveInputStream(inputStream, "UTF-8", true, true);) {
+ 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];
@@ -764,4 +775,43 @@
IOUtils.toByteArray(ais);
}
}
+
+ /**
+ * Forge a zip archive in memory, using STORED and
+ * Data Descriptor, and without signature of Data
+ * Descriptor.
+ *
+ * @return the input stream of the generated zip
+ * @throws IOException there are problems
+ */
+ private InputStream forgeZipInputStream() throws IOException {
+ try (final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ final ZipArchiveOutputStream zo = new ZipArchiveOutputStream(byteArrayOutputStream);){
+
+ final ZipArchiveEntry entryA = new ZipArchiveEntry("foo");
+ entryA.setMethod(ZipEntry.STORED);
+ entryA.setSize(4);
+ entryA.setCrc(0xb63cfbcdl);
+ zo.putArchiveEntry(entryA);
+ zo.write(new byte[] { 1, 2, 3, 4 });
+ zo.closeArchiveEntry();
+ zo.close();
+
+ final byte[] zipContent = byteArrayOutputStream.toByteArray();
+ final byte[] old = Arrays.copyOf(zipContent, zipContent.length);
+
+ final byte[] zipContentWithDataDescriptor = new byte[zipContent.length + 12];
+ System.arraycopy(zipContent, 0, zipContentWithDataDescriptor, 0, 37);
+ // modify the general purpose bit flag
+ zipContentWithDataDescriptor[6] = 8;
+
+ // copy the crc-32, compressed size and uncompressed size to the data descriptor
+ System.arraycopy(zipContent, 14, zipContentWithDataDescriptor, 37, 12);
+
+ // and copy the rest of the zip content
+ System.arraycopy(zipContent, 37, zipContentWithDataDescriptor, 49, zipContent.length - 37);
+
+ return new ByteArrayInputStream(zipContentWithDataDescriptor);
+ }
+ }
}