Bound decompression dictionaries with static size limits

This commit is contained in:
Adam Hathcock
2026-11-09 13:23:53 +00:00
parent 839dcb1ffb
commit cecd8543a4
14 changed files with 736 additions and 11 deletions

View File

@@ -327,6 +327,39 @@ await writer.WriteAllAsync("C:\\source", "*", SearchOption.AllDirectories, cance
## Common Options
### Decompression dictionary limits
`SharpCompress.Common.DictionarySizeLimits` contains process-wide static size limits
in bytes. Set them once at application startup, not around individual requests:
```csharp
// Opt in only when trusted archives require larger dictionaries.
DictionarySizeLimits.Rar5 = 256L << 20;
```
| Static property | Default maximum |
| --- | --- |
| `Rar4` | 4 MiB (the RAR4 format maximum) |
| `Rar5` | 64 MiB |
| `Lzma` (raw LZMA, LZip, ZIP, 7z) | 64 MiB |
| `Lzma2` (XZ, 7z) | 64 MiB |
| `Ppmd` (ZIP, 7z, RAR models) | 64 MiB |
| `ZStandard` (streaming windows) | 128 MiB |
Limits are read directly by the shared codecs before dictionary/model allocation,
so Archive, Reader, direct decoder, sync, and async paths use the same settings.
No reader options or decoder overloads are needed. Settings require positive values;
invalid assignments throw `ArgumentOutOfRangeException` without changing the setting.
Oversized dictionaries throw `InvalidFormatException`; Zstandard reports
`ZstdException` with `ZSTD_error_frameParameter_windowTooLarge`. Zstandard's minimum
configurable window limit is 1 KiB. Format and engine restrictions still apply.
These are dictionary/window or model limits, not total-memory, output-size, or
concurrency limits. Pool rounding and allocator overhead can increase actual memory.
Shared PPMd allocators also apply the model limit during compression. Fixed/bounded
codecs retain their format-defined bounds. Custom providers must enforce their own
limits. Zstandard's one-shot `Unwrap` APIs retain their existing output-size bounds.
### ReaderOptions
Use preset properties and fluent helpers for common configurations: