1
0
mirror of https://github.com/lz4/lz4.git synced 2026-10-24 01:48:57 +03:00

lz4: LZ4_DECODER_RING_BUFFER_SIZE() margin covers the decoder's wide copies

A ring buffer of LZ4_decoderRingBufferSize(maxBlockSize) must decode any valid stream.
When decoding restarts at the beginning of the ring, with maxBlockSize-1 bytes left at its end,
the oldest history still referenced is only margin+2 bytes ahead of the write position.
A copy writing beyond its end can overwrite it.

The margin of 14 was sized for the decoder of v1.8.x, which writes up to 16 bytes beyond a copy.
The fast decoding loop (v1.9.0+) writes up to 31 bytes (LZ4_wildCopy32), requiring a margin of 29,
and up to 63 bytes on aarch64 (LZ4_wildCopy64), requiring 61.

The margin is now 64, and a static assert ties it to the widest copy.
Buffers sized with the former macro remain too small : applications must be recompiled.
LZ4_decompress_fast_continue() is not affected (exact copies only).
This commit is contained in:
Yann Collet
2026-10-12 16:55:15 -07:00
parent fff2a63d51
commit 16d695b1af
2 changed files with 4 additions and 1 deletions

View File

@@ -2643,6 +2643,8 @@ int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dicti
*/
int LZ4_decoderRingBufferSize(int maxBlockSize)
{
/* the margin must cover the widest write beyond a copy (63 bytes, LZ4_wildCopy64), minus 2 */
LZ4_STATIC_ASSERT(LZ4_DECODER_RING_BUFFER_SIZE(0) - 65536 >= 63 - 2);
if (maxBlockSize < 0) return 0;
if (maxBlockSize > LZ4_MAX_INPUT_SIZE) return 0;
if (maxBlockSize < 16) maxBlockSize = 16;

View File

@@ -488,9 +488,10 @@ LZ4LIB_API int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const
* to be compatible with any source respecting maxBlockSize condition.
* @return : minimum ring buffer size,
* or 0 if there is an error (invalid maxBlockSize).
* Note : the former margin (+14 instead of +64) is too small for decoders >= v1.9.0.
*/
LZ4LIB_API int LZ4_decoderRingBufferSize(int maxBlockSize);
#define LZ4_DECODER_RING_BUFFER_SIZE(maxBlockSize) (65536 + 14 + (maxBlockSize)) /* for static allocation; maxBlockSize presumed valid */
#define LZ4_DECODER_RING_BUFFER_SIZE(maxBlockSize) (65536 + 64 + (maxBlockSize)) /* for static allocation; maxBlockSize presumed valid */
/*! LZ4_decompress_safe_continue() :
* This decoding function allows decompression of consecutive blocks in "streaming" mode.