diff options
-rw-r--r-- | lib/lz4frame.c | 24 | ||||
-rw-r--r-- | programs/frametest.c | 23 |
2 files changed, 35 insertions, 12 deletions
diff --git a/lib/lz4frame.c b/lib/lz4frame.c index 99953c1..d08cf94 100644 --- a/lib/lz4frame.c +++ b/lib/lz4frame.c @@ -707,7 +707,7 @@ size_t LZ4F_compressEnd(LZ4F_compressionContext_t compressionContext, void* dstB * If the result LZ4F_errorCode_t is not zero, there was an error during context creation. * Object can release its memory using LZ4F_freeDecompressionContext(); */ -LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_compressionContext_t* LZ4F_decompressionContextPtr, unsigned versionNumber) +LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_decompressionContext_t* LZ4F_decompressionContextPtr, unsigned versionNumber) { LZ4F_dctx_internal_t* dctxPtr; @@ -719,7 +719,7 @@ LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_compressionContext_t* LZ4F return OK_NoError; } -LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_compressionContext_t LZ4F_decompressionContext) +LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_decompressionContext_t LZ4F_decompressionContext) { LZ4F_dctx_internal_t* dctxPtr = (LZ4F_dctx_internal_t*)LZ4F_decompressionContext; FREEMEM(dctxPtr->tmpIn); @@ -766,8 +766,18 @@ static size_t LZ4F_decodeHeader(LZ4F_dctx_internal_t* dctxPtr, const void* srcVo { memset(&(dctxPtr->frameInfo), 0, sizeof(dctxPtr->frameInfo)); dctxPtr->frameInfo.frameType = skippableFrame; - dctxPtr->dStage = dstage_getSBlockSize; - return 4; + if (srcVoidPtr == (void*)(dctxPtr->header)) + { + memcpy(dctxPtr->header, dctxPtr->header + 4, srcSize-4); + dctxPtr->tmpInSize = srcSize-4; + dctxPtr->dStage = dstage_storeSBlockSize; + return srcSize; + } + else + { + dctxPtr->dStage = dstage_getSBlockSize; + return 4; + } } /* control magic number */ @@ -1023,12 +1033,6 @@ size_t LZ4F_decompress(LZ4F_decompressionContext_t decompressionContext, } LZ4F_errorCode_t errorCode = LZ4F_decodeHeader(dctxPtr, dctxPtr->header, 7); if (LZ4F_isError(errorCode)) return errorCode; - if (errorCode==4) - { - memcpy(dctxPtr->header, dctxPtr->header + 4, 3); - dctxPtr->tmpInSize = 3; - dctxPtr->dStage = dstage_storeSBlockSize; - } break; } diff --git a/programs/frametest.c b/programs/frametest.c index be2be76..62b6fa4 100644 --- a/programs/frametest.c +++ b/programs/frametest.c @@ -388,7 +388,7 @@ int basicTests(U32 seed, double compressibility) BYTE* op = (BYTE*)decodedBuffer; BYTE* const oend = (BYTE*)decodedBuffer + COMPRESSIBLE_NOISE_LENGTH; BYTE* ip = (BYTE*)compressedBuffer; - BYTE* const iend = (BYTE*)compressedBuffer + cSize + 8; + BYTE* iend = (BYTE*)compressedBuffer + cSize + 8; LZ4F_errorCode_t errorCode = LZ4F_createDecompressionContext(&dCtx, LZ4F_VERSION); if (LZ4F_isError(errorCode)) goto _output_error; @@ -411,6 +411,25 @@ int basicTests(U32 seed, double compressibility) } DISPLAYLEVEL(3, "Skipped %i bytes \n", (int)decodedBufferSize); + /* generate zero-size skippable frame */ + FUZ_writeLE32(ip, LZ4F_MAGIC_SKIPPABLE_START+1); + FUZ_writeLE32(ip+4, 0); + iend = ip+8; + + DISPLAYLEVEL(3, "random segment sizes : \n"); + while (ip < iend) + { + unsigned nbBits = FUZ_rand(&randState) % maxBits; + size_t iSize = (FUZ_rand(&randState) & ((1<<nbBits)-1)) + 1; + size_t oSize = oend-op; + if (iSize > (size_t)(iend-ip)) iSize = iend-ip; + errorCode = LZ4F_decompress(dCtx, op, &oSize, ip, &iSize, NULL); + if (LZ4F_isError(errorCode)) goto _output_error; + op += oSize; + ip += iSize; + } + DISPLAYLEVEL(3, "Skipped %i bytes \n", (int)decodedBufferSize); + errorCode = LZ4F_freeDecompressionContext(dCtx); if (LZ4F_isError(errorCode)) goto _output_error; } @@ -509,7 +528,7 @@ int fuzzerTests(U32 seed, unsigned nbTests, unsigned startTest, double compressi DISPLAYUPDATE(2, "\r%5u ", testNb); crcOrig = XXH64((BYTE*)srcBuffer+srcStart, srcSize, 1); - if ((FUZ_rand(&randState) & 0xFFF) == 3) + if ((FUZ_rand(&randState) & 0xFFF) == 0) { /* create a skippable frame (rare case) */ BYTE* op = (BYTE*)compressedBuffer; |