COMPRESS-316 detect DEFLATE streams with ZLIB header, submitted by Nick Burch
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/compress/trunk@1681356 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 372a7cb..1d19877 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -54,6 +54,11 @@
This also changes the superclass of ZCompressorInputStream.
">
+ <action issue="COMPRESS-316" type="add" date="2015-05-23"
+ due-to=""Nick Burch">
+ CompressorStreamFactory can now auto-detect DEFLATE streams
+ with ZLIB header.
+ </action>
<action issue="COMPRESS-314" type="fix" date="2015-05-08">
TarArchiveInputStream can now read entries with group or
user ids > 0x80000000.
diff --git a/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java b/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java
index adca670..8dc3c52 100644
--- a/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java
+++ b/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java
@@ -237,6 +237,10 @@
return new ZCompressorInputStream(in);
}
+ if (DeflateCompressorInputStream.matches(signature, signatureLength)) {
+ return new DeflateCompressorInputStream(in);
+ }
+
if (XZUtils.matches(signature, signatureLength) &&
XZUtils.isXZCompressionAvailable()) {
return new XZCompressorInputStream(in, decompressConcatenated);
diff --git a/src/main/java/org/apache/commons/compress/compressors/deflate/DeflateCompressorInputStream.java b/src/main/java/org/apache/commons/compress/compressors/deflate/DeflateCompressorInputStream.java
index a81a7a0..b8ed198 100644
--- a/src/main/java/org/apache/commons/compress/compressors/deflate/DeflateCompressorInputStream.java
+++ b/src/main/java/org/apache/commons/compress/compressors/deflate/DeflateCompressorInputStream.java
@@ -30,6 +30,12 @@
* @since 1.9
*/
public class DeflateCompressorInputStream extends CompressorInputStream {
+ private static final int MAGIC_1 = 0x78;
+ private static final int MAGIC_2a = 0x01;
+ private static final int MAGIC_2b = 0x5e;
+ private static final int MAGIC_2c = 0x9c;
+ private static final int MAGIC_2d = 0xda;
+
private final InputStream in;
/**
@@ -88,4 +94,25 @@
public void close() throws IOException {
in.close();
}
+
+ /**
+ * Checks if the signature matches what is expected for a zlib / deflated file
+ * with the zlib header.
+ *
+ * @param signature
+ * the bytes to check
+ * @param length
+ * the number of bytes to check
+ * @return true, if this stream is zlib / deflate compressed with a header
+ * stream, false otherwise
+ *
+ * @since 1.9
+ */
+ public static boolean matches(byte[] signature, int length) {
+ return length > 3 && signature[0] == MAGIC_1 && (
+ signature[1] == (byte) MAGIC_2a ||
+ signature[1] == (byte) MAGIC_2b ||
+ signature[1] == (byte) MAGIC_2c ||
+ signature[1] == (byte) MAGIC_2d);
+ }
}
diff --git a/src/test/java/org/apache/commons/compress/compressors/DetectCompressorTestCase.java b/src/test/java/org/apache/commons/compress/compressors/DetectCompressorTestCase.java
index 0fc8424..218d913 100644
--- a/src/test/java/org/apache/commons/compress/compressors/DetectCompressorTestCase.java
+++ b/src/test/java/org/apache/commons/compress/compressors/DetectCompressorTestCase.java
@@ -30,6 +30,7 @@
import org.apache.commons.compress.compressors.CompressorInputStream;
import org.apache.commons.compress.compressors.CompressorStreamFactory;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
+import org.apache.commons.compress.compressors.deflate.DeflateCompressorInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.compress.compressors.pack200.Pack200CompressorInputStream;
import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;
@@ -104,6 +105,10 @@
assertNotNull(xz);
assertTrue(xz instanceof XZCompressorInputStream);
+ CompressorInputStream zlib = getStreamFor("bla.tar.deflatez");
+ assertNotNull(zlib);
+ assertTrue(zlib instanceof DeflateCompressorInputStream);
+
try {
factory.createCompressorInputStream(new ByteArrayInputStream(new byte[0]));
fail("No exception thrown for an empty input stream");