Repository: commons-compress
Updated Branches:
  refs/heads/master a12adc362 -> c66db899c


COMPRESS-436 sanity check compressed size is known for bzip etc


Project: http://git-wip-us.apache.org/repos/asf/commons-compress/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-compress/commit/c66db899
Tree: http://git-wip-us.apache.org/repos/asf/commons-compress/tree/c66db899
Diff: http://git-wip-us.apache.org/repos/asf/commons-compress/diff/c66db899

Branch: refs/heads/master
Commit: c66db899cb061c79934986f0efa19a50ca33703f
Parents: a12adc3
Author: Stefan Bodewig <bode...@apache.org>
Authored: Sun Jan 14 12:12:50 2018 +0100
Committer: Stefan Bodewig <bode...@apache.org>
Committed: Sun Jan 14 12:12:50 2018 +0100

----------------------------------------------------------------------
 src/changes/changes.xml                         |  4 ++++
 .../zip/UnsupportedZipFeatureException.java     |  7 +++++++
 .../archivers/zip/ZipArchiveInputStream.java    | 21 ++++++++++++++++++--
 .../zip/ZipArchiveInputStreamTest.java          | 16 +++++++++++++++
 4 files changed, 46 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-compress/blob/c66db899/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index e9b8d7a..46c9b56 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -97,6 +97,10 @@ The <action> type attribute can be add,update,fix,remove.
       <action issue="COMPRESS-437" type="add" date="2018-01-13">
         Added read-only DEFLATE64 support to 7z archives.
       </action>
+      <action issue="COMPRESS-436" type="update" date="2018-01-14">
+        Added a few extra sanity checks for the rarer compression
+        methods used in ZIP archives.
+      </action>
     </release>
     <release version="1.15" date="2017-10-17"
              description="Release 1.15

http://git-wip-us.apache.org/repos/asf/commons-compress/blob/c66db899/src/main/java/org/apache/commons/compress/archivers/zip/UnsupportedZipFeatureException.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/compress/archivers/zip/UnsupportedZipFeatureException.java
 
b/src/main/java/org/apache/commons/compress/archivers/zip/UnsupportedZipFeatureException.java
index 5d7bfc4..a92f9c7 100644
--- 
a/src/main/java/org/apache/commons/compress/archivers/zip/UnsupportedZipFeatureException.java
+++ 
b/src/main/java/org/apache/commons/compress/archivers/zip/UnsupportedZipFeatureException.java
@@ -112,6 +112,13 @@ public class UnsupportedZipFeatureException extends 
ZipException {
          * @since 1.5
          */
         public static final Feature SPLITTING = new Feature("splitting");
+        /**
+         * The archive contains entries with unknown compressed size
+         * for a compression method that doesn't support detection of
+         * the end of the compressed stream.
+         * @since 1.16
+         */
+        public static final Feature UNKNOWN_COMPRESSED_SIZE = new 
Feature("unknown compressed size");
 
         private final String name;
 

http://git-wip-us.apache.org/repos/asf/commons-compress/blob/c66db899/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
----------------------------------------------------------------------
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 755c7c7..41e6940 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
@@ -412,8 +412,8 @@ public class ZipArchiveInputStream extends 
ArchiveInputStream {
         if (ae instanceof ZipArchiveEntry) {
             final ZipArchiveEntry ze = (ZipArchiveEntry) ae;
             return ZipUtil.canHandleEntryData(ze)
-                && supportsDataDescriptorFor(ze);
-
+                && supportsDataDescriptorFor(ze)
+                && supportsCompressedSizeFor(ze);
         }
         return false;
     }
@@ -438,6 +438,10 @@ public class ZipArchiveInputStream extends 
ArchiveInputStream {
             throw new 
UnsupportedZipFeatureException(UnsupportedZipFeatureException.Feature.DATA_DESCRIPTOR,
                     current.entry);
         }
+        if (!supportsCompressedSizeFor(current.entry)) {
+            throw new 
UnsupportedZipFeatureException(UnsupportedZipFeatureException.Feature.UNKNOWN_COMPRESSED_SIZE,
+                    current.entry);
+        }
 
         int read;
         if (current.entry.getMethod() == ZipArchiveOutputStream.STORED) {
@@ -804,6 +808,19 @@ public class ZipArchiveInputStream extends 
ArchiveInputStream {
     }
 
     /**
+     * Whether the compressed size for the entry is either known or
+     * not required by the compression method being used.
+     */
+    private boolean supportsCompressedSizeFor(final ZipArchiveEntry entry) {
+        return entry.getCompressedSize() != ArchiveEntry.SIZE_UNKNOWN
+            || entry.getMethod() == ZipEntry.DEFLATED
+            || entry.getMethod() == ZipMethod.ENHANCED_DEFLATED.getCode()
+            || (entry.getGeneralPurposeBit().usesDataDescriptor()
+                && allowStoredEntriesWithDataDescriptor
+                && entry.getMethod() == ZipEntry.STORED);
+    }
+
+    /**
      * Caches a stored entry that uses the data descriptor.
      *
      * <ul>

http://git-wip-us.apache.org/repos/asf/commons-compress/blob/c66db899/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java
----------------------------------------------------------------------
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 853d6c8..5d1cdb1 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
@@ -21,10 +21,12 @@ package org.apache.commons.compress.archivers.zip;
 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.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
 import java.io.EOFException;
 import java.io.File;
 import java.io.FileInputStream;
@@ -324,6 +326,20 @@ public class ZipArchiveInputStreamTest {
                    ZipArchiveEntry.NameSource.NAME_WITH_EFS_FLAG);
     }
 
+    @Test
+    public void properlyMarksEntriesAsUnreadableIfUncompressedSizeIsUnknown() 
throws Exception {
+        // we never read any data
+        try (ZipArchiveInputStream zis = new ZipArchiveInputStream(new 
ByteArrayInputStream(new byte[0]))) {
+            ZipArchiveEntry e = new ZipArchiveEntry("test");
+            e.setMethod(ZipMethod.DEFLATED.getCode());
+            assertTrue(zis.canReadEntryData(e));
+            e.setMethod(ZipMethod.ENHANCED_DEFLATED.getCode());
+            assertTrue(zis.canReadEntryData(e));
+            e.setMethod(ZipMethod.BZIP2.getCode());
+            assertFalse(zis.canReadEntryData(e));
+        }
+    }
+
     private static byte[] readEntry(ZipArchiveInputStream zip, ZipArchiveEntry 
zae) throws IOException {
         final int len = (int)zae.getSize();
         final byte[] buff = new byte[len];

Reply via email to