COMPRESS-380 support data descriptors with ENHANCED_DEFLATED
Project: http://git-wip-us.apache.org/repos/asf/commons-compress/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-compress/commit/27b16a26 Tree: http://git-wip-us.apache.org/repos/asf/commons-compress/tree/27b16a26 Diff: http://git-wip-us.apache.org/repos/asf/commons-compress/diff/27b16a26 Branch: refs/heads/master Commit: 27b16a26212d5e4b61ebe07c4bd9c36465f56702 Parents: aed74ea Author: Stefan Bodewig <bode...@apache.org> Authored: Fri Jan 5 13:31:23 2018 +0100 Committer: Stefan Bodewig <bode...@apache.org> Committed: Fri Jan 5 13:31:23 2018 +0100 ---------------------------------------------------------------------- .../archivers/zip/ZipArchiveInputStream.java | 39 +++++++++++++------ .../zip/ZipArchiveInputStreamTest.java | 19 +++++++++ src/test/resources/COMPRESS-380-dd.zip | Bin 0 -> 1391 bytes 3 files changed, 46 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-compress/blob/27b16a26/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 ea2b34f..30ccdf3 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 @@ -313,21 +313,35 @@ public class ZipArchiveInputStream extends ArchiveInputStream { current.entry.setDataOffset(getBytesRead()); current.entry.setStreamContiguous(true); + ZipMethod m = ZipMethod.getMethodByCode(current.entry.getMethod()); if (current.entry.getCompressedSize() != ArchiveEntry.SIZE_UNKNOWN) { - // FIXME this currently leaks bis if the method is not one of the supported ones - InputStream bis = new BoundedInputStream(in, current.entry.getCompressedSize()); - if (current.entry.getMethod() == ZipMethod.UNSHRINKING.getCode()) { - current.in = new UnshrinkingInputStream(bis); - } else if (current.entry.getMethod() == ZipMethod.IMPLODING.getCode()) { - current.in = new ExplodingInputStream( + if (ZipUtil.canHandleEntryData(current.entry) && m != ZipMethod.STORED && m != ZipMethod.DEFLATED) { + InputStream bis = new BoundedInputStream(in, current.entry.getCompressedSize()); + switch (m) { + case UNSHRINKING: + current.in = new UnshrinkingInputStream(bis); + break; + case IMPLODING: + current.in = new ExplodingInputStream( current.entry.getGeneralPurposeBit().getSlidingDictionarySize(), current.entry.getGeneralPurposeBit().getNumberOfShannonFanoTrees(), bis); - } else if (current.entry.getMethod() == ZipMethod.BZIP2.getCode()) { - current.in = new BZip2CompressorInputStream(bis); - } else if (current.entry.getMethod() == ZipMethod.ENHANCED_DEFLATED.getCode()) { - current.in = new Deflate64CompressorInputStream(bis); + break; + case BZIP2: + current.in = new BZip2CompressorInputStream(bis); + break; + case ENHANCED_DEFLATED: + current.in = new Deflate64CompressorInputStream(bis); + break; + default: + // we should never get here as all supported methods have been covered + // will cause an error when read is invoked, don't throw an exception here so people can + // skip unsupported entries + break; + } } + } else if (m == ZipMethod.ENHANCED_DEFLATED) { + current.in = new Deflate64CompressorInputStream(in); } entriesRead++; @@ -776,13 +790,14 @@ public class ZipArchiveInputStream extends ArchiveInputStream { * * @return true if allowStoredEntriesWithDataDescriptor is true, * the entry doesn't require any data descriptor or the method is - * DEFLATED. + * DEFLATED or ENHANCED_DEFLATED. */ private boolean supportsDataDescriptorFor(final ZipArchiveEntry entry) { return !entry.getGeneralPurposeBit().usesDataDescriptor() || (allowStoredEntriesWithDataDescriptor && entry.getMethod() == ZipEntry.STORED) - || entry.getMethod() == ZipEntry.DEFLATED; + || entry.getMethod() == ZipEntry.DEFLATED + || entry.getMethod() == ZipMethod.ENHANCED_DEFLATED.getCode(); } /** http://git-wip-us.apache.org/repos/asf/commons-compress/blob/27b16a26/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 3bb62d5..04269ad 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 @@ -221,6 +221,25 @@ public class ZipArchiveInputStreamTest { } } + @Test + public void readDeflate64CompressedStreamWithDataDescriptor() throws Exception { + // this is a copy of bla.jar with META-INF/MANIFEST.MF's method manually changed to ENHANCED_DEFLATED + final File archive = getFile("COMPRESS-380-dd.zip"); + try (ZipArchiveInputStream zin = new ZipArchiveInputStream(new FileInputStream(archive))) { + ZipArchiveEntry e = zin.getNextZipEntry(); + assertEquals(-1, e.getSize()); + assertEquals(ZipMethod.ENHANCED_DEFLATED.getCode(), e.getMethod()); + byte[] fromZip = IOUtils.toByteArray(zin); + byte[] expected = new byte[] { + 'M', 'a', 'n', 'i', 'f', 'e', 's', 't', '-', 'V', 'e', 'r', 's', 'i', 'o', 'n', ':', ' ', '1', '.', '0', + '\r', '\n', '\r', '\n' + }; + assertArrayEquals(expected, fromZip); + zin.getNextZipEntry(); + assertEquals(25, e.getSize()); + } + } + /** * Test case for * <a href="https://issues.apache.org/jira/browse/COMPRESS-364" http://git-wip-us.apache.org/repos/asf/commons-compress/blob/27b16a26/src/test/resources/COMPRESS-380-dd.zip ---------------------------------------------------------------------- diff --git a/src/test/resources/COMPRESS-380-dd.zip b/src/test/resources/COMPRESS-380-dd.zip new file mode 100644 index 0000000..9557996 Binary files /dev/null and b/src/test/resources/COMPRESS-380-dd.zip differ