From d5da787c1bd92a22c87b6428321668548155995f Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 29 Mar 2015 11:20:09 +0100 Subject: Changed struct member to contentSize --- lib/lz4frame.c | 20 ++++++++++---------- lib/lz4frame.h | 2 +- programs/frametest.c | 6 +++--- programs/lz4io.c | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/lz4frame.c b/lib/lz4frame.c index 644f3e8..521be86 100644 --- a/lib/lz4frame.c +++ b/lib/lz4frame.c @@ -299,10 +299,10 @@ size_t LZ4F_compressFrame(void* dstBuffer, size_t dstMaxSize, const void* srcBuf else { memset(&prefs, 0, sizeof(prefs)); - prefs.frameInfo.frameOSize = (U64)srcSize; + prefs.frameInfo.contentSize = (U64)srcSize; } - if (prefs.frameInfo.frameOSize != 0) - prefs.frameInfo.frameOSize = (U64)srcSize; /* correct frame size if selected (!=0) */ + if (prefs.frameInfo.contentSize != 0) + prefs.frameInfo.contentSize = (U64)srcSize; /* correct content size if selected (!=0) */ if (prefs.compressionLevel < minHClevel) { @@ -446,13 +446,13 @@ size_t LZ4F_compressBegin(LZ4F_compressionContext_t compressionContext, void* ds *dstPtr++ = ((1 & _2BITS) << 6) /* Version('01') */ + ((cctxPtr->prefs.frameInfo.blockMode & _1BIT ) << 5) /* Block mode */ + (BYTE)((cctxPtr->prefs.frameInfo.contentChecksumFlag & _1BIT ) << 2) /* Frame checksum */ - + (BYTE)((cctxPtr->prefs.frameInfo.frameOSize > 0) << 3); /* Frame content size */ + + (BYTE)((cctxPtr->prefs.frameInfo.contentSize > 0) << 3); /* Frame content size */ /* BD Byte */ *dstPtr++ = (BYTE)((cctxPtr->prefs.frameInfo.blockSizeID & _3BITS) << 4); /* Optional Frame content size field */ - if (cctxPtr->prefs.frameInfo.frameOSize) + if (cctxPtr->prefs.frameInfo.contentSize) { - LZ4F_writeLE64(dstPtr, cctxPtr->prefs.frameInfo.frameOSize); + LZ4F_writeLE64(dstPtr, cctxPtr->prefs.frameInfo.contentSize); dstPtr += 8; cctxPtr->totalInSize = 0; } @@ -729,9 +729,9 @@ size_t LZ4F_compressEnd(LZ4F_compressionContext_t compressionContext, void* dstB cctxPtr->cStage = 0; /* state is now re-usable (with identical preferences) */ - if (cctxPtr->prefs.frameInfo.frameOSize) + if (cctxPtr->prefs.frameInfo.contentSize) { - if (cctxPtr->prefs.frameInfo.frameOSize != cctxPtr->totalInSize) + if (cctxPtr->prefs.frameInfo.contentSize != cctxPtr->totalInSize) return (size_t)-ERROR_frameSize_wrong; } @@ -871,7 +871,7 @@ static size_t LZ4F_decodeHeader(LZ4F_dctx_internal_t* dctxPtr, const void* srcVo dctxPtr->frameInfo.blockSizeID = (blockSizeID_t)blockSizeID; dctxPtr->maxBlockSize = LZ4F_getBlockSize(blockSizeID); if (contentSizeFlag) - dctxPtr->frameInfo.frameOSize = LZ4F_readLE64(srcPtr+6); + dctxPtr->frameInfo.contentSize = LZ4F_readLE64(srcPtr+6); /* init */ if (contentChecksumFlag) XXH32_reset(&(dctxPtr->xxh), 0); @@ -1389,7 +1389,7 @@ size_t LZ4F_decompress(LZ4F_decompressionContext_t decompressionContext, /* case dstage_decodeSBlockSize: */ /* no direct access */ { size_t SFrameSize = LZ4F_readLE32(selectedIn); - dctxPtr->frameInfo.frameOSize = SFrameSize; + dctxPtr->frameInfo.contentSize = SFrameSize; dctxPtr->tmpInTarget = SFrameSize; dctxPtr->dStage = dstage_skipSkippable; break; diff --git a/lib/lz4frame.h b/lib/lz4frame.h index 54db165..e29f84a 100644 --- a/lib/lz4frame.h +++ b/lib/lz4frame.h @@ -72,7 +72,7 @@ typedef struct { blockMode_t blockMode; /* blockLinked, blockIndependent ; 0 == default */ contentChecksum_t contentChecksumFlag; /* noContentChecksum, contentChecksumEnabled ; 0 == default */ frameType_t frameType; /* LZ4F_frame, skippableFrame ; 0 == default */ - unsigned long long frameOSize; /* Size of uncompressed (original) content ; 0 == unknown */ + unsigned long long contentSize; /* Size of uncompressed (original) content ; 0 == unknown */ unsigned reserved[2]; /* must be zero for forward compatibility */ } LZ4F_frameInfo_t; diff --git a/programs/frametest.c b/programs/frametest.c index 2a087ec..b73cc4e 100644 --- a/programs/frametest.c +++ b/programs/frametest.c @@ -402,7 +402,7 @@ int basicTests(U32 seed, double compressibility) DISPLAYLEVEL(3, "Compressed %i bytes into a %i bytes frame \n", (int)testSize, (int)(op-ostart)); DISPLAYLEVEL(3, "compress with frameSize : \n"); - prefs.frameInfo.frameOSize = testSize; + prefs.frameInfo.contentSize = testSize; op = ostart; errorCode = LZ4F_compressBegin(cctx, compressedBuffer, testSize, &prefs); if (LZ4F_isError(errorCode)) goto _output_error; @@ -415,7 +415,7 @@ int basicTests(U32 seed, double compressibility) DISPLAYLEVEL(3, "Compressed %i bytes into a %i bytes frame \n", (int)testSize, (int)(op-ostart)); DISPLAYLEVEL(3, "compress with wrong frameSize : \n"); - prefs.frameInfo.frameOSize = testSize+1; + prefs.frameInfo.contentSize = testSize+1; op = ostart; errorCode = LZ4F_compressBegin(cctx, compressedBuffer, testSize, &prefs); if (LZ4F_isError(errorCode)) goto _output_error; @@ -594,7 +594,7 @@ int fuzzerTests(U32 seed, unsigned nbTests, unsigned startTest, double compressi prefs.frameInfo.blockMode = (blockMode_t)BMId; prefs.frameInfo.blockSizeID = (blockSizeID_t)BSId; prefs.frameInfo.contentChecksumFlag = (contentChecksum_t)CCflag; - prefs.frameInfo.frameOSize = frameContentSize; + prefs.frameInfo.contentSize = frameContentSize; prefs.autoFlush = autoflush; prefs.compressionLevel = FUZ_rand(&randState) % 5; if ((FUZ_rand(&randState) & 0xF) == 1) prefsPtr = NULL; diff --git a/programs/lz4io.c b/programs/lz4io.c index f5c5e98..34d24bf 100644 --- a/programs/lz4io.c +++ b/programs/lz4io.c @@ -423,7 +423,7 @@ int LZ4IO_compressFilename(const char* input_filename, const char* output_filena if (g_contentSizeFlag) { unsigned long long fileSize = LZ4IO_GetFileSize(input_filename); - prefs.frameInfo.frameOSize = fileSize; /* == 0 if input == stdin */ + prefs.frameInfo.contentSize = fileSize; /* == 0 if input == stdin */ } /* Allocate Memory */ -- cgit v0.12 From 8cb06d5b9922b16854b05081ce829c223a8129fd Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 29 Mar 2015 13:28:32 +0100 Subject: lz4frame validates contentSize during decompression --- lib/lz4frame.c | 16 ++++++++++------ lib/lz4frame.h | 52 +++++++++++++++++++++++++++------------------------- programs/frametest.c | 4 ++-- 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/lib/lz4frame.c b/lib/lz4frame.c index 521be86..5683eee 100644 --- a/lib/lz4frame.c +++ b/lib/lz4frame.c @@ -636,8 +636,8 @@ size_t LZ4F_compressUpdate(LZ4F_compressionContext_t compressionContext, void* d if ((cctxPtr->tmpIn + blockSize) > (cctxPtr->tmpBuff + cctxPtr->maxBufferSize) /* necessarily blockLinked && lastBlockCompressed==fromTmpBuffer */ && !(cctxPtr->prefs.autoFlush)) { - LZ4F_localSaveDict(cctxPtr); - cctxPtr->tmpIn = cctxPtr->tmpBuff + 64 KB; + int realDictSize = LZ4F_localSaveDict(cctxPtr); + cctxPtr->tmpIn = cctxPtr->tmpBuff + realDictSize; } /* some input data left, necessarily < blockSize */ @@ -675,7 +675,7 @@ size_t LZ4F_flush(LZ4F_compressionContext_t compressionContext, void* dstBuffer, if (cctxPtr->tmpInSize == 0) return 0; /* nothing to flush */ if (cctxPtr->cStage != 1) return (size_t)-ERROR_GENERIC; - if (dstMaxSize < (cctxPtr->tmpInSize + 16)) return (size_t)-ERROR_dstMaxSize_tooSmall; + if (dstMaxSize < (cctxPtr->tmpInSize + 8)) return (size_t)-ERROR_dstMaxSize_tooSmall; /* +8 : block header(4) + block checksum(4) */ (void)compressOptionsPtr; /* not yet useful */ /* select compression function */ @@ -689,8 +689,8 @@ size_t LZ4F_flush(LZ4F_compressionContext_t compressionContext, void* dstBuffer, /* keep tmpIn within limits */ if ((cctxPtr->tmpIn + cctxPtr->maxBlockSize) > (cctxPtr->tmpBuff + cctxPtr->maxBufferSize)) /* necessarily blockLinked */ { - LZ4F_localSaveDict(cctxPtr); - cctxPtr->tmpIn = cctxPtr->tmpBuff + 64 KB; + int realDictSize = LZ4F_localSaveDict(cctxPtr); + cctxPtr->tmpIn = cctxPtr->tmpBuff + realDictSize; } return dstPtr - dstStart; @@ -1155,7 +1155,8 @@ size_t LZ4F_decompress(LZ4F_decompressionContext_t decompressionContext, if ((size_t)(srcEnd-srcPtr) < sizeToCopy) sizeToCopy = srcEnd - srcPtr; /* not enough input to read full block */ if ((size_t)(dstEnd-dstPtr) < sizeToCopy) sizeToCopy = dstEnd - dstPtr; memcpy(dstPtr, srcPtr, sizeToCopy); - if (dctxPtr->frameInfo.contentChecksumFlag) XXH32_update(&(dctxPtr->xxh), srcPtr, (U32)sizeToCopy); + if (dctxPtr->frameInfo.contentChecksumFlag) XXH32_update(&(dctxPtr->xxh), srcPtr, sizeToCopy); + if (dctxPtr->frameInfo.contentSize) dctxPtr->frameInfo.contentSize -= sizeToCopy; /* dictionary management */ if (dctxPtr->frameInfo.blockMode==blockLinked) @@ -1228,6 +1229,7 @@ size_t LZ4F_decompress(LZ4F_decompressionContext_t decompressionContext, decodedSize = decoder((const char*)selectedIn, (char*)dstPtr, (int)dctxPtr->tmpInTarget, (int)dctxPtr->maxBlockSize, (const char*)dctxPtr->dict, (int)dctxPtr->dictSize); if (decodedSize < 0) return (size_t)-ERROR_GENERIC; /* decompression failed */ if (dctxPtr->frameInfo.contentChecksumFlag) XXH32_update(&(dctxPtr->xxh), dstPtr, decodedSize); + if (dctxPtr->frameInfo.contentSize) dctxPtr->frameInfo.contentSize -= decodedSize; /* dictionary management */ if (dctxPtr->frameInfo.blockMode==blockLinked) @@ -1273,6 +1275,7 @@ size_t LZ4F_decompress(LZ4F_decompressionContext_t decompressionContext, decodedSize = decoder((const char*)selectedIn, (char*)dctxPtr->tmpOut, (int)dctxPtr->tmpInTarget, (int)dctxPtr->maxBlockSize, (const char*)dctxPtr->dict, (int)dctxPtr->dictSize); if (decodedSize < 0) return (size_t)-ERROR_decompressionFailed; /* decompression failed */ if (dctxPtr->frameInfo.contentChecksumFlag) XXH32_update(&(dctxPtr->xxh), dctxPtr->tmpOut, decodedSize); + if (dctxPtr->frameInfo.contentSize) dctxPtr->frameInfo.contentSize -= decodedSize; dctxPtr->tmpOutSize = decodedSize; dctxPtr->tmpOutStart = 0; dctxPtr->dStage = dstage_flushOut; @@ -1306,6 +1309,7 @@ size_t LZ4F_decompress(LZ4F_decompressionContext_t decompressionContext, case dstage_getSuffix: { size_t suffixSize = dctxPtr->frameInfo.contentChecksumFlag * 4; + if (dctxPtr->frameInfo.contentSize) return (size_t)-ERROR_frameSize_wrong; /* incorrect frame size decoded */ if (suffixSize == 0) /* frame completed */ { nextSrcSizeHint = 0; diff --git a/lib/lz4frame.h b/lib/lz4frame.h index e29f84a..01a756a 100644 --- a/lib/lz4frame.h +++ b/lib/lz4frame.h @@ -91,7 +91,7 @@ size_t LZ4F_compressFrameBound(size_t srcSize, const LZ4F_preferences_t* prefere size_t LZ4F_compressFrame(void* dstBuffer, size_t dstMaxSize, const void* srcBuffer, size_t srcSize, const LZ4F_preferences_t* preferencesPtr); /* LZ4F_compressFrame() - * Compress an entire srcBuffer into a valid LZ4 frame, as defined by specification v1.4.1. + * Compress an entire srcBuffer into a valid LZ4 frame, as defined by specification v1.5 * The most important rule is that dstBuffer MUST be large enough (dstMaxSize) to ensure compression completion even in worst case. * You can get the minimum value of dstMaxSize by using LZ4F_compressFrameBound() * If this condition is not respected, LZ4F_compressFrame() will fail (result is an errorCode) @@ -115,8 +115,8 @@ typedef struct { /* Resource Management */ #define LZ4F_VERSION 100 -LZ4F_errorCode_t LZ4F_createCompressionContext(LZ4F_compressionContext_t* LZ4F_compressionContextPtr, unsigned version); -LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_compressionContext_t LZ4F_compressionContext); +LZ4F_errorCode_t LZ4F_createCompressionContext(LZ4F_compressionContext_t* cctxPtr, unsigned version); +LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_compressionContext_t cctx); /* LZ4F_createCompressionContext() : * The first thing to do is to create a compressionContext object, which will be used in all compression operations. * This is achieved using LZ4F_createCompressionContext(), which takes as argument a version and an LZ4F_preferences_t structure. @@ -129,7 +129,7 @@ LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_compressionContext_t LZ4F_comp /* Compression */ -size_t LZ4F_compressBegin(LZ4F_compressionContext_t compressionContext, void* dstBuffer, size_t dstMaxSize, const LZ4F_preferences_t* preferencesPtr); +size_t LZ4F_compressBegin(LZ4F_compressionContext_t cctx, void* dstBuffer, size_t dstMaxSize, const LZ4F_preferences_t* prefsPtr); /* LZ4F_compressBegin() : * will write the frame header into dstBuffer. * dstBuffer must be large enough to accommodate a header (dstMaxSize). Maximum header size is 15 bytes. @@ -138,14 +138,14 @@ size_t LZ4F_compressBegin(LZ4F_compressionContext_t compressionContext, void* ds * or an error code (can be tested using LZ4F_isError()) */ -size_t LZ4F_compressBound(size_t srcSize, const LZ4F_preferences_t* preferencesPtr); +size_t LZ4F_compressBound(size_t srcSize, const LZ4F_preferences_t* prefsPtr); /* LZ4F_compressBound() : * Provides the minimum size of Dst buffer given srcSize to handle worst case situations. - * preferencesPtr is optional : you can provide NULL as argument, all preferences will then be set to default. + * prefsPtr is optional : you can provide NULL as argument, all preferences will then be set to default. * Note that different preferences will produce in different results. */ -size_t LZ4F_compressUpdate(LZ4F_compressionContext_t compressionContext, void* dstBuffer, size_t dstMaxSize, const void* srcBuffer, size_t srcSize, const LZ4F_compressOptions_t* compressOptionsPtr); +size_t LZ4F_compressUpdate(LZ4F_compressionContext_t cctx, void* dstBuffer, size_t dstMaxSize, const void* srcBuffer, size_t srcSize, const LZ4F_compressOptions_t* cOptPtr); /* LZ4F_compressUpdate() * LZ4F_compressUpdate() can be called repetitively to compress as much data as necessary. * The most important rule is that dstBuffer MUST be large enough (dstMaxSize) to ensure compression completion even in worst case. @@ -156,17 +156,18 @@ size_t LZ4F_compressUpdate(LZ4F_compressionContext_t compressionContext, void* d * The function outputs an error code if it fails (can be tested using LZ4F_isError()) */ -size_t LZ4F_flush(LZ4F_compressionContext_t compressionContext, void* dstBuffer, size_t dstMaxSize, const LZ4F_compressOptions_t* compressOptionsPtr); +size_t LZ4F_flush(LZ4F_compressionContext_t cctx, void* dstBuffer, size_t dstMaxSize, const LZ4F_compressOptions_t* cOptPtr); /* LZ4F_flush() - * Should you need to create compressed data immediately, without waiting for a block to be filled, - * you can call LZ4_flush(), which will immediately compress any remaining data buffered within compressionContext. - * The LZ4F_compressOptions_t structure is optional : you can provide NULL as argument. + * Should you need to generate compressed data immediately, without waiting for the current block to be filled, + * you can call LZ4_flush(), which will immediately compress any remaining data buffered within cctx. + * Note that dstMaxSize must be large enough to ensure the operation will be successful. + * LZ4F_compressOptions_t structure is optional : you can provide NULL as argument. * The result of the function is the number of bytes written into dstBuffer - * (it can be zero, this means there was no data left within compressionContext) + * (it can be zero, this means there was no data left within cctx) * The function outputs an error code if it fails (can be tested using LZ4F_isError()) */ -size_t LZ4F_compressEnd(LZ4F_compressionContext_t compressionContext, void* dstBuffer, size_t dstMaxSize, const LZ4F_compressOptions_t* compressOptionsPtr); +size_t LZ4F_compressEnd(LZ4F_compressionContext_t cctx, void* dstBuffer, size_t dstMaxSize, const LZ4F_compressOptions_t* cOptPtr); /* LZ4F_compressEnd() * When you want to properly finish the compressed frame, just call LZ4F_compressEnd(). * It will flush whatever data remained within compressionContext (like LZ4_flush()) @@ -174,7 +175,7 @@ size_t LZ4F_compressEnd(LZ4F_compressionContext_t compressionContext, void* dstB * The result of the function is the number of bytes written into dstBuffer (necessarily >= 4 (endMark size)) * The function outputs an error code if it fails (can be tested using LZ4F_isError()) * The LZ4F_compressOptions_t structure is optional : you can provide NULL as argument. - * compressionContext can then be used again, starting with LZ4F_compressBegin(). + * A successful call to LZ4F_compressEnd() makes cctx available again for future compression work. */ @@ -192,21 +193,21 @@ typedef struct { /* Resource management */ -LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_decompressionContext_t* ctxPtr, unsigned version); -LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_decompressionContext_t ctx); +LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_decompressionContext_t* dctxPtr, unsigned version); +LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_decompressionContext_t dctx); /* LZ4F_createDecompressionContext() : - * The first thing to do is to create a decompressionContext object, which will be used in all decompression operations. + * The first thing to do is to create an LZ4F_decompressionContext_t object, which will be used in all decompression operations. * This is achieved using LZ4F_createDecompressionContext(). - * The version provided MUST be LZ4F_VERSION. It is intended to track potential version differences between different binaries. + * The version provided MUST be LZ4F_VERSION. It is intended to track potential breaking differences between different versions. * The function will provide a pointer to a fully allocated and initialized LZ4F_decompressionContext_t object. - * If the result LZ4F_errorCode_t is not OK_NoError, there was an error during context creation. - * Object can release its memory using LZ4F_freeDecompressionContext(); + * The result is an errorCode, which can be tested using LZ4F_isError(). + * dctx memory can be released using LZ4F_freeDecompressionContext(); */ /* Decompression */ -size_t LZ4F_getFrameInfo(LZ4F_decompressionContext_t ctx, +size_t LZ4F_getFrameInfo(LZ4F_decompressionContext_t dctx, LZ4F_frameInfo_t* frameInfoPtr, const void* srcBuffer, size_t* srcSizePtr); /* LZ4F_getFrameInfo() @@ -220,10 +221,10 @@ size_t LZ4F_getFrameInfo(LZ4F_decompressionContext_t ctx, * or an error code which can be tested using LZ4F_isError(). */ -size_t LZ4F_decompress(LZ4F_decompressionContext_t ctx, +size_t LZ4F_decompress(LZ4F_decompressionContext_t dctx, void* dstBuffer, size_t* dstSizePtr, const void* srcBuffer, size_t* srcSizePtr, - const LZ4F_decompressOptions_t* optionsPtr); + const LZ4F_decompressOptions_t* dOptPtr); /* LZ4F_decompress() * Call this function repetitively to regenerate data compressed within srcBuffer. * The function will attempt to decode *srcSizePtr bytes from srcBuffer, into dstBuffer of maximum size *dstSizePtr. @@ -243,12 +244,13 @@ size_t LZ4F_decompress(LZ4F_decompressionContext_t ctx, * Schematically, it's the size of the current (or remaining) compressed block + header of next block. * Respecting the hint provides some boost to performance, since it does skip intermediate buffers. * This is just a hint, you can always provide any srcSize you want. - * When a frame is fully decoded, the function result will be 0. (no more data expected) + * When a frame is fully decoded, the function result will be 0 (no more data expected). * If decompression failed, function result is an error code, which can be tested using LZ4F_isError(). + * + * After a frame is fully decoded, dctx can be used again to decompress another frame. */ - #if defined (__cplusplus) } #endif diff --git a/programs/frametest.c b/programs/frametest.c index b73cc4e..96d5acb 100644 --- a/programs/frametest.c +++ b/programs/frametest.c @@ -740,7 +740,7 @@ int main(int argc, char** argv) int proba = FUZ_COMPRESSIBILITY_DEFAULT; int result=0; - // Check command line + /* Check command line */ programName = argv[0]; for(argNb=1; argNb