Skip to content

Commit 3a3c506

Browse files
committed
Fix #4553
This is a bug in the streaming implementation of the v0.5 decoder. The bug has always been there. It requires an uncommon block configuration, which wasn't tested at the time. v0.5 is deprecated now, latest version to produce such format is v0.5.1 from February 2016. It was superceded in April 2016. So it's both short lived and very old. Another PR will remove support of this format, but it will still be possible to explicitely request this support on demand, so better fix the issue.
1 parent ebc93b0 commit 3a3c506

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

lib/legacy/zstd_v05.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3972,8 +3972,15 @@ size_t ZBUFFv05_decompressContinue(ZBUFFv05_DCtx* zbc, void* dst, size_t* maxDst
39723972
zbc->outStart += flushedSize;
39733973
if (flushedSize == toFlushSize) {
39743974
zbc->stage = ZBUFFv05ds_read;
3975-
if (zbc->outStart + BLOCKSIZE > zbc->outBuffSize)
3976-
zbc->outStart = zbc->outEnd = 0;
3975+
if (zbc->outStart + BLOCKSIZE > zbc->outBuffSize) {
3976+
/* Not enough room for next block - need to wrap buffer.
3977+
* Preserve history: copy the last windowSize bytes to the
3978+
* beginning so that back-references can still find valid data. */
3979+
size_t const windowSize = (size_t)1 << zbc->params.windowLog;
3980+
size_t const preserveSize = MIN(zbc->outEnd, windowSize);
3981+
memmove(zbc->outBuff, zbc->outBuff + zbc->outEnd - preserveSize, preserveSize);
3982+
zbc->outStart = zbc->outEnd = preserveSize;
3983+
}
39773984
break;
39783985
}
39793986
/* cannot flush everything */

0 commit comments

Comments
 (0)