aboutsummaryrefslogtreecommitdiff
path: root/tests/fuzzer.c
diff options
context:
space:
mode:
authorConrad Meyer <cem@FreeBSD.org>2019-11-06 06:42:00 +0000
committerConrad Meyer <cem@FreeBSD.org>2019-11-06 06:42:00 +0000
commitea68403922c3b53b00fc999fcb3eaef1feb50177 (patch)
tree9870b0c695852e26fb9f8e19df8d7f5cb6616141 /tests/fuzzer.c
parent90f4bdbe917eaf678feca2b0ff9647b5ae8bbb9d (diff)
Diffstat (limited to 'tests/fuzzer.c')
-rw-r--r--tests/fuzzer.c363
1 files changed, 290 insertions, 73 deletions
diff --git a/tests/fuzzer.c b/tests/fuzzer.c
index f42de9ed55c3..88f3b83f834c 100644
--- a/tests/fuzzer.c
+++ b/tests/fuzzer.c
@@ -123,9 +123,10 @@ static U32 FUZ_highbit32(U32 v32)
exit(1); \
} }
-#define CHECK_V(var, fn) size_t const var = fn; if (ZSTD_isError(var)) goto _output_error
-#define CHECK(fn) { CHECK_V(err, fn); }
-#define CHECKPLUS(var, fn, more) { CHECK_V(var, fn); more; }
+#define CHECK_VAR(var, fn) var = fn; if (ZSTD_isError(var)) { DISPLAYLEVEL(1, "%s : fails : %s \n", #fn, ZSTD_getErrorName(var)); goto _output_error; }
+#define CHECK_NEWV(var, fn) size_t const CHECK_VAR(var, fn)
+#define CHECK(fn) { CHECK_NEWV(err, fn); }
+#define CHECKPLUS(var, fn, more) { CHECK_NEWV(var, fn); more; }
#define CHECK_OP(op, lhs, rhs) { \
if (!((lhs) op (rhs))) { \
@@ -231,7 +232,7 @@ static int FUZ_mallocTests_internal(unsigned seed, double compressibility, unsig
/* advanced MT API test */
if (part <= 3)
- { unsigned nbThreads;
+ { int nbThreads;
for (nbThreads=1; nbThreads<=4; nbThreads++) {
int compressionLevel;
for (compressionLevel=1; compressionLevel<=6; compressionLevel++) {
@@ -242,7 +243,7 @@ static int FUZ_mallocTests_internal(unsigned seed, double compressibility, unsig
CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, nbThreads) );
CHECK_Z( ZSTD_compress2(cctx, outBuffer, outSize, inBuffer, inSize) );
ZSTD_freeCCtx(cctx);
- DISPLAYLEVEL(3, "compress_generic,-T%u,end level %i : ",
+ DISPLAYLEVEL(3, "compress_generic,-T%i,end level %i : ",
nbThreads, compressionLevel);
FUZ_displayMallocStats(malcount);
} } }
@@ -303,11 +304,33 @@ static int FUZ_mallocTests(unsigned seed, double compressibility, unsigned part)
#endif
+static void FUZ_decodeSequences(BYTE* dst, ZSTD_Sequence* seqs, size_t seqsSize, BYTE* src, size_t size)
+{
+ size_t i;
+ size_t j;
+ for(i = 0; i < seqsSize - 1; ++i) {
+ assert(dst + seqs[i].litLength + seqs[i].matchLength < dst + size);
+ assert(src + seqs[i].litLength + seqs[i].matchLength < src + size);
+
+ memcpy(dst, src, seqs[i].litLength);
+ dst += seqs[i].litLength;
+ src += seqs[i].litLength;
+ size -= seqs[i].litLength;
+
+ for (j = 0; j < seqs[i].matchLength; ++j)
+ dst[j] = dst[j - seqs[i].offset];
+ dst += seqs[i].matchLength;
+ src += seqs[i].matchLength;
+ size -= seqs[i].matchLength;
+ }
+ memcpy(dst, src, size);
+}
+
/*=============================================
* Unit tests
=============================================*/
-static int basicUnitTests(U32 seed, double compressibility)
+static int basicUnitTests(U32 const seed, double compressibility)
{
size_t const CNBuffSize = 5 MB;
void* const CNBuffer = malloc(CNBuffSize);
@@ -345,10 +368,9 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(3, "test%3u : compress %u bytes : ", testNb++, (unsigned)CNBuffSize);
{ ZSTD_CCtx* const cctx = ZSTD_createCCtx();
if (cctx==NULL) goto _output_error;
- CHECKPLUS(r, ZSTD_compressCCtx(cctx,
+ CHECK_VAR(cSize, ZSTD_compressCCtx(cctx,
compressedBuffer, compressedBufferSize,
- CNBuffer, CNBuffSize, 1),
- cSize=r );
+ CNBuffer, CNBuffSize, 1) );
DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (unsigned)cSize, (double)cSize/CNBuffSize*100);
DISPLAYLEVEL(3, "test%3i : size of cctx for level 1 : ", testNb++);
@@ -401,7 +423,7 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(3, "test%3i : check decompressed result : ", testNb++);
{ size_t u;
for (u=0; u<CNBuffSize; u++) {
- if (((BYTE*)decodedBuffer)[u] != ((BYTE*)CNBuffer)[u]) goto _output_error;;
+ if (((BYTE*)decodedBuffer)[u] != ((BYTE*)CNBuffer)[u]) goto _output_error;
} }
DISPLAYLEVEL(3, "OK \n");
@@ -450,12 +472,11 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(3, "test%3i : ZSTD_decompressBound test with content size missing : ", testNb++);
{ /* create compressed buffer with content size missing */
- ZSTD_CCtx* cctx = ZSTD_createCCtx();
+ ZSTD_CCtx* const cctx = ZSTD_createCCtx();
CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_contentSizeFlag, 0) );
- CHECKPLUS(r, ZSTD_compress2(cctx,
+ CHECK_VAR(cSize, ZSTD_compress2(cctx,
compressedBuffer, compressedBufferSize,
- CNBuffer, CNBuffSize),
- cSize=r );
+ CNBuffer, CNBuffSize) );
ZSTD_freeCCtx(cctx);
}
{ /* ensure frame content size is missing */
@@ -742,10 +763,9 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : simple compression test with static CCtx : ", testNb++);
- CHECKPLUS(r, ZSTD_compressCCtx(staticCCtx,
- compressedBuffer, compressedBufferSize,
- CNBuffer, CNBuffSize, STATIC_CCTX_LEVEL),
- cSize=r );
+ CHECK_VAR(cSize, ZSTD_compressCCtx(staticCCtx,
+ compressedBuffer, compressedBufferSize,
+ CNBuffer, CNBuffSize, STATIC_CCTX_LEVEL) );
DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n",
(unsigned)cSize, (double)cSize/CNBuffSize*100);
@@ -760,7 +780,7 @@ static int basicUnitTests(U32 seed, double compressibility)
{ size_t u;
for (u=0; u<CNBuffSize; u++) {
if (((BYTE*)decodedBuffer)[u] != ((BYTE*)CNBuffer)[u])
- goto _output_error;;
+ goto _output_error;
} }
DISPLAYLEVEL(3, "OK \n");
@@ -777,7 +797,7 @@ static int basicUnitTests(U32 seed, double compressibility)
CHECK( ZSTD_initCStream(staticCCtx, 1) );
DISPLAYLEVEL(3, "OK \n");
- DISPLAYLEVEL(3, "test%3i : init CStream with dictionary (should fail) : ", testNb++);
+ DISPLAYLEVEL(3, "test%3i : init static CStream with dictionary (should fail) : ", testNb++);
{ size_t const r = ZSTD_initCStream_usingDict(staticCCtx, CNBuffer, 64 KB, 1);
if (!ZSTD_isError(r)) goto _output_error; }
DISPLAYLEVEL(3, "OK \n");
@@ -810,20 +830,19 @@ static int basicUnitTests(U32 seed, double compressibility)
/* ZSTDMT simple MT compression test */
DISPLAYLEVEL(3, "test%3i : create ZSTDMT CCtx : ", testNb++);
- { ZSTDMT_CCtx* mtctx = ZSTDMT_createCCtx(2);
+ { ZSTDMT_CCtx* const mtctx = ZSTDMT_createCCtx(2);
if (mtctx==NULL) {
- DISPLAY("mtctx : mot enough memory, aborting \n");
+ DISPLAY("mtctx : not enough memory, aborting \n");
testResult = 1;
goto _end;
}
DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3u : compress %u bytes with 2 threads : ", testNb++, (unsigned)CNBuffSize);
- CHECKPLUS(r, ZSTDMT_compressCCtx(mtctx,
+ CHECK_VAR(cSize, ZSTDMT_compressCCtx(mtctx,
compressedBuffer, compressedBufferSize,
CNBuffer, CNBuffSize,
- 1),
- cSize=r );
+ 1) );
DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (unsigned)cSize, (double)cSize/CNBuffSize*100);
DISPLAYLEVEL(3, "test%3i : decompressed size test : ", testNb++);
@@ -842,7 +861,7 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(3, "test%3i : check decompressed result : ", testNb++);
{ size_t u;
for (u=0; u<CNBuffSize; u++) {
- if (((BYTE*)decodedBuffer)[u] != ((BYTE*)CNBuffer)[u]) goto _output_error;;
+ if (((BYTE*)decodedBuffer)[u] != ((BYTE*)CNBuffer)[u]) goto _output_error;
} }
DISPLAYLEVEL(3, "OK \n");
@@ -850,11 +869,10 @@ static int basicUnitTests(U32 seed, double compressibility)
{ ZSTD_parameters params = ZSTD_getParams(1, CNBuffSize, 0);
params.fParams.checksumFlag = 1;
params.fParams.contentSizeFlag = 1;
- CHECKPLUS(r, ZSTDMT_compress_advanced(mtctx,
+ CHECK_VAR(cSize, ZSTDMT_compress_advanced(mtctx,
compressedBuffer, compressedBufferSize,
CNBuffer, CNBuffSize,
- NULL, params, 3 /*overlapRLog*/),
- cSize=r );
+ NULL, params, 3 /*overlapRLog*/) );
}
DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (unsigned)cSize, (double)cSize/CNBuffSize*100);
@@ -928,10 +946,10 @@ static int basicUnitTests(U32 seed, double compressibility)
/* only use the first half so we don't push against size limit of compressedBuffer */
size_t const segSize = (CNBuffSize / 2) / segs;
for (i = 0; i < segs; i++) {
- CHECK_V(r, ZSTD_compress(
- (BYTE *)compressedBuffer + off, CNBuffSize - off,
- (BYTE *)CNBuffer + segSize * i,
- segSize, 5));
+ CHECK_NEWV(r, ZSTD_compress(
+ (BYTE*)compressedBuffer + off, CNBuffSize - off,
+ (BYTE*)CNBuffer + segSize * (size_t)i, segSize,
+ 5) );
off += r;
if (i == segs/2) {
/* insert skippable frame */
@@ -956,7 +974,7 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : decompress multiple frames : ", testNb++);
- { CHECK_V(r, ZSTD_decompress(decodedBuffer, CNBuffSize, compressedBuffer, cSize));
+ { CHECK_NEWV(r, ZSTD_decompress(decodedBuffer, CNBuffSize, compressedBuffer, cSize));
if (r != CNBuffSize / 2) goto _output_error; }
DISPLAYLEVEL(3, "OK \n");
@@ -983,8 +1001,9 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(3, "test%3i : compress with flat dictionary : ", testNb++);
cSize = 0;
- CHECKPLUS(r, ZSTD_compressEnd(ctxOrig, compressedBuffer, compressedBufferSize,
- (const char*)CNBuffer + dictSize, CNBuffSize - dictSize),
+ CHECKPLUS(r, ZSTD_compressEnd(ctxOrig,
+ compressedBuffer, compressedBufferSize,
+ (const char*)CNBuffer + dictSize, CNBuffSize - dictSize),
cSize += r);
DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (unsigned)cSize, (double)cSize/CNBuffSize*100);
@@ -999,8 +1018,9 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(3, "test%3i : compress with duplicated context : ", testNb++);
{ size_t const cSizeOrig = cSize;
cSize = 0;
- CHECKPLUS(r, ZSTD_compressEnd(ctxDuplicated, compressedBuffer, compressedBufferSize,
- (const char*)CNBuffer + dictSize, CNBuffSize - dictSize),
+ CHECKPLUS(r, ZSTD_compressEnd(ctxDuplicated,
+ compressedBuffer, compressedBufferSize,
+ (const char*)CNBuffer + dictSize, CNBuffSize - dictSize),
cSize += r);
if (cSize != cSizeOrig) goto _output_error; /* should be identical ==> same size */
}
@@ -1024,7 +1044,7 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(3, "test%3i : decompress with static DDict : ", testNb++);
{ size_t const ddictBufferSize = ZSTD_estimateDDictSize(dictSize, ZSTD_dlm_byCopy);
- void* ddictBuffer = malloc(ddictBufferSize);
+ void* const ddictBuffer = malloc(ddictBufferSize);
if (ddictBuffer == NULL) goto _output_error;
{ const ZSTD_DDict* const ddict = ZSTD_initStaticDDict(ddictBuffer, ddictBufferSize, CNBuffer, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto);
size_t const r = ZSTD_decompress_usingDDict(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize, ddict);
@@ -1042,15 +1062,66 @@ static int basicUnitTests(U32 seed, double compressibility)
}
CHECK( ZSTD_copyCCtx(ctxDuplicated, ctxOrig, testSize) );
- CHECKPLUS(r, ZSTD_compressEnd(ctxDuplicated, compressedBuffer, ZSTD_compressBound(testSize),
- (const char*)CNBuffer + dictSize, testSize),
- cSize = r);
+ CHECK_VAR(cSize, ZSTD_compressEnd(ctxDuplicated, compressedBuffer, ZSTD_compressBound(testSize),
+ (const char*)CNBuffer + dictSize, testSize) );
{ ZSTD_frameHeader zfh;
if (ZSTD_getFrameHeader(&zfh, compressedBuffer, cSize)) goto _output_error;
if ((zfh.frameContentSize != testSize) && (zfh.frameContentSize != 0)) goto _output_error;
} }
DISPLAYLEVEL(3, "OK \n");
+ if ((int)(compressibility * 100 + 0.1) == FUZ_compressibility_default) { /* test only valid with known input */
+ size_t const flatdictSize = 22 KB;
+ size_t const contentSize = 9 KB;
+ const void* const dict = (const char*)CNBuffer;
+ const void* const contentStart = (const char*)dict + flatdictSize;
+ size_t const target_nodict_cSize[22+1] = { 3840, 3770, 3870, 3830, 3770,
+ 3770, 3770, 3770, 3750, 3750,
+ 3740, 3670, 3670, 3660, 3660,
+ 3660, 3660, 3660, 3660, 3660,
+ 3660, 3660, 3660 };
+ size_t const target_wdict_cSize[22+1] = { 2830, 2890, 2890, 2820, 2940,
+ 2950, 2950, 2920, 2900, 2890,
+ 2910, 2910, 2910, 2770, 2760,
+ 2750, 2750, 2750, 2750, 2750,
+ 2750, 2750, 2750 };
+ int l = 1;
+ int const maxLevel = ZSTD_maxCLevel();
+
+ DISPLAYLEVEL(3, "test%3i : flat-dictionary efficiency test : \n", testNb++);
+ assert(maxLevel == 22);
+ RDG_genBuffer(CNBuffer, flatdictSize + contentSize, compressibility, 0., seed);
+ DISPLAYLEVEL(4, "content hash : %016llx; dict hash : %016llx \n", XXH64(contentStart, contentSize, 0), XXH64(dict, flatdictSize, 0));
+
+ for ( ; l <= maxLevel; l++) {
+ size_t const nodict_cSize = ZSTD_compress(compressedBuffer, compressedBufferSize,
+ contentStart, contentSize, l);
+ if (nodict_cSize > target_nodict_cSize[l]) {
+ DISPLAYLEVEL(1, "error : compression at level %i worse than expected (%u > %u) \n",
+ l, (unsigned)nodict_cSize, (unsigned)target_nodict_cSize[l]);
+ goto _output_error;
+ }
+ DISPLAYLEVEL(4, "level %i : max expected %u >= reached %u \n",
+ l, (unsigned)target_nodict_cSize[l], (unsigned)nodict_cSize);
+ }
+ for ( l=1 ; l <= maxLevel; l++) {
+ size_t const wdict_cSize = ZSTD_compress_usingDict(ctxOrig,
+ compressedBuffer, compressedBufferSize,
+ contentStart, contentSize,
+ dict, flatdictSize,
+ l);
+ if (wdict_cSize > target_wdict_cSize[l]) {
+ DISPLAYLEVEL(1, "error : compression with dictionary at level %i worse than expected (%u > %u) \n",
+ l, (unsigned)wdict_cSize, (unsigned)target_wdict_cSize[l]);
+ goto _output_error;
+ }
+ DISPLAYLEVEL(4, "level %i with dictionary : max expected %u >= reached %u \n",
+ l, (unsigned)target_wdict_cSize[l], (unsigned)wdict_cSize);
+ }
+
+ DISPLAYLEVEL(4, "compression efficiency tests OK \n");
+ }
+
ZSTD_freeCCtx(ctxOrig);
ZSTD_freeCCtx(ctxDuplicated);
ZSTD_freeDCtx(dctx);
@@ -1316,7 +1387,7 @@ static int basicUnitTests(U32 seed, double compressibility)
}
DISPLAYLEVEL(3, "OK \n");
- DISPLAYLEVEL(3, "test%3i : Building cdict w/ ZSTD_dm_fullDict on a good dictionary : ", testNb++);
+ DISPLAYLEVEL(3, "test%3i : Building cdict w/ ZSTD_dct_fullDict on a good dictionary : ", testNb++);
{ ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize);
ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, ZSTD_dct_fullDict, cParams, ZSTD_defaultCMem);
if (cdict==NULL) goto _output_error;
@@ -1324,7 +1395,7 @@ static int basicUnitTests(U32 seed, double compressibility)
}
DISPLAYLEVEL(3, "OK \n");
- DISPLAYLEVEL(3, "test%3i : Building cdict w/ ZSTD_dm_fullDict on a rawContent (must fail) : ", testNb++);
+ DISPLAYLEVEL(3, "test%3i : Building cdict w/ ZSTD_dct_fullDict on a rawContent (must fail) : ", testNb++);
{ ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize);
ZSTD_CDict* const cdict = ZSTD_createCDict_advanced((const char*)dictBuffer+1, dictSize-1, ZSTD_dlm_byRef, ZSTD_dct_fullDict, cParams, ZSTD_defaultCMem);
if (cdict!=NULL) goto _output_error;
@@ -1332,7 +1403,7 @@ static int basicUnitTests(U32 seed, double compressibility)
}
DISPLAYLEVEL(3, "OK \n");
- DISPLAYLEVEL(3, "test%3i : Loading rawContent starting with dict header w/ ZSTD_dm_auto should fail : ", testNb++);
+ DISPLAYLEVEL(3, "test%3i : Loading rawContent starting with dict header w/ ZSTD_dct_auto should fail : ", testNb++);
{
size_t ret;
MEM_writeLE32((char*)dictBuffer+2, ZSTD_MAGIC_DICTIONARY);
@@ -1346,7 +1417,7 @@ static int basicUnitTests(U32 seed, double compressibility)
}
DISPLAYLEVEL(3, "OK \n");
- DISPLAYLEVEL(3, "test%3i : Loading rawContent starting with dict header w/ ZSTD_dm_rawContent should pass : ", testNb++);
+ DISPLAYLEVEL(3, "test%3i : Loading rawContent starting with dict header w/ ZSTD_dct_rawContent should pass : ", testNb++);
{
size_t ret;
MEM_writeLE32((char*)dictBuffer+2, ZSTD_MAGIC_DICTIONARY);
@@ -1598,6 +1669,7 @@ static int basicUnitTests(U32 seed, double compressibility)
size_t const sampleUnitSize = 8 KB;
U32 const nbSamples = (U32)(totalSampleSize / sampleUnitSize);
size_t* const samplesSizes = (size_t*) malloc(nbSamples * sizeof(size_t));
+ U32 seed32 = seed;
ZDICT_cover_params_t params;
U32 dictID;
@@ -1610,8 +1682,8 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(3, "test%3i : ZDICT_trainFromBuffer_cover : ", testNb++);
{ U32 u; for (u=0; u<nbSamples; u++) samplesSizes[u] = sampleUnitSize; }
memset(&params, 0, sizeof(params));
- params.d = 1 + (FUZ_rand(&seed) % 16);
- params.k = params.d + (FUZ_rand(&seed) % 256);
+ params.d = 1 + (FUZ_rand(&seed32) % 16);
+ params.k = params.d + (FUZ_rand(&seed32) % 256);
dictSize = ZDICT_trainFromBuffer_cover(dictBuffer, dictSize,
CNBuffer, samplesSizes, nbSamples,
params);
@@ -1814,6 +1886,36 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(3, "streaming OK : regenerated %u bytes \n", (unsigned)out.pos);
}
+ /* basic block compression */
+ DISPLAYLEVEL(3, "test%3i : empty magic-less format test : ", testNb++);
+ CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_format, ZSTD_f_zstd1_magicless) );
+ { ZSTD_inBuffer in = { CNBuffer, 0, 0 };
+ ZSTD_outBuffer out = { compressedBuffer, ZSTD_compressBound(0), 0 };
+ size_t const result = ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_end);
+ if (result != 0) goto _output_error;
+ if (in.pos != in.size) goto _output_error;
+ cSize = out.pos;
+ }
+ DISPLAYLEVEL(3, "OK (compress : %u -> %u bytes)\n", (unsigned)0, (unsigned)cSize);
+
+ DISPLAYLEVEL(3, "test%3i : decompress of empty magic-less frame : ", testNb++);
+ ZSTD_DCtx_reset(dctx, ZSTD_reset_session_and_parameters);
+ CHECK( ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, ZSTD_f_zstd1_magicless) );
+ /* one shot */
+ { size_t const result = ZSTD_decompressDCtx(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize);
+ if (result != 0) goto _output_error;
+ DISPLAYLEVEL(3, "one-shot OK, ");
+ }
+ /* streaming */
+ { ZSTD_inBuffer in = { compressedBuffer, cSize, 0 };
+ ZSTD_outBuffer out = { decodedBuffer, CNBuffSize, 0 };
+ size_t const result = ZSTD_decompressStream(dctx, &out, &in);
+ if (result != 0) goto _output_error;
+ if (in.pos != in.size) goto _output_error;
+ if (out.pos != 0) goto _output_error;
+ DISPLAYLEVEL(3, "streaming OK : regenerated %u bytes \n", (unsigned)out.pos);
+ }
+
ZSTD_freeCCtx(cctx);
ZSTD_freeDCtx(dctx);
}
@@ -1830,13 +1932,12 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(3, "test%3i : Block compression test : ", testNb++);
CHECK( ZSTD_compressBegin(cctx, 5) );
CHECK( ZSTD_getBlockSize(cctx) >= blockSize);
- cSize = ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), CNBuffer, blockSize);
- if (ZSTD_isError(cSize)) goto _output_error;
+ CHECK_VAR(cSize, ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), CNBuffer, blockSize) );
DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : Block decompression test : ", testNb++);
CHECK( ZSTD_decompressBegin(dctx) );
- { CHECK_V(r, ZSTD_decompressBlock(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize) );
+ { CHECK_NEWV(r, ZSTD_decompressBlock(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize) );
if (r != blockSize) goto _output_error; }
DISPLAYLEVEL(3, "OK \n");
@@ -1851,30 +1952,36 @@ static int basicUnitTests(U32 seed, double compressibility)
assert(blockCSize != 0);
if (ZSTD_isError(blockCSize)) goto _output_error;
compressed += blockCSize;
- }
- }
+ } }
DISPLAYLEVEL(3, "OK \n");
/* dictionary block compression */
DISPLAYLEVEL(3, "test%3i : Dictionary Block compression test : ", testNb++);
CHECK( ZSTD_compressBegin_usingDict(cctx, CNBuffer, dictSize, 5) );
- cSize = ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), (char*)CNBuffer+dictSize, blockSize);
- if (ZSTD_isError(cSize)) goto _output_error;
- cSize2 = ZSTD_compressBlock(cctx, (char*)compressedBuffer+cSize, ZSTD_compressBound(blockSize), (char*)CNBuffer+dictSize+blockSize, blockSize);
- if (ZSTD_isError(cSize2)) goto _output_error;
- memcpy((char*)compressedBuffer+cSize, (char*)CNBuffer+dictSize+blockSize, blockSize); /* fake non-compressed block */
- cSize2 = ZSTD_compressBlock(cctx, (char*)compressedBuffer+cSize+blockSize, ZSTD_compressBound(blockSize),
- (char*)CNBuffer+dictSize+2*blockSize, blockSize);
- if (ZSTD_isError(cSize2)) goto _output_error;
+ CHECK_VAR(cSize, ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), (char*)CNBuffer+dictSize, blockSize));
+ RDG_genBuffer((char*)CNBuffer+dictSize+blockSize, blockSize, 0.0, 0.0, seed); /* create a non-compressible second block */
+ { CHECK_NEWV(r, ZSTD_compressBlock(cctx, (char*)compressedBuffer+cSize, ZSTD_compressBound(blockSize), (char*)CNBuffer+dictSize+blockSize, blockSize) ); /* for cctx history consistency */
+ assert(r == 0); /* non-compressible block */ }
+ memcpy((char*)compressedBuffer+cSize, (char*)CNBuffer+dictSize+blockSize, blockSize); /* send non-compressed block (without header) */
+ CHECK_VAR(cSize2, ZSTD_compressBlock(cctx, (char*)compressedBuffer+cSize+blockSize, ZSTD_compressBound(blockSize),
+ (char*)CNBuffer+dictSize+2*blockSize, blockSize));
DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : Dictionary Block decompression test : ", testNb++);
CHECK( ZSTD_decompressBegin_usingDict(dctx, CNBuffer, dictSize) );
- { CHECK_V( r, ZSTD_decompressBlock(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize) );
- if (r != blockSize) goto _output_error; }
+ { CHECK_NEWV( r, ZSTD_decompressBlock(dctx, decodedBuffer, blockSize, compressedBuffer, cSize) );
+ if (r != blockSize) {
+ DISPLAYLEVEL(1, "ZSTD_decompressBlock() with _usingDict() fails : %u, instead of %u expected \n", (unsigned)r, (unsigned)blockSize);
+ goto _output_error;
+ } }
+ memcpy((char*)decodedBuffer+blockSize, (char*)compressedBuffer+cSize, blockSize);
ZSTD_insertBlock(dctx, (char*)decodedBuffer+blockSize, blockSize); /* insert non-compressed block into dctx history */
- { CHECK_V( r, ZSTD_decompressBlock(dctx, (char*)decodedBuffer+2*blockSize, CNBuffSize, (char*)compressedBuffer+cSize+blockSize, cSize2) );
- if (r != blockSize) goto _output_error; }
+ { CHECK_NEWV( r, ZSTD_decompressBlock(dctx, (char*)decodedBuffer+2*blockSize, blockSize, (char*)compressedBuffer+cSize+blockSize, cSize2) );
+ if (r != blockSize) {
+ DISPLAYLEVEL(1, "ZSTD_decompressBlock() with _usingDict() and after insertBlock() fails : %u, instead of %u expected \n", (unsigned)r, (unsigned)blockSize);
+ goto _output_error;
+ } }
+ assert(memcpy((char*)CNBuffer+dictSize, decodedBuffer, blockSize*3)); /* ensure regenerated content is identical to origin */
DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : Block compression with CDict : ", testNb++);
@@ -1900,21 +2007,59 @@ static int basicUnitTests(U32 seed, double compressibility)
sampleSize += 96 KB;
cSize = ZSTD_compress(compressedBuffer, ZSTD_compressBound(sampleSize), CNBuffer, sampleSize, 1);
if (ZSTD_isError(cSize)) goto _output_error;
- { CHECK_V(regenSize, ZSTD_decompress(decodedBuffer, sampleSize, compressedBuffer, cSize));
+ { CHECK_NEWV(regenSize, ZSTD_decompress(decodedBuffer, sampleSize, compressedBuffer, cSize));
if (regenSize!=sampleSize) goto _output_error; }
DISPLAYLEVEL(3, "OK \n");
}
+ DISPLAYLEVEL(3, "test%3i : ZSTD_getSequences decode from sequences test : ", testNb++);
+ {
+ size_t srcSize = 100 KB;
+ BYTE* src = (BYTE*)CNBuffer;
+ BYTE* decoded = (BYTE*)compressedBuffer;
+
+ ZSTD_CCtx* cctx = ZSTD_createCCtx();
+ ZSTD_Sequence* seqs = (ZSTD_Sequence*)malloc(srcSize * sizeof(ZSTD_Sequence));
+ size_t seqsSize;
+
+ if (seqs == NULL) goto _output_error;
+ assert(cctx != NULL);
+
+ /* Populate src with random data */
+ RDG_genBuffer(CNBuffer, srcSize, compressibility, 0., seed);
+
+ /* get the sequences */
+ seqsSize = ZSTD_getSequences(cctx, seqs, srcSize, src, srcSize);
+
+ /* "decode" and compare the sequences */
+ FUZ_decodeSequences(decoded, seqs, seqsSize, src, srcSize);
+ assert(!memcmp(CNBuffer, compressedBuffer, srcSize));
+
+ ZSTD_freeCCtx(cctx);
+ free(seqs);
+ }
+
+ /* Multiple blocks of zeros test */
+ #define LONGZEROSLENGTH 1000000 /* 1MB of zeros */
+ DISPLAYLEVEL(3, "test%3i : compress %u zeroes : ", testNb++, LONGZEROSLENGTH);
+ memset(CNBuffer, 0, LONGZEROSLENGTH);
+ CHECK_VAR(cSize, ZSTD_compress(compressedBuffer, ZSTD_compressBound(LONGZEROSLENGTH), CNBuffer, LONGZEROSLENGTH, 1) );
+ DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (unsigned)cSize, (double)cSize/LONGZEROSLENGTH*100);
+
+ DISPLAYLEVEL(3, "test%3i : decompress %u zeroes : ", testNb++, LONGZEROSLENGTH);
+ { CHECK_NEWV(r, ZSTD_decompress(decodedBuffer, LONGZEROSLENGTH, compressedBuffer, cSize) );
+ if (r != LONGZEROSLENGTH) goto _output_error; }
+ DISPLAYLEVEL(3, "OK \n");
+
/* All zeroes test (test bug #137) */
#define ZEROESLENGTH 100
DISPLAYLEVEL(3, "test%3i : compress %u zeroes : ", testNb++, ZEROESLENGTH);
memset(CNBuffer, 0, ZEROESLENGTH);
- { CHECK_V(r, ZSTD_compress(compressedBuffer, ZSTD_compressBound(ZEROESLENGTH), CNBuffer, ZEROESLENGTH, 1) );
- cSize = r; }
+ CHECK_VAR(cSize, ZSTD_compress(compressedBuffer, ZSTD_compressBound(ZEROESLENGTH), CNBuffer, ZEROESLENGTH, 1) );
DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (unsigned)cSize, (double)cSize/ZEROESLENGTH*100);
DISPLAYLEVEL(3, "test%3i : decompress %u zeroes : ", testNb++, ZEROESLENGTH);
- { CHECK_V(r, ZSTD_decompress(decodedBuffer, ZEROESLENGTH, compressedBuffer, cSize) );
+ { CHECK_NEWV(r, ZSTD_decompress(decodedBuffer, ZEROESLENGTH, compressedBuffer, cSize) );
if (r != ZEROESLENGTH) goto _output_error; }
DISPLAYLEVEL(3, "OK \n");
@@ -1962,13 +2107,12 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : compress lots 3-bytes sequences : ", testNb++);
- { CHECK_V(r, ZSTD_compress(compressedBuffer, ZSTD_compressBound(_3BYTESTESTLENGTH),
- CNBuffer, _3BYTESTESTLENGTH, 19) );
- cSize = r; }
+ CHECK_VAR(cSize, ZSTD_compress(compressedBuffer, ZSTD_compressBound(_3BYTESTESTLENGTH),
+ CNBuffer, _3BYTESTESTLENGTH, 19) );
DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (unsigned)cSize, (double)cSize/_3BYTESTESTLENGTH*100);
DISPLAYLEVEL(3, "test%3i : decompress lots 3-bytes sequence : ", testNb++);
- { CHECK_V(r, ZSTD_decompress(decodedBuffer, _3BYTESTESTLENGTH, compressedBuffer, cSize) );
+ { CHECK_NEWV(r, ZSTD_decompress(decodedBuffer, _3BYTESTESTLENGTH, compressedBuffer, cSize) );
if (r != _3BYTESTESTLENGTH) goto _output_error; }
DISPLAYLEVEL(3, "OK \n");
@@ -2084,6 +2228,79 @@ static int basicUnitTests(U32 seed, double compressibility)
}
DISPLAYLEVEL(3, "OK \n");
+ DISPLAYLEVEL(3, "test%3i : table cleanliness through index reduction : ", testNb++);
+ {
+ int cLevel;
+ size_t approxIndex = 0;
+ size_t maxIndex = ((3U << 29) + (1U << ZSTD_WINDOWLOG_MAX)); /* ZSTD_CURRENT_MAX from zstd_compress_internal.h */
+
+ /* Provision enough space in a static context so that we can do all
+ * this without ever reallocating, which would reset the indices. */
+ size_t const staticCCtxSize = ZSTD_estimateCStreamSize(22);
+ void* const staticCCtxBuffer = malloc(staticCCtxSize);
+ ZSTD_CCtx* cctx = ZSTD_initStaticCCtx(staticCCtxBuffer, staticCCtxSize);
+
+ /* bump the indices so the following compressions happen at high
+ * indices. */
+ {
+ ZSTD_outBuffer out = { compressedBuffer, compressedBufferSize, 0 };
+ ZSTD_inBuffer in = { CNBuffer, CNBuffSize, 0 };
+ ZSTD_CCtx_reset(cctx, ZSTD_reset_session_and_parameters);
+ CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, -500));
+ while (approxIndex <= (maxIndex / 4) * 3) {
+ CHECK_Z(ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_flush));
+ approxIndex += in.pos;
+ CHECK(in.pos == in.size);
+ in.pos = 0;
+ out.pos = 0;
+ }
+ CHECK_Z(ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_end));
+ }
+
+ /* spew a bunch of stuff into the table area */
+ for (cLevel = 1; cLevel <= 22; cLevel++) {
+ ZSTD_outBuffer out = { compressedBuffer, compressedBufferSize / cLevel, 0 };
+ ZSTD_inBuffer in = { CNBuffer, CNBuffSize, 0 };
+ ZSTD_CCtx_reset(cctx, ZSTD_reset_session_and_parameters);
+ CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, cLevel));
+ CHECK_Z(ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_flush));
+ CHECK_Z(ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_end));
+ approxIndex += in.pos;
+ }
+
+ /* now crank the indices so we overflow */
+ {
+ ZSTD_outBuffer out = { compressedBuffer, compressedBufferSize, 0 };
+ ZSTD_inBuffer in = { CNBuffer, CNBuffSize, 0 };
+ ZSTD_CCtx_reset(cctx, ZSTD_reset_session_and_parameters);
+ CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, -500));
+ while (approxIndex <= maxIndex) {
+ CHECK_Z(ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_flush));
+ approxIndex += in.pos;
+ CHECK(in.pos == in.size);
+ in.pos = 0;
+ out.pos = 0;
+ }
+ CHECK_Z(ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_end));
+ }
+
+ /* do a bunch of compressions again in low indices and ensure we don't
+ * hit untracked invalid indices */
+ for (cLevel = 1; cLevel <= 22; cLevel++) {
+ ZSTD_outBuffer out = { compressedBuffer, compressedBufferSize / cLevel, 0 };
+ ZSTD_inBuffer in = { CNBuffer, CNBuffSize, 0 };
+ ZSTD_CCtx_reset(cctx, ZSTD_reset_session_and_parameters);
+ CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, cLevel));
+ CHECK_Z(ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_flush));
+ CHECK_Z(ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_end));
+ approxIndex += in.pos;
+ }
+
+ ZSTD_freeCCtx(cctx);
+ free(staticCCtxBuffer);
+ }
+ DISPLAYLEVEL(3, "OK \n");
+
_end:
free(CNBuffer);
free(compressedBuffer);