Fixed issue #62, reported by @luben
This commit is contained in:
parent
2c7ac7c055
commit
3e3582719c
39
lib/zstdhc.c
39
lib/zstdhc.c
@ -942,18 +942,22 @@ static size_t ZSTD_HC_compress_generic (ZSTD_HC_CCtx* ctxPtr,
|
|||||||
void* dst, size_t maxDstSize,
|
void* dst, size_t maxDstSize,
|
||||||
const void* src, size_t srcSize)
|
const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
static const size_t blockSize = 128 KB;
|
size_t blockSize = BLOCKSIZE;
|
||||||
size_t remaining = srcSize;
|
size_t remaining = srcSize;
|
||||||
const BYTE* ip = (const BYTE*)src;
|
const BYTE* ip = (const BYTE*)src;
|
||||||
BYTE* const ostart = (BYTE*)dst;
|
BYTE* const ostart = (BYTE*)dst;
|
||||||
BYTE* op = ostart;
|
BYTE* op = ostart;
|
||||||
BYTE* const oend = op + maxDstSize;
|
|
||||||
const ZSTD_HC_blockCompressor blockCompressor = ZSTD_HC_selectBlockCompressor(ctxPtr->params.strategy);
|
const ZSTD_HC_blockCompressor blockCompressor = ZSTD_HC_selectBlockCompressor(ctxPtr->params.strategy);
|
||||||
|
|
||||||
|
while (remaining)
|
||||||
while (remaining > blockSize)
|
|
||||||
{
|
{
|
||||||
size_t cSize = blockCompressor(ctxPtr, op+3, oend-op, ip, blockSize);
|
size_t cSize;
|
||||||
|
|
||||||
|
if (maxDstSize < 5) return ERROR(dstSize_tooSmall); /* not enough space to store compressed block */
|
||||||
|
|
||||||
|
if (remaining < blockSize) blockSize = remaining;
|
||||||
|
cSize = blockCompressor(ctxPtr, op+3, maxDstSize-3, ip, blockSize);
|
||||||
|
if (ZSTD_isError(cSize)) return cSize;
|
||||||
|
|
||||||
if (cSize == 0)
|
if (cSize == 0)
|
||||||
{
|
{
|
||||||
@ -969,30 +973,9 @@ static size_t ZSTD_HC_compress_generic (ZSTD_HC_CCtx* ctxPtr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
remaining -= blockSize;
|
remaining -= blockSize;
|
||||||
|
maxDstSize -= cSize;
|
||||||
ip += blockSize;
|
ip += blockSize;
|
||||||
op += cSize;
|
op += cSize;
|
||||||
if (ZSTD_isError(cSize)) return cSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* last block */
|
|
||||||
{
|
|
||||||
size_t cSize = blockCompressor(ctxPtr, op+3, oend-op, ip, remaining);
|
|
||||||
|
|
||||||
if (cSize == 0)
|
|
||||||
{
|
|
||||||
cSize = ZSTD_noCompressBlock(op, maxDstSize, ip, remaining); /* block is not compressible */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
op[0] = (BYTE)(cSize>>16);
|
|
||||||
op[1] = (BYTE)(cSize>>8);
|
|
||||||
op[2] = (BYTE)cSize;
|
|
||||||
op[0] += (BYTE)(bt_compressed << 6); /* is a compressed block */
|
|
||||||
cSize += 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
op += cSize;
|
|
||||||
if (ZSTD_isError(cSize)) return cSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return op-ostart;
|
return op-ostart;
|
||||||
@ -1077,7 +1060,7 @@ size_t ZSTD_HC_compress_advanced (ZSTD_HC_CCtx* ctx,
|
|||||||
|
|
||||||
/* body (compression) */
|
/* body (compression) */
|
||||||
ctx->base = (const BYTE*)src;
|
ctx->base = (const BYTE*)src;
|
||||||
op += ZSTD_HC_compress_generic (ctx, op, maxDstSize, src, srcSize);
|
oSize = ZSTD_HC_compress_generic (ctx, op, maxDstSize, src, srcSize);
|
||||||
if(ZSTD_isError(oSize)) return oSize;
|
if(ZSTD_isError(oSize)) return oSize;
|
||||||
op += oSize;
|
op += oSize;
|
||||||
maxDstSize -= oSize;
|
maxDstSize -= oSize;
|
@ -328,14 +328,15 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
|
|||||||
sampleStart = FUZ_rand(&lseed) % (srcBufferSize - sampleSize);
|
sampleStart = FUZ_rand(&lseed) % (srcBufferSize - sampleSize);
|
||||||
crcOrig = XXH64(srcBuffer + sampleStart, sampleSize, 0);
|
crcOrig = XXH64(srcBuffer + sampleStart, sampleSize, 0);
|
||||||
|
|
||||||
/* HC compression test */
|
|
||||||
cLevel = (FUZ_rand(&lseed) & 3) + 2;
|
|
||||||
cSize = ZSTD_HC_compressCCtx(hcctx, cBuffer, cBufferSize, srcBuffer + sampleStart, sampleSize, cLevel);
|
|
||||||
CHECK(ZSTD_isError(cSize), "ZSTD_compress failed");
|
|
||||||
|
|
||||||
/* compression test */
|
/* compression test */
|
||||||
|
/* covered by HC cLevel 1
|
||||||
cSize = ZSTD_compressCCtx(ctx, cBuffer, cBufferSize, srcBuffer + sampleStart, sampleSize);
|
cSize = ZSTD_compressCCtx(ctx, cBuffer, cBufferSize, srcBuffer + sampleStart, sampleSize);
|
||||||
CHECK(ZSTD_isError(cSize), "ZSTD_compress failed");
|
CHECK(ZSTD_isError(cSize), "ZSTD_compress failed"); */
|
||||||
|
|
||||||
|
/* HC compression test */
|
||||||
|
cLevel = (FUZ_rand(&lseed) & 3) +1;
|
||||||
|
cSize = ZSTD_HC_compressCCtx(hcctx, cBuffer, cBufferSize, srcBuffer + sampleStart, sampleSize, cLevel);
|
||||||
|
CHECK(ZSTD_isError(cSize), "ZSTD_HC_compressCCtx failed");
|
||||||
|
|
||||||
/* compression failure test : too small dest buffer */
|
/* compression failure test : too small dest buffer */
|
||||||
if (cSize > 3)
|
if (cSize > 3)
|
||||||
@ -346,16 +347,16 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
|
|||||||
static const U32 endMark = 0x4DC2B1A9;
|
static const U32 endMark = 0x4DC2B1A9;
|
||||||
U32 endCheck;
|
U32 endCheck;
|
||||||
memcpy(dstBuffer+tooSmallSize, &endMark, 4);
|
memcpy(dstBuffer+tooSmallSize, &endMark, 4);
|
||||||
errorCode = ZSTD_compressCCtx(ctx, dstBuffer, tooSmallSize, srcBuffer + sampleStart, sampleSize);
|
errorCode = ZSTD_HC_compressCCtx(hcctx, dstBuffer, tooSmallSize, srcBuffer + sampleStart, sampleSize, cLevel);
|
||||||
CHECK(!ZSTD_isError(errorCode), "ZSTD_compress should have failed ! (buffer too small)");
|
CHECK(!ZSTD_isError(errorCode), "ZSTD_HC_compressCCtx should have failed ! (buffer too small : %u < %u)", (U32)tooSmallSize, (U32)cSize);
|
||||||
memcpy(&endCheck, dstBuffer+tooSmallSize, 4);
|
memcpy(&endCheck, dstBuffer+tooSmallSize, 4);
|
||||||
CHECK(endCheck != endMark, "ZSTD_compress : dst buffer overflow");
|
CHECK(endCheck != endMark, "ZSTD_HC_compressCCtx : dst buffer overflow");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* successfull decompression tests*/
|
/* successfull decompression tests*/
|
||||||
dSupSize = (FUZ_rand(&lseed) & 1) ? 0 : (FUZ_rand(&lseed) & 31) + 1;
|
dSupSize = (FUZ_rand(&lseed) & 1) ? 0 : (FUZ_rand(&lseed) & 31) + 1;
|
||||||
dSize = ZSTD_decompress(dstBuffer, sampleSize + dSupSize, cBuffer, cSize);
|
dSize = ZSTD_decompress(dstBuffer, sampleSize + dSupSize, cBuffer, cSize);
|
||||||
CHECK(dSize != sampleSize, "ZSTD_decompress failed (%s)", ZSTD_getErrorName(dSize));
|
CHECK(dSize != sampleSize, "ZSTD_decompress failed (%s) (srcSize : %u ; cSize : %u)", ZSTD_getErrorName(dSize), (U32)sampleSize, (U32)cSize);
|
||||||
crcDest = XXH64(dstBuffer, sampleSize, 0);
|
crcDest = XXH64(dstBuffer, sampleSize, 0);
|
||||||
CHECK(crcOrig != crcDest, "dstBuffer corrupted (pos %u / %u)", (U32)findDiff(srcBuffer+sampleStart, dstBuffer, sampleSize), (U32)sampleSize);
|
CHECK(crcOrig != crcDest, "dstBuffer corrupted (pos %u / %u)", (U32)findDiff(srcBuffer+sampleStart, dstBuffer, sampleSize), (U32)sampleSize);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user