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