Repository: commons-compress
Updated Branches:
  refs/heads/master 08f0aba10 -> 5def510d0


COMPRESS-382 first draft of preventing OOM in LZMA


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

Branch: refs/heads/master
Commit: 70594bcaff1d553cbd35312bb63a33bcba0680d3
Parents: 0811386
Author: tballison <talli...@mitre.org>
Authored: Fri Apr 14 15:04:20 2017 -0400
Committer: tballison <talli...@mitre.org>
Committed: Fri Apr 14 15:04:20 2017 -0400

----------------------------------------------------------------------
 .../compressors/CompressorStreamFactory.java    |  15 ++++++++++--
 .../lzma/LZMACompressorInputStream.java         |  14 +++++++++--
 .../compressors/DetectCompressorTestCase.java   |  24 +++++++++++++++----
 src/test/resources/COMPRESS-382                 | Bin 0 -> 19 bytes
 4 files changed, 45 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-compress/blob/70594bca/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java
----------------------------------------------------------------------
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 55da36a..d569a8a 100644
--- 
a/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java
+++ 
b/src/main/java/org/apache/commons/compress/compressors/CompressorStreamFactory.java
@@ -349,6 +349,8 @@ public class CompressorStreamFactory implements 
CompressorStreamProvider {
      */
     private volatile boolean decompressConcatenated = false;
 
+    private volatile int lzmaMemoryLimitKb = -1;
+
     /**
      * Create an instance with the decompress Concatenated option set to false.
      */
@@ -431,7 +433,7 @@ public class CompressorStreamFactory implements 
CompressorStreamProvider {
             }
 
             if (LZMAUtils.matches(signature, signatureLength) && 
LZMAUtils.isLZMACompressionAvailable()) {
-                return new LZMACompressorInputStream(in);
+                return new LZMACompressorInputStream(in, lzmaMemoryLimitKb);
             }
 
             if (FramedLZ4CompressorInputStream.matches(signature, 
signatureLength)) {
@@ -666,5 +668,14 @@ public class CompressorStreamFactory implements 
CompressorStreamProvider {
         }
         this.decompressConcatenated = decompressConcatenated;
     }
-    
+
+    /**
+     * Set the maximum calculated memory usage for LZMA
+     * in KB.
+     *
+     * @param lzmaMemoryLimitKb
+     */
+    public void setLzmaMemoryLimitKb(int lzmaMemoryLimitKb) {
+        this.lzmaMemoryLimitKb = lzmaMemoryLimitKb;
+    }
 }

http://git-wip-us.apache.org/repos/asf/commons-compress/blob/70594bca/src/main/java/org/apache/commons/compress/compressors/lzma/LZMACompressorInputStream.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/compress/compressors/lzma/LZMACompressorInputStream.java
 
b/src/main/java/org/apache/commons/compress/compressors/lzma/LZMACompressorInputStream.java
index 556c78c..ea8a498 100644
--- 
a/src/main/java/org/apache/commons/compress/compressors/lzma/LZMACompressorInputStream.java
+++ 
b/src/main/java/org/apache/commons/compress/compressors/lzma/LZMACompressorInputStream.java
@@ -31,21 +31,31 @@ import 
org.apache.commons.compress.compressors.CompressorInputStream;
 public class LZMACompressorInputStream extends CompressorInputStream {
     private final InputStream in;
 
+    public LZMACompressorInputStream(final InputStream inputStream)
+            throws IOException {
+        in = new LZMAInputStream(inputStream, -1);
+    }
+
     /**
      * Creates a new input stream that decompresses LZMA-compressed data
      * from the specified input stream.
      *
      * @param       inputStream where to read the compressed data
      *
+     * @param       memoryLimitKb calculated memory use threshold.  Throws 
MemoryLimitException
+     *                            if calculate memory use is above this 
threshold
+     *
      * @throws      IOException if the input is not in the .lzma format,
      *                          the input is corrupt or truncated, the .lzma
      *                          headers specify sizes that are not supported
      *                          by this implementation, or the underlying
      *                          <code>inputStream</code> throws an exception
+     *
+     * @since 1.14
      */
-    public LZMACompressorInputStream(final InputStream inputStream)
+    public LZMACompressorInputStream(final InputStream inputStream, int 
memoryLimitKb)
             throws IOException {
-        in = new LZMAInputStream(inputStream);
+        in = new LZMAInputStream(inputStream, memoryLimitKb);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/commons-compress/blob/70594bca/src/test/java/org/apache/commons/compress/compressors/DetectCompressorTestCase.java
----------------------------------------------------------------------
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 674a2a0..9c446fa 100644
--- 
a/src/test/java/org/apache/commons/compress/compressors/DetectCompressorTestCase.java
+++ 
b/src/test/java/org/apache/commons/compress/compressors/DetectCompressorTestCase.java
@@ -19,22 +19,25 @@
 package org.apache.commons.compress.compressors;
 
 import static org.apache.commons.compress.AbstractTestCase.getFile;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 
-import org.apache.commons.compress.compressors.CompressorException;
-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;
 import org.junit.Test;
+import org.tukaani.xz.MemoryLimitException;
 
 @SuppressWarnings("deprecation") // deliberately tests 
setDecompressConcatenated
 public final class DetectCompressorTestCase {
@@ -160,6 +163,19 @@ public final class DetectCompressorTestCase {
         }
     }
 
+    @Test
+    public void testLZMAMemoryLimit() throws Exception {
+        CompressorStreamFactory compressorStreamFactory = new 
CompressorStreamFactory();
+        compressorStreamFactory.setLzmaMemoryLimitKb(500);
+        try {
+            InputStream is = 
compressorStreamFactory.createCompressorInputStream(
+                    new BufferedInputStream(new 
FileInputStream(getFile("COMPRESS-382"))));
+            fail("Should have thrown memory limit exception");
+        } catch (CompressorException e) {
+            assertTrue(e.getCause() instanceof MemoryLimitException);
+        }
+    }
+
     private CompressorInputStream getStreamFor(final String resource)
             throws CompressorException, IOException {
         return factory.createCompressorInputStream(

http://git-wip-us.apache.org/repos/asf/commons-compress/blob/70594bca/src/test/resources/COMPRESS-382
----------------------------------------------------------------------
diff --git a/src/test/resources/COMPRESS-382 b/src/test/resources/COMPRESS-382
new file mode 100644
index 0000000..be257f2
Binary files /dev/null and b/src/test/resources/COMPRESS-382 differ

Reply via email to