if (mode == ZSTD_sf_explicitBlockDelimiters) {
/* ensure that no sequence can be larger than one block */
literalsSizeLimit = MIN(literalsSizeLimit, blockSizeMax/2);
- matchLengthMax = MIN(matchLengthMax, blockSizeMax/2);
+ matchLengthMax = MIN(matchLengthMax, (uint32_t)blockSizeMax/2);
}
while ( nbSeqGenerated < ZSTD_FUZZ_MAX_NBSEQ - 3 /* extra room for explicit delimiters */
if (bytesGenerated > ZSTD_FUZZ_GENERATED_SRC_MAXSIZE) {
break;
}
- offsetBound = (bytesGenerated > windowSize) ? windowSize : bytesGenerated + (uint32_t)dictSize;
+ offsetBound = (bytesGenerated > windowSize) ? (uint32_t)windowSize : bytesGenerated + (uint32_t)dictSize;
offset = FUZZ_dataProducer_uint32Range(producer, 1, offsetBound);
if (dictSize > 0 && bytesGenerated <= windowSize) {
/* Prevent match length from being such that it would be associated with an offset too large
*/
const size_t bytesToReachWindowSize = windowSize - bytesGenerated;
if (bytesToReachWindowSize < ZSTD_MINMATCH_MIN) {
- const uint32_t newOffsetBound = offsetBound > windowSize ? windowSize : offsetBound;
+ const uint32_t newOffsetBound = offsetBound > windowSize ? (uint32_t)windowSize : offsetBound;
offset = FUZZ_dataProducer_uint32Range(producer, 1, newOffsetBound);
} else {
matchBound = MIN(matchLengthMax, (uint32_t)bytesToReachWindowSize);
if (blockSize + seqSize > blockSizeMax) { /* reaching limit : must end block now */
const ZSTD_Sequence endBlock = {0, 0, 0, 0};
generatedSequences[nbSeqGenerated++] = endBlock;
- blockSize = seqSize;
+ blockSize = (uint32_t)seqSize;
}
if (split) {
const ZSTD_Sequence endBlock = {0, lastLits, 0, 0};
generatedSequences[nbSeqGenerated++] = endBlock;
assert(lastLits <= seq.litLength);
seq.litLength -= lastLits;
- blockSize = seqSize - lastLits;
+ blockSize = (uint32_t)(seqSize - lastLits);
} else {
blockSize += seqSize;
}
return nbSeqGenerated;
}
+static size_t
+transferLiterals(void* dst, size_t dstCapacity, const ZSTD_Sequence* seqs, size_t nbSeqs, const void* src, size_t srcSize)
+{
+ size_t n;
+ char* op = dst;
+ char* const oend = op + dstCapacity;
+ const char* ip = src;
+ const char* const iend = ip + srcSize;
+ for (n=0; n<nbSeqs; n++) {
+ size_t litLen = seqs[n].litLength;
+ size_t mlen = seqs[n].matchLength;
+ assert(op + litLen < oend);
+ assert(ip + litLen + mlen <= iend);
+ memcpy(op, ip, litLen);
+ op += litLen;
+ ip += litLen + mlen;
+ }
+ assert(oend - op >= 8);
+ return (size_t)(op - (char*)dst);
+}
+
+static size_t roundTripTest_compressSequencesAndLiterals(
+ void* result, size_t resultCapacity,
+ void* compressed, size_t compressedCapacity,
+ const void* src, size_t srcSize,
+ const ZSTD_Sequence* seqs, size_t nbSeqs,
+ ZSTD_SequenceFormat_e mode)
+{
+ size_t const litCapacity = srcSize + 8;
+ void* literals = malloc(litCapacity);
+ size_t cSize, litSize;
+
+ assert(literals);
+ litSize = transferLiterals(literals, litCapacity, seqs, nbSeqs, src, srcSize);
+
+ cSize = ZSTD_compressSequencesAndLiterals(cctx,
+ compressed, compressedCapacity,
+ seqs, nbSeqs,
+ literals, litSize, litCapacity, srcSize);
+ if ( (ZSTD_getErrorCode(cSize) == ZSTD_error_dstSize_tooSmall)
+ && (mode == ZSTD_sf_explicitBlockDelimiters) ) {
+ /* Valid scenario : in explicit delimiter mode,
+ * it might be possible for the compressed size to outgrow dstCapacity.
+ * In which case, it's still a valid fuzzer scenario,
+ * but no roundtrip shall be possible */
+ return 0;
+ }
+ /* round-trip */
+ FUZZ_ZASSERT(cSize);
+ { size_t const dSize = ZSTD_decompressDCtx(dctx, result, resultCapacity, compressed, cSize);
+ FUZZ_ZASSERT(dSize);
+ FUZZ_ASSERT_MSG(dSize == srcSize, "Incorrect regenerated size");
+ FUZZ_ASSERT_MSG(!FUZZ_memcmp(src, result, srcSize), "Corruption!");
+ return dSize;
+ }
+}
+
static size_t roundTripTest(void* result, size_t resultCapacity,
void* compressed, size_t compressedCapacity,
const void* src, size_t srcSize,
- const ZSTD_Sequence* seqs, size_t seqSize,
+ const ZSTD_Sequence* seqs, size_t nbSeqs,
unsigned hasDict,
ZSTD_SequenceFormat_e mode)
{
FUZZ_ZASSERT(ZSTD_DCtx_refDDict(dctx, ddict));
}
+ { int blockMode;
+ /* compressSequencesAndLiterals() only supports explicitBlockDelimiters */
+ FUZZ_ZASSERT(ZSTD_CCtx_getParameter(cctx, ZSTD_c_blockDelimiters, &blockMode));
+ if (blockMode == ZSTD_sf_explicitBlockDelimiters) {
+ FUZZ_ZASSERT(roundTripTest_compressSequencesAndLiterals(result, resultCapacity, compressed, compressedCapacity, src, srcSize, seqs, nbSeqs, mode));
+ }
+ }
+
cSize = ZSTD_compressSequences(cctx, compressed, compressedCapacity,
- seqs, seqSize,
+ seqs, nbSeqs,
src, srcSize);
if ( (ZSTD_getErrorCode(cSize) == ZSTD_error_dstSize_tooSmall)
&& (mode == ZSTD_sf_explicitBlockDelimiters) ) {
ZSTD_CCtx_reset(cctx, ZSTD_reset_session_and_parameters);
ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, 0);
ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, cLevel);
- ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, wLog);
+ ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, (int)wLog);
ZSTD_CCtx_setParameter(cctx, ZSTD_c_minMatch, ZSTD_MINMATCH_MIN);
ZSTD_CCtx_setParameter(cctx, ZSTD_c_validateSequences, 1);
- ZSTD_CCtx_setParameter(cctx, ZSTD_c_blockDelimiters, mode);
+ ZSTD_CCtx_setParameter(cctx, ZSTD_c_blockDelimiters, (int)mode);
ZSTD_CCtx_setParameter(cctx, ZSTD_c_forceAttachDict, ZSTD_dictForceAttach);
if (!literalsBuffer) {