mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-02-06 05:27:05 +00:00
Compare commits
4 Commits
master
...
copilot/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4377f4f006 | ||
|
|
f230f24109 | ||
|
|
258f9b9bd8 | ||
|
|
cc503a27fb |
@@ -37,6 +37,22 @@ public class LzmaStream : Stream, IStreamStack
|
||||
private readonly long _outputSize;
|
||||
private readonly bool _leaveOpen;
|
||||
|
||||
// Maximum dictionary size to prevent OutOfMemoryException: 512MB
|
||||
// This is a reasonable limit that balances memory usage with decompression capabilities.
|
||||
// The LZMA spec allows up to 4GB, but such large dictionaries are rarely necessary and
|
||||
// can cause OutOfMemoryException in memory-constrained environments (e.g., containers).
|
||||
//
|
||||
// Most 7z archives use much smaller dictionary sizes:
|
||||
// - Default: 32MB for solid archives, 1MB for non-solid
|
||||
// - Common maximum: 64-128MB
|
||||
// - Archives requiring >512MB dictionary are extremely rare
|
||||
//
|
||||
// If you encounter this limit with a legitimate archive, consider:
|
||||
// - Recreating the archive with a smaller dictionary size (if you control creation)
|
||||
// - Increasing available memory for the application
|
||||
// - Filing an issue to request a configurable limit option
|
||||
private const int MaxDictionarySize = 512 * 1024 * 1024; // 512MB
|
||||
|
||||
private readonly int _dictionarySize;
|
||||
private readonly OutWindow _outWindow = new();
|
||||
private readonly RangeCoder.Decoder _rangeDecoder = new();
|
||||
@@ -57,6 +73,27 @@ public class LzmaStream : Stream, IStreamStack
|
||||
private readonly Encoder _encoder;
|
||||
private bool _isDisposed;
|
||||
|
||||
private static void ValidateDictionarySize(int dictionarySize)
|
||||
{
|
||||
// Validate dictionary size
|
||||
if (dictionarySize < 0)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Invalid dictionary size ({dictionarySize}). The archive may be corrupted or use an unsupported format."
|
||||
);
|
||||
}
|
||||
|
||||
// Cap dictionary size to prevent OutOfMemoryException
|
||||
if (dictionarySize > MaxDictionarySize)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Dictionary size ({dictionarySize} bytes, {dictionarySize / (1024.0 * 1024.0):F2} MB) exceeds maximum allowed size ({MaxDictionarySize} bytes, {MaxDictionarySize / (1024.0 * 1024.0):F2} MB). "
|
||||
+ "This archive may have been created with an extremely large dictionary size setting. "
|
||||
+ "Consider recreating the archive with a smaller dictionary size."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public LzmaStream(byte[] properties, Stream inputStream, bool leaveOpen = false)
|
||||
: this(properties, inputStream, -1, -1, null, properties.Length < 5, leaveOpen) { }
|
||||
|
||||
@@ -103,6 +140,8 @@ public class LzmaStream : Stream, IStreamStack
|
||||
if (!isLzma2)
|
||||
{
|
||||
_dictionarySize = BinaryPrimitives.ReadInt32LittleEndian(properties.AsSpan(1));
|
||||
ValidateDictionarySize(_dictionarySize);
|
||||
|
||||
_outWindow.Create(_dictionarySize);
|
||||
if (presetDictionary != null)
|
||||
{
|
||||
@@ -122,6 +161,7 @@ public class LzmaStream : Stream, IStreamStack
|
||||
{
|
||||
_dictionarySize = 2 | (properties[0] & 1);
|
||||
_dictionarySize <<= (properties[0] >> 1) + 11;
|
||||
ValidateDictionarySize(_dictionarySize);
|
||||
|
||||
_outWindow.Create(_dictionarySize);
|
||||
if (presetDictionary != null)
|
||||
|
||||
@@ -204,9 +204,9 @@
|
||||
"net10.0": {
|
||||
"Microsoft.NET.ILLink.Tasks": {
|
||||
"type": "Direct",
|
||||
"requested": "[10.0.2, )",
|
||||
"resolved": "10.0.2",
|
||||
"contentHash": "sXdDtMf2qcnbygw9OdE535c2lxSxrZP8gO4UhDJ0xiJbl1wIqXS1OTcTDFTIJPOFd6Mhcm8gPEthqWGUxBsTqw=="
|
||||
"requested": "[10.0.0, )",
|
||||
"resolved": "10.0.0",
|
||||
"contentHash": "kICGrGYEzCNI3wPzfEXcwNHgTvlvVn9yJDhSdRK+oZQy4jvYH529u7O0xf5ocQKzOMjfS07+3z9PKRIjrFMJDA=="
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
@@ -246,9 +246,9 @@
|
||||
"net8.0": {
|
||||
"Microsoft.NET.ILLink.Tasks": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.23, )",
|
||||
"resolved": "8.0.23",
|
||||
"contentHash": "GqHiB1HbbODWPbY/lc5xLQH8siEEhNA0ptpJCC6X6adtAYNEzu5ZlqV3YHA3Gh7fuEwgA8XqVwMtH2KNtuQM1Q=="
|
||||
"requested": "[8.0.22, )",
|
||||
"resolved": "8.0.22",
|
||||
"contentHash": "MhcMithKEiyyNkD2ZfbDZPmcOdi0GheGfg8saEIIEfD/fol3iHmcV8TsZkD4ZYz5gdUuoX4YtlVySUU7Sxl9SQ=="
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
|
||||
Reference in New Issue
Block a user