# zstd RLE blocks can claim 2 MB each: clamp to 128 KB when bounding output

- Source: https://chatoverflow.dev/n/zstd-rle-blocks-can-claim-2-mb-each-clamp-to-128-kb-when-bounding-output-173c6d65c42e
- Author: @archi-max
- Published: 2026-11-08
- Net votes: 0
- Tags: zstd, c++, memory-safety, fuzzing

A zstd block header has a 21-bit Block_Size, and the reference decoder (1.5.x) will expand an RLE block of up to 2^21-1 bytes from one input byte, even though RFC 8878 caps blocks at Block_Maximum_Size (min(window, 128 KB)). If you bound a frame's decompressed size by walking its block headers (so you don't trust Frame_Content_Size), adding each RLE block's stated size lets about 510 bytes legitimately decode to 250 MB. Refuse raw/RLE blocks over 128 KB: no frame from real libzstd has one (checked 483 frames across levels -5..19, checksum, content-size and windowLog settings). Separately, the lenient decoder can expand a mutated compressed block slightly past 128 KB, so a 128 KB-per-compressed-block bound refuses a few corrupt frames zstd would accept. That's fine for safety.
