size_t const maxNbSeq = ZSTD_maxNbSeq(blockSize, cParams->minMatch, useExternalMatchFinder);
size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize)
+ ZSTD_cwksp_aligned_alloc_size(maxNbSeq * sizeof(seqDef))
- + 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE))
- + ZSTD_cwksp_alloc_size(sizeof(BYTE)); /* longOffsets */
+ + 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE));
size_t const entropySpace = ZSTD_cwksp_alloc_size(ENTROPY_WORKSPACE_SIZE);
size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t));
size_t const matchStateSize = ZSTD_sizeof_matchState(cParams, useRowMatchFinder, /* enableDedicatedDictSearch */ 0, /* forCCtx */ 1);
zc->seqStore.llCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE));
zc->seqStore.mlCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE));
zc->seqStore.ofCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE));
- zc->seqStore.longOffsets = ZSTD_cwksp_reserve_buffer(ws, sizeof(BYTE));
- zc->seqStore.longOffsets[0] = 0;
zc->seqStore.sequencesStart = (seqDef*)ZSTD_cwksp_reserve_aligned(ws, maxNbSeq * sizeof(seqDef));
FORWARD_IF_ERROR(ZSTD_reset_matchState(
/* See doc/zstd_compression_format.md for detailed format description */
-void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
+int ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
{
const seqDef* const sequences = seqStorePtr->sequencesStart;
BYTE* const llCodeTable = seqStorePtr->llCode;
BYTE* const ofCodeTable = seqStorePtr->ofCode;
BYTE* const mlCodeTable = seqStorePtr->mlCode;
- BYTE* const longOffsetsFlag = seqStorePtr->longOffsets;
U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
U32 u;
- BYTE longOffsets = 0;
+ int longOffsets = 0;
assert(nbSeq <= seqStorePtr->maxNbSeq);
for (u=0; u<nbSeq; u++) {
U32 const llv = sequences[u].litLength;
mlCodeTable[u] = (BYTE)ZSTD_MLcode(mlv);
longOffsets |= (ofCode >= STREAM_ACCUMULATOR_MIN);
}
- longOffsetsFlag[0] = longOffsets;
if (seqStorePtr->longLengthType==ZSTD_llt_literalLength)
llCodeTable[seqStorePtr->longLengthPos] = MaxLL;
if (seqStorePtr->longLengthType==ZSTD_llt_matchLength)
mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
+ return longOffsets;
}
/* ZSTD_useTargetCBlockSize():
U32 MLtype;
size_t size;
size_t lastCountSize; /* Accounts for bug in 1.3.4. More detail in ZSTD_entropyCompressSeqStore_internal() */
+ int longOffsets;
} ZSTD_symbolEncodingTypeStats_t;
/* ZSTD_buildSequencesStatistics():
stats.lastCountSize = 0;
/* convert length/distances into codes */
- ZSTD_seqToCodes(seqStorePtr);
+ stats.longOffsets = ZSTD_seqToCodes(seqStorePtr);
assert(op <= oend);
assert(nbSeq != 0); /* ZSTD_selectEncodingType() divides by nbSeq */
/* build CTable for Literal Lengths */
const BYTE* const ofCodeTable = seqStorePtr->ofCode;
const BYTE* const llCodeTable = seqStorePtr->llCode;
const BYTE* const mlCodeTable = seqStorePtr->mlCode;
- const BYTE* const longOffsetsFlag = seqStorePtr->longOffsets;
BYTE* const ostart = (BYTE*)dst;
BYTE* const oend = ostart + dstCapacity;
BYTE* op = ostart;
size_t lastCountSize;
+ int longOffsets = 0;
entropyWorkspace = count + (MaxSeq + 1);
entropyWkspSize -= (MaxSeq + 1) * sizeof(*count);
*seqHead = (BYTE)((stats.LLtype<<6) + (stats.Offtype<<4) + (stats.MLtype<<2));
lastCountSize = stats.lastCountSize;
op += stats.size;
+ longOffsets = stats.longOffsets;
}
- { const BYTE longOffsets = longOffsetsFlag[0];
- size_t const bitstreamSize = ZSTD_encodeSequences(
+ { size_t const bitstreamSize = ZSTD_encodeSequences(
op, (size_t)(oend - op),
CTable_MatchLength, mlCodeTable,
CTable_OffsetBits, ofCodeTable,
static ZSTD_symbolEncodingTypeStats_t
ZSTD_buildDummySequencesStatistics(ZSTD_fseCTables_t* nextEntropy)
{
- ZSTD_symbolEncodingTypeStats_t stats = {set_basic, set_basic, set_basic, 0, 0};
+ ZSTD_symbolEncodingTypeStats_t stats = {set_basic, set_basic, set_basic, 0, 0, 0};
nextEntropy->litlength_repeatMode = FSE_repeat_none;
nextEntropy->offcode_repeatMode = FSE_repeat_none;
nextEntropy->matchlength_repeatMode = FSE_repeat_none;
}
DISPLAYLEVEL(3, "OK \n");
+
+ DISPLAYLEVEL(3, "test%3i : Testing large offset with small window size: ", testNb++);
+ {
+ ZSTD_CCtx* cctx = ZSTD_createCCtx();
+ ZSTD_DCtx* dctx = ZSTD_createDCtx();
+
+ /* Test large offset, small window size*/
+ {
+ size_t srcSize = 21;
+ void* const src = CNBuffer;
+ size_t dstSize = ZSTD_compressBound(srcSize);
+ void* const dst = compressedBuffer;
+ size_t const kNbSequences = 4;
+ ZSTD_Sequence* sequences = malloc(sizeof(ZSTD_Sequence) * kNbSequences);
+ void* const checkBuf = malloc(srcSize);
+ const size_t largeDictSize = 1 << 30;
+ ZSTD_CDict* cdict = NULL;
+ ZSTD_DDict* ddict = NULL;
+
+ /* Generate large dictionary */
+ void* dictBuffer = calloc(largeDictSize, 1);
+ ZSTD_compressionParameters cParams = ZSTD_getCParams(1, srcSize, largeDictSize);
+ cParams.minMatch = ZSTD_MINMATCH_MIN;
+ cParams.hashLog = ZSTD_HASHLOG_MIN;
+ cParams.chainLog = ZSTD_CHAINLOG_MIN;
+
+ cdict = ZSTD_createCDict_advanced(dictBuffer, largeDictSize, ZSTD_dlm_byRef, ZSTD_dct_rawContent, cParams, ZSTD_defaultCMem);
+ ddict = ZSTD_createDDict_advanced(dictBuffer, largeDictSize, ZSTD_dlm_byRef, ZSTD_dct_rawContent, ZSTD_defaultCMem);
+
+ ZSTD_CCtx_refCDict(cctx, cdict);
+ ZSTD_DCtx_refDDict(dctx, ddict);
+
+ sequences[0] = (ZSTD_Sequence) {3, 3, 3, 0};
+ sequences[1] = (ZSTD_Sequence) {1 << 29, 0, 3, 0};
+ sequences[2] = (ZSTD_Sequence) {1 << 29, 0, 9, 0};
+ sequences[3] = (ZSTD_Sequence) {3, 0, 3, 0};
+
+ cSize = ZSTD_compressSequences(cctx, dst, dstSize,
+ sequences, kNbSequences,
+ src, srcSize);
+
+ CHECK(ZSTD_isError(cSize), "Should not throw an error");
+
+ {
+ size_t dSize = ZSTD_decompressDCtx(dctx, checkBuf, srcSize, dst, cSize);
+ CHECK(ZSTD_isError(dSize), "Should not throw an error");
+ CHECK(memcmp(src, checkBuf, srcSize) != 0, "Corruption!");
+ }
+
+ free(sequences);
+ free(checkBuf);
+ free(dictBuffer);
+ ZSTD_freeCDict(cdict);
+ ZSTD_freeDDict(ddict);
+ }
+ ZSTD_freeCCtx(cctx);
+ ZSTD_freeDCtx(dctx);
+ }
+ DISPLAYLEVEL(3, "OK \n");
+
_end:
FUZ_freeDictionary(dictionary);
ZSTD_freeCStream(zc);