You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by bo...@apache.org on 2019/08/18 09:59:04 UTC

[commons-compress] 02/02: COMPRESS-482 stored with data descriptor now works without DD signature

This is an automated email from the ASF dual-hosted git repository.

bodewig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-compress.git

commit 82986dd12fc255d218a6454364a50eb9ae3f812d
Author: Stefan Bodewig <bo...@apache.org>
AuthorDate: Sun Aug 18 11:57:40 2019 +0200

    COMPRESS-482 stored with data descriptor now works without DD signature
---
 .../archivers/zip/ZipArchiveInputStream.java       |   9 ++-
 .../archivers/zip/ZipArchiveInputStreamTest.java   |  76 +++++++++++++++++++++
 src/test/resources/bla-stored-dd-nosig.zip         | Bin 0 -> 1018 bytes
 src/test/resources/bla-stored-dd.zip               | Bin 0 -> 1022 bytes
 src/test/resources/bla-stored.zip                  | Bin 0 -> 1006 bytes
 5 files changed, 80 insertions(+), 5 deletions(-)

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 3d33fa4..818c1bf 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
@@ -929,18 +929,17 @@ public class ZipArchiveInputStream extends ArchiveInputStream implements InputSt
             throws IOException {
 
         boolean done = false;
-        int readTooMuch = 0;
         for (int i = 0; !done && i < offset + lastRead - 4; i++) {
             if (buf.array()[i] == LFH[0] && buf.array()[i + 1] == LFH[1]) {
+                int expectDDPos = i;
                 if ((buf.array()[i + 2] == LFH[2] && buf.array()[i + 3] == LFH[3])
                     || (buf.array()[i] == CFH[2] && buf.array()[i + 3] == CFH[3])) {
                     // found a LFH or CFH:
-                    readTooMuch = offset + lastRead - i - expectedDDLen;
+                    expectDDPos = i - expectedDDLen;
                     done = true;
                 }
                 else if (buf.array()[i + 2] == DD[2] && buf.array()[i + 3] == DD[3]) {
                     // found DD:
-                    readTooMuch = offset + lastRead - i;
                     done = true;
                 }
                 if (done) {
@@ -948,8 +947,8 @@ public class ZipArchiveInputStream extends ArchiveInputStream implements InputSt
                     //   descriptor
                     // * copy the remaining bytes to cache
                     // * read data descriptor
-                    pushback(buf.array(), offset + lastRead - readTooMuch, readTooMuch);
-                    bos.write(buf.array(), 0, i);
+                    pushback(buf.array(), expectDDPos, offset + lastRead - expectDDPos);
+                    bos.write(buf.array(), 0, expectDDPos);
                     readDataDescriptor();
                 }
             }
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 b9395fb..0392fd5 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
@@ -22,6 +22,8 @@ import static org.apache.commons.compress.AbstractTestCase.getFile;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -38,10 +40,15 @@ import java.util.zip.ZipException;
 import org.apache.commons.compress.archivers.ArchiveEntry;
 import org.apache.commons.compress.utils.IOUtils;
 import org.junit.Assert;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
 
 public class ZipArchiveInputStreamTest {
 
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
     /**
      * @see "https://issues.apache.org/jira/browse/COMPRESS-176"
      */
@@ -490,6 +497,75 @@ public class ZipArchiveInputStreamTest {
         }
     }
 
+    @Test
+    public void properlyReadsStoredEntries() throws IOException {
+        try (FileInputStream fs = new FileInputStream(getFile("bla-stored.zip"));
+             ZipArchiveInputStream archive = new ZipArchiveInputStream(fs)) {
+            ZipArchiveEntry e = archive.getNextZipEntry();
+            assertNotNull(e);
+            assertEquals("test1.xml", e.getName());
+            assertEquals(610, e.getCompressedSize());
+            assertEquals(610, e.getSize());
+            byte[] data = IOUtils.toByteArray(archive);
+            assertEquals(610, data.length);
+            e = archive.getNextZipEntry();
+            assertNotNull(e);
+            assertEquals("test2.xml", e.getName());
+            assertEquals(82, e.getCompressedSize());
+            assertEquals(82, e.getSize());
+            data = IOUtils.toByteArray(archive);
+            assertEquals(82, data.length);
+            assertNull(archive.getNextEntry());
+        }
+    }
+
+    @Test
+    public void rejectsStoredEntriesWithDataDescriptorByDefault() throws IOException {
+        try (FileInputStream fs = new FileInputStream(getFile("bla-stored-dd.zip"));
+             ZipArchiveInputStream archive = new ZipArchiveInputStream(fs)) {
+            ZipArchiveEntry e = archive.getNextZipEntry();
+            assertNotNull(e);
+            assertEquals("test1.xml", e.getName());
+            assertEquals(-1, e.getCompressedSize());
+            assertEquals(-1, e.getSize());
+            thrown.expect(UnsupportedZipFeatureException.class);
+            thrown.expectMessage("Unsupported feature data descriptor used in entry test1.xml");
+            byte[] data = IOUtils.toByteArray(archive);
+        }
+    }
+
+    @Test
+    public void properlyReadsStoredEntryWithDataDescriptorWithSignature() throws IOException {
+        try (FileInputStream fs = new FileInputStream(getFile("bla-stored-dd.zip"));
+             ZipArchiveInputStream archive = new ZipArchiveInputStream(fs, "UTF-8", true, true)) {
+            ZipArchiveEntry e = archive.getNextZipEntry();
+            assertNotNull(e);
+            assertEquals("test1.xml", e.getName());
+            assertEquals(-1, e.getCompressedSize());
+            assertEquals(-1, e.getSize());
+            byte[] data = IOUtils.toByteArray(archive);
+            assertEquals(610, data.length);
+            assertEquals(610, e.getCompressedSize());
+            assertEquals(610, e.getSize());
+        }
+    }
+
+    @Test
+    public void properlyReadsStoredEntryWithDataDescriptorWithoutSignature() throws IOException {
+        try (FileInputStream fs = new FileInputStream(getFile("bla-stored-dd-nosig.zip"));
+             ZipArchiveInputStream archive = new ZipArchiveInputStream(fs, "UTF-8", true, true)) {
+            ZipArchiveEntry e = archive.getNextZipEntry();
+            assertNotNull(e);
+            assertEquals("test1.xml", e.getName());
+            assertEquals(-1, e.getCompressedSize());
+            assertEquals(-1, e.getSize());
+            byte[] data = IOUtils.toByteArray(archive);
+            assertEquals(610, data.length);
+            assertEquals(610, e.getCompressedSize());
+            assertEquals(610, e.getSize());
+        }
+    }
+
     private static byte[] readEntry(ZipArchiveInputStream zip, ZipArchiveEntry zae) throws IOException {
         final int len = (int)zae.getSize();
         final byte[] buff = new byte[len];
diff --git a/src/test/resources/bla-stored-dd-nosig.zip b/src/test/resources/bla-stored-dd-nosig.zip
new file mode 100644
index 0000000..eb93c2e
Binary files /dev/null and b/src/test/resources/bla-stored-dd-nosig.zip differ
diff --git a/src/test/resources/bla-stored-dd.zip b/src/test/resources/bla-stored-dd.zip
new file mode 100644
index 0000000..a1aae19
Binary files /dev/null and b/src/test/resources/bla-stored-dd.zip differ
diff --git a/src/test/resources/bla-stored.zip b/src/test/resources/bla-stored.zip
new file mode 100644
index 0000000..7d44d56
Binary files /dev/null and b/src/test/resources/bla-stored.zip differ