[lib] Fix NULL pointer dereference
When the output buffer is `NULL` with size 0, but the frame content size is non-zero, we will write to the NULL pointer because our bounds check underflowed. This was exposed by a recent PR that allowed an empty frame into the single-pass shortcut in streaming mode. * Fix the bug. * Fix another NULL dereference in zstd-v1. * Overflow checks in 32-bit mode. * Add a dedicated test. * Expose the bug in the dedicated simple_decompress fuzzer. * Switch all mallocs in fuzzers to return NULL for size=0. * Fix a new timeout in a fuzzer. Neither clang nor gcc show a decompression speed regression on x86-64. On x86-32 clang is slightly positive and gcc loses 2.5% of speed. Credit to OSS-Fuzz.dev
parent
ad8dbae1b7
commit
5717bd39ee
|
@ -709,7 +709,9 @@ FORCE_INLINE_TEMPLATE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, c
|
||||||
state->total_len += len;
|
state->total_len += len;
|
||||||
|
|
||||||
if (state->memsize + len < 32) { /* fill in tmp buffer */
|
if (state->memsize + len < 32) { /* fill in tmp buffer */
|
||||||
XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len);
|
if (input != NULL) {
|
||||||
|
XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len);
|
||||||
|
}
|
||||||
state->memsize += (U32)len;
|
state->memsize += (U32)len;
|
||||||
return XXH_OK;
|
return XXH_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -665,15 +665,15 @@ size_t ZSTD_execSequenceEnd(BYTE* op,
|
||||||
{
|
{
|
||||||
BYTE* const oLitEnd = op + sequence.litLength;
|
BYTE* const oLitEnd = op + sequence.litLength;
|
||||||
size_t const sequenceLength = sequence.litLength + sequence.matchLength;
|
size_t const sequenceLength = sequence.litLength + sequence.matchLength;
|
||||||
BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
|
|
||||||
const BYTE* const iLitEnd = *litPtr + sequence.litLength;
|
const BYTE* const iLitEnd = *litPtr + sequence.litLength;
|
||||||
const BYTE* match = oLitEnd - sequence.offset;
|
const BYTE* match = oLitEnd - sequence.offset;
|
||||||
BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
|
BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
|
||||||
|
|
||||||
/* bounds checks */
|
/* bounds checks : careful of address space overflow in 32-bit mode */
|
||||||
assert(oLitEnd < oMatchEnd);
|
RETURN_ERROR_IF(sequenceLength > (size_t)(oend - op), dstSize_tooSmall, "last match must fit within dstBuffer");
|
||||||
RETURN_ERROR_IF(oMatchEnd > oend, dstSize_tooSmall, "last match must fit within dstBuffer");
|
RETURN_ERROR_IF(sequence.litLength > (size_t)(litLimit - *litPtr), corruption_detected, "try to read beyond literal buffer");
|
||||||
RETURN_ERROR_IF(iLitEnd > litLimit, corruption_detected, "try to read beyond literal buffer");
|
assert(op < op + sequenceLength);
|
||||||
|
assert(oLitEnd < op + sequenceLength);
|
||||||
|
|
||||||
/* copy literals */
|
/* copy literals */
|
||||||
ZSTD_safecopy(op, oend_w, *litPtr, sequence.litLength, ZSTD_no_overlap);
|
ZSTD_safecopy(op, oend_w, *litPtr, sequence.litLength, ZSTD_no_overlap);
|
||||||
|
@ -709,16 +709,27 @@ size_t ZSTD_execSequence(BYTE* op,
|
||||||
BYTE* const oLitEnd = op + sequence.litLength;
|
BYTE* const oLitEnd = op + sequence.litLength;
|
||||||
size_t const sequenceLength = sequence.litLength + sequence.matchLength;
|
size_t const sequenceLength = sequence.litLength + sequence.matchLength;
|
||||||
BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
|
BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
|
||||||
BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
|
BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; /* risk : address space underflow on oend=NULL */
|
||||||
const BYTE* const iLitEnd = *litPtr + sequence.litLength;
|
const BYTE* const iLitEnd = *litPtr + sequence.litLength;
|
||||||
const BYTE* match = oLitEnd - sequence.offset;
|
const BYTE* match = oLitEnd - sequence.offset;
|
||||||
|
|
||||||
/* Errors and uncommon cases handled here. */
|
assert(op != NULL /* Precondition */);
|
||||||
assert(oLitEnd < oMatchEnd);
|
assert(oend_w < oend /* No underflow */);
|
||||||
if (UNLIKELY(iLitEnd > litLimit || oMatchEnd > oend_w))
|
/* Handle edge cases in a slow path:
|
||||||
|
* - Read beyond end of literals
|
||||||
|
* - Match end is within WILDCOPY_OVERLIMIT of oend
|
||||||
|
* - 32-bit mode and the match length overflows
|
||||||
|
*/
|
||||||
|
if (UNLIKELY(
|
||||||
|
iLitEnd > litLimit ||
|
||||||
|
oMatchEnd > oend_w ||
|
||||||
|
(MEM_32bits() && (size_t)(oend - op) < sequenceLength + WILDCOPY_OVERLENGTH)))
|
||||||
return ZSTD_execSequenceEnd(op, oend, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd);
|
return ZSTD_execSequenceEnd(op, oend, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd);
|
||||||
|
|
||||||
/* Assumptions (everything else goes into ZSTD_execSequenceEnd()) */
|
/* Assumptions (everything else goes into ZSTD_execSequenceEnd()) */
|
||||||
|
assert(op <= oLitEnd /* No overflow */);
|
||||||
|
assert(oLitEnd < oMatchEnd /* Non-zero match & no overflow */);
|
||||||
|
assert(oMatchEnd <= oend /* No underflow */);
|
||||||
assert(iLitEnd <= litLimit /* Literal length is in bounds */);
|
assert(iLitEnd <= litLimit /* Literal length is in bounds */);
|
||||||
assert(oLitEnd <= oend_w /* Can wildcopy literals */);
|
assert(oLitEnd <= oend_w /* Can wildcopy literals */);
|
||||||
assert(oMatchEnd <= oend_w /* Can wildcopy matches */);
|
assert(oMatchEnd <= oend_w /* Can wildcopy matches */);
|
||||||
|
@ -968,6 +979,7 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx,
|
||||||
ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
|
ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
|
||||||
ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
|
ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
|
||||||
ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
|
ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
|
||||||
|
assert(dst != NULL);
|
||||||
|
|
||||||
ZSTD_STATIC_ASSERT(
|
ZSTD_STATIC_ASSERT(
|
||||||
BIT_DStream_unfinished < BIT_DStream_completed &&
|
BIT_DStream_unfinished < BIT_DStream_completed &&
|
||||||
|
@ -1043,8 +1055,10 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx,
|
||||||
/* last literal segment */
|
/* last literal segment */
|
||||||
{ size_t const lastLLSize = litEnd - litPtr;
|
{ size_t const lastLLSize = litEnd - litPtr;
|
||||||
RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
|
RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
|
||||||
memcpy(op, litPtr, lastLLSize);
|
if (op != NULL) {
|
||||||
op += lastLLSize;
|
memcpy(op, litPtr, lastLLSize);
|
||||||
|
op += lastLLSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return op-ostart;
|
return op-ostart;
|
||||||
|
@ -1093,6 +1107,7 @@ ZSTD_decompressSequencesLong_body(
|
||||||
seqState.prefixStart = prefixStart;
|
seqState.prefixStart = prefixStart;
|
||||||
seqState.pos = (size_t)(op-prefixStart);
|
seqState.pos = (size_t)(op-prefixStart);
|
||||||
seqState.dictEnd = dictEnd;
|
seqState.dictEnd = dictEnd;
|
||||||
|
assert(dst != NULL);
|
||||||
assert(iend >= ip);
|
assert(iend >= ip);
|
||||||
RETURN_ERROR_IF(
|
RETURN_ERROR_IF(
|
||||||
ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)),
|
ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)),
|
||||||
|
@ -1134,8 +1149,10 @@ ZSTD_decompressSequencesLong_body(
|
||||||
/* last literal segment */
|
/* last literal segment */
|
||||||
{ size_t const lastLLSize = litEnd - litPtr;
|
{ size_t const lastLLSize = litEnd - litPtr;
|
||||||
RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
|
RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
|
||||||
memcpy(op, litPtr, lastLLSize);
|
if (op != NULL) {
|
||||||
op += lastLLSize;
|
memcpy(op, litPtr, lastLLSize);
|
||||||
|
op += lastLLSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return op-ostart;
|
return op-ostart;
|
||||||
|
@ -1255,7 +1272,6 @@ ZSTD_getLongOffsetsShare(const ZSTD_seqSymbol* offTable)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
|
ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
|
||||||
void* dst, size_t dstCapacity,
|
void* dst, size_t dstCapacity,
|
||||||
|
@ -1297,6 +1313,8 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
|
||||||
ip += seqHSize;
|
ip += seqHSize;
|
||||||
srcSize -= seqHSize;
|
srcSize -= seqHSize;
|
||||||
|
|
||||||
|
RETURN_ERROR_IF(dst == NULL && nbSeq > 0, dstSize_tooSmall, "NULL not handled");
|
||||||
|
|
||||||
#if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \
|
#if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \
|
||||||
!defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
|
!defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
|
||||||
if ( !usePrefetchDecoder
|
if ( !usePrefetchDecoder
|
||||||
|
|
|
@ -1078,7 +1078,7 @@ static size_t HUF_decompress_usingDTable( /* -3% slower when non static */
|
||||||
BYTE* const ostart = (BYTE*) dst;
|
BYTE* const ostart = (BYTE*) dst;
|
||||||
BYTE* op = ostart;
|
BYTE* op = ostart;
|
||||||
BYTE* const omax = op + maxDstSize;
|
BYTE* const omax = op + maxDstSize;
|
||||||
BYTE* const olimit = omax-15;
|
BYTE* const olimit = maxDstSize < 15 ? op : omax-15;
|
||||||
|
|
||||||
const void* ptr = DTable;
|
const void* ptr = DTable;
|
||||||
const HUF_DElt* const dt = (const HUF_DElt*)(ptr)+1;
|
const HUF_DElt* const dt = (const HUF_DElt*)(ptr)+1;
|
||||||
|
@ -1483,7 +1483,9 @@ static size_t ZSTDv01_getcBlockSize(const void* src, size_t srcSize, blockProper
|
||||||
static size_t ZSTD_copyUncompressedBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
static size_t ZSTD_copyUncompressedBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
|
if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
|
||||||
memcpy(dst, src, srcSize);
|
if (srcSize > 0) {
|
||||||
|
memcpy(dst, src, srcSize);
|
||||||
|
}
|
||||||
return srcSize;
|
return srcSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1541,7 +1543,9 @@ static size_t ZSTDv01_decodeLiteralsBlock(void* ctx,
|
||||||
size_t rleSize = litbp.origSize;
|
size_t rleSize = litbp.origSize;
|
||||||
if (rleSize>maxDstSize) return ERROR(dstSize_tooSmall);
|
if (rleSize>maxDstSize) return ERROR(dstSize_tooSmall);
|
||||||
if (!srcSize) return ERROR(srcSize_wrong);
|
if (!srcSize) return ERROR(srcSize_wrong);
|
||||||
memset(oend - rleSize, *ip, rleSize);
|
if (rleSize > 0) {
|
||||||
|
memset(oend - rleSize, *ip, rleSize);
|
||||||
|
}
|
||||||
*litStart = oend - rleSize;
|
*litStart = oend - rleSize;
|
||||||
*litSize = rleSize;
|
*litSize = rleSize;
|
||||||
ip++;
|
ip++;
|
||||||
|
@ -1901,8 +1905,10 @@ static size_t ZSTD_decompressSequences(
|
||||||
{
|
{
|
||||||
size_t lastLLSize = litEnd - litPtr;
|
size_t lastLLSize = litEnd - litPtr;
|
||||||
if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
|
if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
|
||||||
if (op != litPtr) memmove(op, litPtr, lastLLSize);
|
if (lastLLSize > 0) {
|
||||||
op += lastLLSize;
|
if (op != litPtr) memmove(op, litPtr, lastLLSize);
|
||||||
|
op += lastLLSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2836,7 +2836,9 @@ static size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockPropertie
|
||||||
static size_t ZSTD_copyUncompressedBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
static size_t ZSTD_copyUncompressedBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
|
if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
|
||||||
memcpy(dst, src, srcSize);
|
if (srcSize > 0) {
|
||||||
|
memcpy(dst, src, srcSize);
|
||||||
|
}
|
||||||
return srcSize;
|
return srcSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3229,8 +3231,10 @@ static size_t ZSTD_decompressSequences(
|
||||||
size_t lastLLSize = litEnd - litPtr;
|
size_t lastLLSize = litEnd - litPtr;
|
||||||
if (litPtr > litEnd) return ERROR(corruption_detected);
|
if (litPtr > litEnd) return ERROR(corruption_detected);
|
||||||
if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
|
if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
|
||||||
if (op != litPtr) memmove(op, litPtr, lastLLSize);
|
if (lastLLSize > 0) {
|
||||||
op += lastLLSize;
|
if (op != litPtr) memmove(op, litPtr, lastLLSize);
|
||||||
|
op += lastLLSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2477,7 +2477,9 @@ static size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockPropertie
|
||||||
static size_t ZSTD_copyUncompressedBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
static size_t ZSTD_copyUncompressedBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
|
if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
|
||||||
memcpy(dst, src, srcSize);
|
if (srcSize > 0) {
|
||||||
|
memcpy(dst, src, srcSize);
|
||||||
|
}
|
||||||
return srcSize;
|
return srcSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2870,8 +2872,10 @@ static size_t ZSTD_decompressSequences(
|
||||||
size_t lastLLSize = litEnd - litPtr;
|
size_t lastLLSize = litEnd - litPtr;
|
||||||
if (litPtr > litEnd) return ERROR(corruption_detected);
|
if (litPtr > litEnd) return ERROR(corruption_detected);
|
||||||
if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
|
if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
|
||||||
if (op != litPtr) memmove(op, litPtr, lastLLSize);
|
if (lastLLSize > 0) {
|
||||||
op += lastLLSize;
|
if (op != litPtr) memmove(op, litPtr, lastLLSize);
|
||||||
|
op += lastLLSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2603,7 +2603,9 @@ static size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockPropertie
|
||||||
static size_t ZSTD_copyRawBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
static size_t ZSTD_copyRawBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
|
if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
|
||||||
memcpy(dst, src, srcSize);
|
if (srcSize > 0) {
|
||||||
|
memcpy(dst, src, srcSize);
|
||||||
|
}
|
||||||
return srcSize;
|
return srcSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3008,8 +3010,10 @@ static size_t ZSTD_decompressSequences(
|
||||||
size_t lastLLSize = litEnd - litPtr;
|
size_t lastLLSize = litEnd - litPtr;
|
||||||
if (litPtr > litEnd) return ERROR(corruption_detected);
|
if (litPtr > litEnd) return ERROR(corruption_detected);
|
||||||
if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
|
if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
|
||||||
if (op != litPtr) memcpy(op, litPtr, lastLLSize);
|
if (lastLLSize > 0) {
|
||||||
op += lastLLSize;
|
if (op != litPtr) memcpy(op, litPtr, lastLLSize);
|
||||||
|
op += lastLLSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3362,8 +3362,10 @@ static size_t ZSTDv05_decompressSequences(
|
||||||
size_t lastLLSize = litEnd - litPtr;
|
size_t lastLLSize = litEnd - litPtr;
|
||||||
if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
|
if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
|
||||||
if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
|
if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
|
||||||
memcpy(op, litPtr, lastLLSize);
|
if (lastLLSize > 0) {
|
||||||
op += lastLLSize;
|
memcpy(op, litPtr, lastLLSize);
|
||||||
|
op += lastLLSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return op-ostart;
|
return op-ostart;
|
||||||
|
|
|
@ -3501,8 +3501,10 @@ static size_t ZSTDv06_decompressSequences(
|
||||||
{ size_t const lastLLSize = litEnd - litPtr;
|
{ size_t const lastLLSize = litEnd - litPtr;
|
||||||
if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
|
if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
|
||||||
if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
|
if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
|
||||||
memcpy(op, litPtr, lastLLSize);
|
if (lastLLSize > 0) {
|
||||||
op += lastLLSize;
|
memcpy(op, litPtr, lastLLSize);
|
||||||
|
op += lastLLSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return op-ostart;
|
return op-ostart;
|
||||||
|
|
|
@ -3272,7 +3272,9 @@ static size_t ZSTDv07_getcBlockSize(const void* src, size_t srcSize, blockProper
|
||||||
static size_t ZSTDv07_copyRawBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
static size_t ZSTDv07_copyRawBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
if (srcSize > dstCapacity) return ERROR(dstSize_tooSmall);
|
if (srcSize > dstCapacity) return ERROR(dstSize_tooSmall);
|
||||||
memcpy(dst, src, srcSize);
|
if (srcSize > 0) {
|
||||||
|
memcpy(dst, src, srcSize);
|
||||||
|
}
|
||||||
return srcSize;
|
return srcSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3714,8 +3716,10 @@ static size_t ZSTDv07_decompressSequences(
|
||||||
{ size_t const lastLLSize = litEnd - litPtr;
|
{ size_t const lastLLSize = litEnd - litPtr;
|
||||||
/* if (litPtr > litEnd) return ERROR(corruption_detected); */ /* too many literals already used */
|
/* if (litPtr > litEnd) return ERROR(corruption_detected); */ /* too many literals already used */
|
||||||
if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
|
if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
|
||||||
memcpy(op, litPtr, lastLLSize);
|
if (lastLLSize > 0) {
|
||||||
op += lastLLSize;
|
memcpy(op, litPtr, lastLLSize);
|
||||||
|
op += lastLLSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return op-ostart;
|
return op-ostart;
|
||||||
|
@ -3776,7 +3780,9 @@ ZSTDLIBv07_API size_t ZSTDv07_insertBlock(ZSTDv07_DCtx* dctx, const void* blockS
|
||||||
static size_t ZSTDv07_generateNxBytes(void* dst, size_t dstCapacity, BYTE byte, size_t length)
|
static size_t ZSTDv07_generateNxBytes(void* dst, size_t dstCapacity, BYTE byte, size_t length)
|
||||||
{
|
{
|
||||||
if (length > dstCapacity) return ERROR(dstSize_tooSmall);
|
if (length > dstCapacity) return ERROR(dstSize_tooSmall);
|
||||||
memset(dst, byte, length);
|
if (length > 0) {
|
||||||
|
memset(dst, byte, length);
|
||||||
|
}
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ FUZZ_ARFLAGS := $(ARFLAGS)
|
||||||
FUZZ_TARGET_FLAGS = $(FUZZ_CPPFLAGS) $(FUZZ_CXXFLAGS) $(FUZZ_LDFLAGS)
|
FUZZ_TARGET_FLAGS = $(FUZZ_CPPFLAGS) $(FUZZ_CXXFLAGS) $(FUZZ_LDFLAGS)
|
||||||
|
|
||||||
FUZZ_HEADERS := fuzz_helpers.h fuzz.h zstd_helpers.h fuzz_data_producer.h
|
FUZZ_HEADERS := fuzz_helpers.h fuzz.h zstd_helpers.h fuzz_data_producer.h
|
||||||
FUZZ_SRC := $(PRGDIR)/util.c zstd_helpers.c fuzz_data_producer.c
|
FUZZ_SRC := $(PRGDIR)/util.c fuzz_helpers.c zstd_helpers.c fuzz_data_producer.c
|
||||||
|
|
||||||
ZSTDCOMMON_SRC := $(ZSTDDIR)/common/*.c
|
ZSTDCOMMON_SRC := $(ZSTDDIR)/common/*.c
|
||||||
ZSTDCOMP_SRC := $(ZSTDDIR)/compress/*.c
|
ZSTDCOMP_SRC := $(ZSTDDIR)/compress/*.c
|
||||||
|
|
|
@ -32,9 +32,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
||||||
/* Allocate all buffers and contexts if not already allocated */
|
/* Allocate all buffers and contexts if not already allocated */
|
||||||
if (neededBufSize > bufSize) {
|
if (neededBufSize > bufSize) {
|
||||||
free(rBuf);
|
free(rBuf);
|
||||||
rBuf = malloc(neededBufSize);
|
rBuf = FUZZ_malloc(neededBufSize);
|
||||||
bufSize = neededBufSize;
|
bufSize = neededBufSize;
|
||||||
FUZZ_ASSERT(rBuf);
|
|
||||||
}
|
}
|
||||||
if (!dctx) {
|
if (!dctx) {
|
||||||
dctx = ZSTD_createDCtx();
|
dctx = ZSTD_createDCtx();
|
||||||
|
|
|
@ -43,7 +43,9 @@ static size_t roundTripTest(void *result, size_t resultCapacity,
|
||||||
FUZZ_ZASSERT(ret);
|
FUZZ_ZASSERT(ret);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
FUZZ_ASSERT(resultCapacity >= srcSize);
|
FUZZ_ASSERT(resultCapacity >= srcSize);
|
||||||
memcpy(result, src, srcSize);
|
if (srcSize > 0) {
|
||||||
|
memcpy(result, src, srcSize);
|
||||||
|
}
|
||||||
return srcSize;
|
return srcSize;
|
||||||
}
|
}
|
||||||
ZSTD_decompressBegin(dctx);
|
ZSTD_decompressBegin(dctx);
|
||||||
|
@ -67,10 +69,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
||||||
if (neededBufSize > bufSize || !cBuf || !rBuf) {
|
if (neededBufSize > bufSize || !cBuf || !rBuf) {
|
||||||
free(cBuf);
|
free(cBuf);
|
||||||
free(rBuf);
|
free(rBuf);
|
||||||
cBuf = malloc(neededBufSize);
|
cBuf = FUZZ_malloc(neededBufSize);
|
||||||
rBuf = malloc(neededBufSize);
|
rBuf = FUZZ_malloc(neededBufSize);
|
||||||
bufSize = neededBufSize;
|
bufSize = neededBufSize;
|
||||||
FUZZ_ASSERT(cBuf && rBuf);
|
|
||||||
}
|
}
|
||||||
if (!cctx) {
|
if (!cctx) {
|
||||||
cctx = ZSTD_createCCtx();
|
cctx = ZSTD_createCCtx();
|
||||||
|
@ -87,7 +88,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
||||||
cLevel);
|
cLevel);
|
||||||
FUZZ_ZASSERT(result);
|
FUZZ_ZASSERT(result);
|
||||||
FUZZ_ASSERT_MSG(result == size, "Incorrect regenerated size");
|
FUZZ_ASSERT_MSG(result == size, "Incorrect regenerated size");
|
||||||
FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!");
|
FUZZ_ASSERT_MSG(!FUZZ_memcmp(src, rBuf, size), "Corruption!");
|
||||||
}
|
}
|
||||||
FUZZ_dataProducer_free(producer);
|
FUZZ_dataProducer_free(producer);
|
||||||
#ifndef STATEFUL_FUZZING
|
#ifndef STATEFUL_FUZZING
|
||||||
|
|
|
@ -55,8 +55,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
||||||
|
|
||||||
{
|
{
|
||||||
size_t const bufSize = FUZZ_dataProducer_uint32Range(producer, 0, 10 * size);
|
size_t const bufSize = FUZZ_dataProducer_uint32Range(producer, 0, 10 * size);
|
||||||
void* rBuf = malloc(bufSize);
|
void* rBuf = FUZZ_malloc(bufSize);
|
||||||
FUZZ_ASSERT(rBuf);
|
|
||||||
if (ddict) {
|
if (ddict) {
|
||||||
ZSTD_decompress_usingDDict(dctx, rBuf, bufSize, src, size, ddict);
|
ZSTD_decompress_usingDDict(dctx, rBuf, bufSize, src, size, ddict);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -79,11 +79,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
||||||
DEBUGLOG(2, "Dict content type %d", dct);
|
DEBUGLOG(2, "Dict content type %d", dct);
|
||||||
DEBUGLOG(2, "Dict size %u", (unsigned)size);
|
DEBUGLOG(2, "Dict size %u", (unsigned)size);
|
||||||
|
|
||||||
void* const rBuf = malloc(size);
|
void* const rBuf = FUZZ_malloc(size);
|
||||||
FUZZ_ASSERT(rBuf);
|
|
||||||
size_t const cBufSize = ZSTD_compressBound(size);
|
size_t const cBufSize = ZSTD_compressBound(size);
|
||||||
void* const cBuf = malloc(cBufSize);
|
void* const cBuf = FUZZ_malloc(cBufSize);
|
||||||
FUZZ_ASSERT(cBuf);
|
|
||||||
|
|
||||||
size_t const cSize =
|
size_t const cSize =
|
||||||
compress(cBuf, cBufSize, src, size, src, size, dlm, dct, refPrefix);
|
compress(cBuf, cBufSize, src, size, src, size, dlm, dct, refPrefix);
|
||||||
|
@ -95,7 +93,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
||||||
size_t const rSize =
|
size_t const rSize =
|
||||||
decompress(rBuf, size, cBuf, cSize, src, size, dlm, dct, refPrefix);
|
decompress(rBuf, size, cBuf, cSize, src, size, dlm, dct, refPrefix);
|
||||||
FUZZ_ASSERT_MSG(rSize == size, "Incorrect regenerated size");
|
FUZZ_ASSERT_MSG(rSize == size, "Incorrect regenerated size");
|
||||||
FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!");
|
FUZZ_ASSERT_MSG(!FUZZ_memcmp(src, rBuf, size), "Corruption!");
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free(cBuf);
|
free(cBuf);
|
||||||
|
|
|
@ -84,7 +84,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
||||||
size = FUZZ_dataProducer_reserveDataPrefix(producer);
|
size = FUZZ_dataProducer_reserveDataPrefix(producer);
|
||||||
|
|
||||||
size_t const rBufSize = size;
|
size_t const rBufSize = size;
|
||||||
void* rBuf = malloc(rBufSize);
|
void* rBuf = FUZZ_malloc(rBufSize);
|
||||||
size_t cBufSize = ZSTD_compressBound(size) * 2;
|
size_t cBufSize = ZSTD_compressBound(size) * 2;
|
||||||
void *cBuf;
|
void *cBuf;
|
||||||
/* Half of the time fuzz with a 1 byte smaller output size.
|
/* Half of the time fuzz with a 1 byte smaller output size.
|
||||||
|
@ -92,7 +92,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
||||||
* giving us 4 bytes of overhead.
|
* giving us 4 bytes of overhead.
|
||||||
*/
|
*/
|
||||||
cBufSize -= FUZZ_dataProducer_uint32Range(producer, 0, 1);
|
cBufSize -= FUZZ_dataProducer_uint32Range(producer, 0, 1);
|
||||||
cBuf = malloc(cBufSize);
|
cBuf = FUZZ_malloc(cBufSize);
|
||||||
|
|
||||||
if (!cctx) {
|
if (!cctx) {
|
||||||
cctx = ZSTD_createCCtx();
|
cctx = ZSTD_createCCtx();
|
||||||
|
@ -108,7 +108,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
||||||
roundTripTest(rBuf, rBufSize, cBuf, cBufSize, src, size, producer);
|
roundTripTest(rBuf, rBufSize, cBuf, cBufSize, src, size, producer);
|
||||||
FUZZ_ZASSERT(result);
|
FUZZ_ZASSERT(result);
|
||||||
FUZZ_ASSERT_MSG(result == size, "Incorrect regenerated size");
|
FUZZ_ASSERT_MSG(result == size, "Incorrect regenerated size");
|
||||||
FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!");
|
FUZZ_ASSERT_MSG(!FUZZ_memcmp(src, rBuf, size), "Corruption!");
|
||||||
}
|
}
|
||||||
free(rBuf);
|
free(rBuf);
|
||||||
free(cBuf);
|
free(cBuf);
|
||||||
|
|
|
@ -16,9 +16,7 @@ struct FUZZ_dataProducer_s{
|
||||||
};
|
};
|
||||||
|
|
||||||
FUZZ_dataProducer_t *FUZZ_dataProducer_create(const uint8_t *data, size_t size) {
|
FUZZ_dataProducer_t *FUZZ_dataProducer_create(const uint8_t *data, size_t size) {
|
||||||
FUZZ_dataProducer_t *producer = malloc(sizeof(FUZZ_dataProducer_t));
|
FUZZ_dataProducer_t *producer = FUZZ_malloc(sizeof(FUZZ_dataProducer_t));
|
||||||
|
|
||||||
FUZZ_ASSERT(producer != NULL);
|
|
||||||
|
|
||||||
producer->data = data;
|
producer->data = data;
|
||||||
producer->size = size;
|
producer->size = size;
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under both the BSD-style license (found in the
|
||||||
|
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||||
|
* in the COPYING file in the root directory of this source tree).
|
||||||
|
* You may select, at your option, one of the above-listed licenses.
|
||||||
|
*/
|
||||||
|
#include "fuzz_helpers.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void* FUZZ_malloc(size_t size)
|
||||||
|
{
|
||||||
|
if (size > 0) {
|
||||||
|
void* const mem = malloc(size);
|
||||||
|
FUZZ_ASSERT(mem);
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FUZZ_memcmp(void const* lhs, void const* rhs, size_t size)
|
||||||
|
{
|
||||||
|
if (size == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return memcmp(lhs, rhs, size);
|
||||||
|
}
|
|
@ -56,6 +56,17 @@ extern "C" {
|
||||||
#define FUZZ_STATIC static
|
#define FUZZ_STATIC static
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* malloc except return NULL for zero sized data and FUZZ_ASSERT
|
||||||
|
* that malloc doesn't fail.
|
||||||
|
*/
|
||||||
|
void* FUZZ_malloc(size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* memcmp but accepts NULL.
|
||||||
|
*/
|
||||||
|
int FUZZ_memcmp(void const* lhs, void const* rhs, size_t size);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -41,8 +41,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
||||||
FUZZ_ASSERT(cctx);
|
FUZZ_ASSERT(cctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *rBuf = malloc(bufSize);
|
void *rBuf = FUZZ_malloc(bufSize);
|
||||||
FUZZ_ASSERT(rBuf);
|
|
||||||
ZSTD_compressCCtx(cctx, rBuf, bufSize, src, size, cLevel);
|
ZSTD_compressCCtx(cctx, rBuf, bufSize, src, size, cLevel);
|
||||||
free(rBuf);
|
free(rBuf);
|
||||||
FUZZ_dataProducer_free(producer);
|
FUZZ_dataProducer_free(producer);
|
||||||
|
|
|
@ -35,8 +35,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t const bufSize = FUZZ_dataProducer_uint32Range(producer, 0, 10 * size);
|
size_t const bufSize = FUZZ_dataProducer_uint32Range(producer, 0, 10 * size);
|
||||||
void *rBuf = malloc(bufSize);
|
void *rBuf = FUZZ_malloc(bufSize);
|
||||||
FUZZ_ASSERT(rBuf);
|
|
||||||
|
|
||||||
ZSTD_decompressDCtx(dctx, rBuf, bufSize, src, size);
|
ZSTD_decompressDCtx(dctx, rBuf, bufSize, src, size);
|
||||||
free(rBuf);
|
free(rBuf);
|
||||||
|
|
|
@ -70,7 +70,7 @@ static size_t roundTripTest(void *result, size_t resultCapacity,
|
||||||
int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
||||||
{
|
{
|
||||||
size_t const rBufSize = size;
|
size_t const rBufSize = size;
|
||||||
void* rBuf = malloc(rBufSize);
|
void* rBuf = FUZZ_malloc(rBufSize);
|
||||||
size_t cBufSize = ZSTD_compressBound(size);
|
size_t cBufSize = ZSTD_compressBound(size);
|
||||||
void* cBuf;
|
void* cBuf;
|
||||||
|
|
||||||
|
@ -85,9 +85,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
||||||
*/
|
*/
|
||||||
cBufSize -= FUZZ_dataProducer_uint32Range(producer, 0, 1);
|
cBufSize -= FUZZ_dataProducer_uint32Range(producer, 0, 1);
|
||||||
|
|
||||||
cBuf = malloc(cBufSize);
|
cBuf = FUZZ_malloc(cBufSize);
|
||||||
|
|
||||||
FUZZ_ASSERT(cBuf && rBuf);
|
|
||||||
|
|
||||||
if (!cctx) {
|
if (!cctx) {
|
||||||
cctx = ZSTD_createCCtx();
|
cctx = ZSTD_createCCtx();
|
||||||
|
@ -103,7 +101,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
||||||
roundTripTest(rBuf, rBufSize, cBuf, cBufSize, src, size, producer);
|
roundTripTest(rBuf, rBufSize, cBuf, cBufSize, src, size, producer);
|
||||||
FUZZ_ZASSERT(result);
|
FUZZ_ZASSERT(result);
|
||||||
FUZZ_ASSERT_MSG(result == size, "Incorrect regenerated size");
|
FUZZ_ASSERT_MSG(result == size, "Incorrect regenerated size");
|
||||||
FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!");
|
FUZZ_ASSERT_MSG(!FUZZ_memcmp(src, rBuf, size), "Corruption!");
|
||||||
}
|
}
|
||||||
free(rBuf);
|
free(rBuf);
|
||||||
free(cBuf);
|
free(cBuf);
|
||||||
|
|
|
@ -76,9 +76,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
||||||
|
|
||||||
/* Allocate all buffers and contexts if not already allocated */
|
/* Allocate all buffers and contexts if not already allocated */
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
buf = malloc(kBufSize);
|
buf = FUZZ_malloc(kBufSize);
|
||||||
FUZZ_ASSERT(buf);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!dstream) {
|
if (!dstream) {
|
||||||
dstream = ZSTD_createDStream();
|
dstream = ZSTD_createDStream();
|
||||||
|
@ -99,7 +98,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
||||||
ZSTD_inBuffer in = makeInBuffer(&src, &size, producer, prevInWasZero ? 1 : 0);
|
ZSTD_inBuffer in = makeInBuffer(&src, &size, producer, prevInWasZero ? 1 : 0);
|
||||||
prevInWasZero = in.size == 0;
|
prevInWasZero = in.size == 0;
|
||||||
while (in.pos != in.size) {
|
while (in.pos != in.size) {
|
||||||
if (!stableOutBuffer || FUZZ_dataProducer_uint32Range(producer, 0, 100) == 55) {
|
if (!stableOutBuffer || prevOutWasZero || FUZZ_dataProducer_uint32Range(producer, 0, 100) == 55) {
|
||||||
out = makeOutBuffer(producer, prevOutWasZero ? 1 : 0);
|
out = makeOutBuffer(producer, prevOutWasZero ? 1 : 0);
|
||||||
}
|
}
|
||||||
prevOutWasZero = out.size == 0;
|
prevOutWasZero = out.size == 0;
|
||||||
|
|
|
@ -146,10 +146,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
||||||
if (neededBufSize > bufSize) {
|
if (neededBufSize > bufSize) {
|
||||||
free(cBuf);
|
free(cBuf);
|
||||||
free(rBuf);
|
free(rBuf);
|
||||||
cBuf = (uint8_t*)malloc(neededBufSize);
|
cBuf = (uint8_t*)FUZZ_malloc(neededBufSize);
|
||||||
rBuf = (uint8_t*)malloc(neededBufSize);
|
rBuf = (uint8_t*)FUZZ_malloc(neededBufSize);
|
||||||
bufSize = neededBufSize;
|
bufSize = neededBufSize;
|
||||||
FUZZ_ASSERT(cBuf && rBuf);
|
|
||||||
}
|
}
|
||||||
if (!cctx) {
|
if (!cctx) {
|
||||||
cctx = ZSTD_createCCtx();
|
cctx = ZSTD_createCCtx();
|
||||||
|
@ -166,7 +165,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
||||||
ZSTD_decompressDCtx(dctx, rBuf, neededBufSize, cBuf, cSize);
|
ZSTD_decompressDCtx(dctx, rBuf, neededBufSize, cBuf, cSize);
|
||||||
FUZZ_ZASSERT(rSize);
|
FUZZ_ZASSERT(rSize);
|
||||||
FUZZ_ASSERT_MSG(rSize == size, "Incorrect regenerated size");
|
FUZZ_ASSERT_MSG(rSize == size, "Incorrect regenerated size");
|
||||||
FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!");
|
FUZZ_ASSERT_MSG(!FUZZ_memcmp(src, rBuf, size), "Corruption!");
|
||||||
}
|
}
|
||||||
|
|
||||||
FUZZ_dataProducer_free(producer);
|
FUZZ_dataProducer_free(producer);
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
||||||
{
|
{
|
||||||
ZSTD_frameHeader zfh;
|
ZSTD_frameHeader zfh;
|
||||||
|
if (size == 0) {
|
||||||
|
src = NULL;
|
||||||
|
}
|
||||||
/* You can fuzz any helper functions here that are fast, and take zstd
|
/* You can fuzz any helper functions here that are fast, and take zstd
|
||||||
* compressed data as input. E.g. don't expect the input to be a dictionary,
|
* compressed data as input. E.g. don't expect the input to be a dictionary,
|
||||||
* so don't fuzz ZSTD_getDictID_fromDict().
|
* so don't fuzz ZSTD_getDictID_fromDict().
|
||||||
|
|
|
@ -106,14 +106,13 @@ FUZZ_dict_t FUZZ_train(void const* src, size_t srcSize, FUZZ_dataProducer_t *pro
|
||||||
{
|
{
|
||||||
size_t const dictSize = MAX(srcSize / 8, 1024);
|
size_t const dictSize = MAX(srcSize / 8, 1024);
|
||||||
size_t const totalSampleSize = dictSize * 11;
|
size_t const totalSampleSize = dictSize * 11;
|
||||||
FUZZ_dict_t dict = { malloc(dictSize), dictSize };
|
FUZZ_dict_t dict = { FUZZ_malloc(dictSize), dictSize };
|
||||||
char* const samples = (char*)malloc(totalSampleSize);
|
char* const samples = (char*)FUZZ_malloc(totalSampleSize);
|
||||||
unsigned nbSamples = 100;
|
unsigned nbSamples = 100;
|
||||||
size_t* const samplesSizes = (size_t*)malloc(sizeof(size_t) * nbSamples);
|
size_t* const samplesSizes = (size_t*)FUZZ_malloc(sizeof(size_t) * nbSamples);
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
size_t sample = 0;
|
size_t sample = 0;
|
||||||
ZDICT_fastCover_params_t params;
|
ZDICT_fastCover_params_t params;
|
||||||
FUZZ_ASSERT(dict.buff && samples && samplesSizes);
|
|
||||||
|
|
||||||
for (sample = 0; sample < nbSamples; ++sample) {
|
for (sample = 0; sample < nbSamples; ++sample) {
|
||||||
size_t const remaining = totalSampleSize - pos;
|
size_t const remaining = totalSampleSize - pos;
|
||||||
|
@ -123,7 +122,6 @@ FUZZ_dict_t FUZZ_train(void const* src, size_t srcSize, FUZZ_dataProducer_t *pro
|
||||||
memcpy(samples + pos, src + offset, toCopy);
|
memcpy(samples + pos, src + offset, toCopy);
|
||||||
pos += toCopy;
|
pos += toCopy;
|
||||||
samplesSizes[sample] = toCopy;
|
samplesSizes[sample] = toCopy;
|
||||||
|
|
||||||
}
|
}
|
||||||
memset(samples + pos, 0, totalSampleSize - pos);
|
memset(samples + pos, 0, totalSampleSize - pos);
|
||||||
|
|
||||||
|
|
|
@ -538,6 +538,12 @@ static int basicUnitTests(U32 const seed, double compressibility)
|
||||||
if (ZSTD_getErrorCode(r) != ZSTD_error_srcSize_wrong) goto _output_error; }
|
if (ZSTD_getErrorCode(r) != ZSTD_error_srcSize_wrong) goto _output_error; }
|
||||||
DISPLAYLEVEL(3, "OK \n");
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
|
DISPLAYLEVEL(3, "test%3i : decompress into NULL buffer : ", testNb++);
|
||||||
|
{ size_t const r = ZSTD_decompress(NULL, 0, compressedBuffer, compressedBufferSize);
|
||||||
|
if (!ZSTD_isError(r)) goto _output_error;
|
||||||
|
if (ZSTD_getErrorCode(r) != ZSTD_error_dstSize_tooSmall) goto _output_error; }
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
DISPLAYLEVEL(3, "test%3i : ZSTD_decompressBound test with content size missing : ", testNb++);
|
DISPLAYLEVEL(3, "test%3i : ZSTD_decompressBound test with content size missing : ", testNb++);
|
||||||
{ /* create compressed buffer with content size missing */
|
{ /* create compressed buffer with content size missing */
|
||||||
ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
||||||
|
|
Loading…
Reference in New Issue