diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 4e2fbd85..7facbeff 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2272,37 +2272,46 @@ static void ZSTD_copyBlockSequences(ZSTD_CCtx* zc) size_t seqsSize = seqStore->sequences - seqs; ZSTD_Sequence* outSeqs = &zc->seqCollector.seqStart[zc->seqCollector.seqIndex]; - int i; + size_t i; size_t position; int repIdx; assert(zc->seqCollector.seqIndex + 1 < zc->seqCollector.maxSequences); - for (i = 0; i < (int)seqsSize; ++i) { - unsigned int offsetValue = seqs[i].offset; + for (i = 0, position = 0; i < seqsSize; ++i) { + outSeqs[i].offset = seqs[i].offset; outSeqs[i].litLength = seqs[i].litLength; - outSeqs[i].matchLength = seqs[i].matchLength; - if (offsetValue > 3) { - outSeqs[i].offset = offsetValue - 3; - } else { - /* special repeat offset case */ - unsigned int repeatOffset1 = i - 1 >= 0 ? outSeqs[i - 1].offset : 1; - unsigned int repeatOffset2 = 1 - 2 >= 0 ? outSeqs[i - 2].offset : 4; - unsigned int repeatOffset3 = i - 3 >= 0 ? outSeqs[i - 3].offset : 8; - if (seqs[i].litLength != 0) { - switch (offsetValue) { - case 1: outSeqs[i].offset = repeatOffset1; break; - case 2: outSeqs[i].offset = repeatOffset2; break; - case 3: outSeqs[i].offset = repeatOffset3; break; - } - } else { - /* offsets shifted by one */ - switch (offsetValue) { - case 1: outSeqs[i].offset = repeatOffset2; break; - case 2: outSeqs[i].offset = repeatOffset3; break; - /* corner case where offsetValue == 3 */ - case 3: outSeqs[i].offset = repeatOffset1 - 1; break; - } + outSeqs[i].matchLength = seqs[i].matchLength + MINMATCH; + + if (i == seqStore->longLengthPos) { + if (seqStore->longLengthID == 1) { + outSeqs[i].litLength += 0x10000; + } else if (seqStore->longLengthID == 2) { + outSeqs[i].matchLength += 0x10000; } } + if (outSeqs[i].offset <= ZSTD_REP_NUM) { + outSeqs[i].rep = outSeqs[i].offset; + repIdx = (unsigned int)i - outSeqs[i].offset; + + if (outSeqs[i].litLength == 0) { + if (outSeqs[i].offset < 3) { + --repIdx; + } else { + repIdx = (unsigned int)i - 1; + } + ++outSeqs[i].rep; + } + assert(repIdx >= -3); + outSeqs[i].offset = repIdx >= 0 ? outSeqs[repIdx].offset : repStartValue[-repIdx - 1]; + if (outSeqs[i].rep == 4) { + --outSeqs[i].offset; + } + } else { + outSeqs[i].offset -= ZSTD_REP_NUM; + } + + position += outSeqs[i].litLength; + outSeqs[i].matchPos = (unsigned int)position; + position += outSeqs[i].matchLength; } zc->seqCollector.seqIndex += seqsSize; } diff --git a/tests/fuzzer.c b/tests/fuzzer.c index cf81230d..a22dafa3 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -307,7 +307,8 @@ static int FUZ_mallocTests(unsigned seed, double compressibility, unsigned part) static void FUZ_decodeSequences(BYTE* dst, ZSTD_Sequence* seqs, size_t seqsSize, BYTE* src, size_t size) { size_t i; - for(i = 0; i < seqsSize; ++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); @@ -316,7 +317,8 @@ static void FUZ_decodeSequences(BYTE* dst, ZSTD_Sequence* seqs, size_t seqsSize, src += seqs[i].litLength; size -= seqs[i].litLength; - memcpy(dst, dst-seqs[i].offset, seqs[i].matchLength); + 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; @@ -1982,20 +1984,19 @@ static int basicUnitTests(U32 const seed, double compressibility) DISPLAYLEVEL(3, "test%3i : ZSTD_getSequences decode from sequences test : ", testNb++); { - size_t srcSize = sizeof(U32) * 1000; + 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; size_t i; - U32 randSeed = seed; + size_t seqsSize; if (seqs == NULL) goto _output_error; assert(cctx != NULL); /* Populate src with random data */ - for (i = 0; i < srcSize / sizeof(U32); ++i) {((U32*)CNBuffer)[i] = FUZ_rand(&randSeed);} + RDG_genBuffer(CNBuffer, srcSize, compressibility, 0., seed); /* get the sequences */ seqsSize = ZSTD_getSequences(cctx, seqs, srcSize, src, srcSize);