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


The following commit(s) were added to refs/heads/master by this push:
     new ae2b27c  COMPRESS-542 make memory limit configuration apply to 7z 
metadata as well
ae2b27c is described below

commit ae2b27cc011f47f0289cb24a11f2d4f1db711f8a
Author: Stefan Bodewig <bode...@apache.org>
AuthorDate: Sun Jun 6 08:20:13 2021 +0200

    COMPRESS-542 make memory limit configuration apply to 7z metadata as well
---
 src/changes/changes.xml                                 |  4 ++++
 .../commons/compress/archivers/sevenz/SevenZFile.java   | 12 +++++++++---
 .../compress/archivers/sevenz/SevenZFileOptions.java    | 17 +++++++++++------
 3 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 439187b..d713d11 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -187,6 +187,10 @@ The <action> type attribute can be add,update,fix,remove.
         Make the memory allocation in SevenZFile.readFilesInfo a lazy
         allocation to avoid OOM when dealing some giant 7z archives.
         Github Pull Request #120.
+
+        Also added sanity checks before even trying to parse an
+        archive and made SevenZFileOptions' maxMemorySizeInKb apply to
+        the stored metadata for an archive.
       </action>
       <action issue="COMPRESS-546" type="fix" date="2020-08-15"
               due-to="Maksim Zuev" dev="PeterLee">
diff --git 
a/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java 
b/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java
index f4bec6c..d84ab5e 100644
--- a/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java
+++ b/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java
@@ -45,6 +45,7 @@ import java.util.Map;
 import java.util.stream.Collectors;
 import java.util.zip.CRC32;
 
+import org.apache.commons.compress.MemoryLimitException;
 import org.apache.commons.compress.utils.BoundedInputStream;
 import org.apache.commons.compress.utils.ByteUtils;
 import org.apache.commons.compress.utils.CRC32VerifyingInputStream;
@@ -576,7 +577,7 @@ public class SevenZFile implements Closeable {
     private void readHeader(final ByteBuffer header, final Archive archive) 
throws IOException {
         final int pos = header.position();
         final ArchiveStatistics stats = 
sanityCheckAndCollectStatistics(header);
-        stats.assertValidity();
+        stats.assertValidity(options.getMaxMemoryLimitInKb());
         header.position(pos);
 
         int nid = getUnsignedByte(header);
@@ -669,7 +670,7 @@ public class SevenZFile implements Closeable {
         final int pos = header.position();
         ArchiveStatistics stats = new ArchiveStatistics();
         sanityCheckStreamsInfo(header, stats);
-        stats.assertValidity();
+        stats.assertValidity(options.getMaxMemoryLimitInKb());
         header.position(pos);
 
         readStreamsInfo(header, archive);
@@ -2191,13 +2192,18 @@ public class SevenZFile implements Closeable {
             return 2 * lowerBound /* conservative guess */;
         }
 
-        void assertValidity() throws IOException {
+        void assertValidity(int maxMemoryLimitInKb) throws IOException {
             if (numberOfEntriesWithStream > 0 && numberOfFolders == 0) {
                 throw new IOException("archive with entries but no folders");
             }
             if (numberOfEntriesWithStream > numberOfUnpackSubStreams) {
                 throw new IOException("archive doesn't contain enough 
substreams for entries");
             }
+
+            final long memoryNeededInKb = estimateSize() / 1024;
+            if (maxMemoryLimitInKb < memoryNeededInKb) {
+                throw new MemoryLimitException(memoryNeededInKb, 
maxMemoryLimitInKb);
+            }
         }
 
         private long folderSize() {
diff --git 
a/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFileOptions.java
 
b/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFileOptions.java
index 4869225..ad920b5 100644
--- 
a/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFileOptions.java
+++ 
b/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFileOptions.java
@@ -55,9 +55,12 @@ public class SevenZFileOptions {
     }
 
     /**
-     * Gets the maximum amount of memory to use for extraction. Not
-     * all codecs will honor this setting. Currently only lzma and
-     * lzma2 are supported.
+     * Gets the maximum amount of memory to use for parsing the
+     * archive and during extraction.
+     *
+     * <p>Not all codecs will honor this setting. Currently only lzma
+     * and lzma2 are supported.</p>
+     *
      * @return the maximum amount of memory to use for extraction
      */
     public int getMaxMemoryLimitInKb() {
@@ -83,9 +86,11 @@ public class SevenZFileOptions {
         private int maxMemoryLimitInKb = DEFAUL_MEMORY_LIMIT_IN_KB;
         private boolean useDefaultNameForUnnamedEntries = 
DEFAULT_USE_DEFAULTNAME_FOR_UNNAMED_ENTRIES;
         /**
-         * Sets the maximum amount of memory to use for
-         * extraction. Not all codecs will honor this
-         * setting. Currently only lzma and lzma2 are supported.
+         * Sets the maximum amount of memory to use for parsing the
+         * archive and during extraction.
+         *
+         * <p>Not all codecs will honor this setting. Currently only lzma
+         * and lzma2 are supported.</p>
          *
          * @param maxMemoryLimitInKb limit of the maximum amount of memory to 
use
          * @return the reconfigured builder

Reply via email to