contrib/lz4/lib/lz4frame.c in extlz4-0.3 vs contrib/lz4/lib/lz4frame.c in extlz4-0.3.1
- old
+ new
@@ -211,12 +211,12 @@
#define LZ4F_BLOCKUNCOMPRESSED_FLAG 0x80000000U
#define LZ4F_BLOCKSIZEID_DEFAULT LZ4F_max64KB
static const size_t minFHSize = LZ4F_HEADER_SIZE_MIN; /* 7 */
static const size_t maxFHSize = LZ4F_HEADER_SIZE_MAX; /* 19 */
-static const size_t BHSize = 4; /* block header : size, and compress flag */
-static const size_t BFSize = 4; /* block footer : checksum (optional) */
+static const size_t BHSize = LZ4F_BLOCK_HEADER_SIZE; /* block header : size, and compress flag */
+static const size_t BFSize = LZ4F_BLOCK_CHECKSUM_SIZE; /* block footer : checksum (optional) */
/*-************************************
* Structures and local types
**************************************/
@@ -323,13 +323,13 @@
*/
static size_t LZ4F_compressBound_internal(size_t srcSize,
const LZ4F_preferences_t* preferencesPtr,
size_t alreadyBuffered)
{
- LZ4F_preferences_t prefsNull;
- MEM_INIT(&prefsNull, 0, sizeof(prefsNull));
+ LZ4F_preferences_t prefsNull = LZ4F_INIT_PREFERENCES;
prefsNull.frameInfo.contentChecksumFlag = LZ4F_contentChecksumEnabled; /* worst case */
+ prefsNull.frameInfo.blockChecksumFlag = LZ4F_blockChecksumEnabled; /* worst case */
{ const LZ4F_preferences_t* const prefsPtr = (preferencesPtr==NULL) ? &prefsNull : preferencesPtr;
U32 const flush = prefsPtr->autoFlush | (srcSize==0);
LZ4F_blockSizeID_t const blockID = prefsPtr->frameInfo.blockSizeID;
size_t const blockSize = LZ4F_getBlockSize(blockID);
size_t const maxBuffered = blockSize - 1;
@@ -1063,11 +1063,14 @@
* @return : if != 0, there was an error during context creation.
*/
LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_dctx** LZ4F_decompressionContextPtr, unsigned versionNumber)
{
LZ4F_dctx* const dctx = (LZ4F_dctx*)ALLOC_AND_ZERO(sizeof(LZ4F_dctx));
- if (dctx==NULL) return err0r(LZ4F_ERROR_GENERIC);
+ if (dctx == NULL) { /* failed allocation */
+ *LZ4F_decompressionContextPtr = NULL;
+ return err0r(LZ4F_ERROR_allocation_failed);
+ }
dctx->version = versionNumber;
*LZ4F_decompressionContextPtr = dctx;
return LZ4F_OK_NoError;
}
@@ -1126,12 +1129,14 @@
return 4;
}
}
/* control magic number */
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if (LZ4F_readLE32(srcPtr) != LZ4F_MAGICNUMBER)
return err0r(LZ4F_ERROR_frameType_unknown);
+#endif
dctx->frameInfo.frameType = LZ4F_frame;
/* Flags */
{ U32 const FLG = srcPtr[4];
U32 const version = (FLG>>6) & _2BITS;
@@ -1166,14 +1171,16 @@
if (((BD>>0)&_4BITS) != 0) return err0r(LZ4F_ERROR_reservedFlag_set); /* Reserved bits */
}
/* check header */
assert(frameHeaderSize > 5);
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
{ BYTE const HC = LZ4F_headerChecksum(srcPtr+4, frameHeaderSize-5);
if (HC != srcPtr[frameHeaderSize-1])
return err0r(LZ4F_ERROR_headerChecksum_invalid);
}
+#endif
/* save */
dctx->frameInfo.blockMode = (LZ4F_blockMode_t)blockMode;
dctx->frameInfo.blockChecksumFlag = (LZ4F_blockChecksum_t)blockChecksumFlag;
dctx->frameInfo.contentChecksumFlag = (LZ4F_contentChecksum_t)contentChecksumFlag;
@@ -1206,12 +1213,14 @@
/* special case : skippable frames */
if ((LZ4F_readLE32(src) & 0xFFFFFFF0U) == LZ4F_MAGIC_SKIPPABLE_START)
return 8;
/* control magic number */
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if (LZ4F_readLE32(src) != LZ4F_MAGICNUMBER)
return err0r(LZ4F_ERROR_frameType_unknown);
+#endif
/* Frame Header Size */
{ BYTE const FLG = ((const BYTE*)src)[4];
U32 const contentSizeFlag = (FLG>>3) & _1BIT;
U32 const dictIDFlag = FLG & _1BIT;
@@ -1489,11 +1498,11 @@
break;
}
/* next block is a compressed block */
dctx->tmpInTarget = nextCBlockSize + crcSize;
dctx->dStage = dstage_getCBlock;
- if (dstPtr==dstEnd) {
+ if (dstPtr==dstEnd || srcPtr==srcEnd) {
nextSrcSizeHint = BHSize + nextCBlockSize + crcSize;
doAnotherStage = 0;
}
break;
}
@@ -1550,12 +1559,17 @@
}
crcSrc = dctx->header;
}
{ U32 const readCRC = LZ4F_readLE32(crcSrc);
U32 const calcCRC = XXH32_digest(&dctx->blockChecksum);
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if (readCRC != calcCRC)
return err0r(LZ4F_ERROR_blockChecksum_invalid);
+#else
+ (void)readCRC;
+ (void)calcCRC;
+#endif
} }
dctx->dStage = dstage_getBlockHeader; /* new block */
break;
case dstage_getCBlock:
@@ -1590,12 +1604,17 @@
if (dctx->frameInfo.blockChecksumFlag) {
dctx->tmpInTarget -= 4;
assert(selectedIn != NULL); /* selectedIn is defined at this stage (either srcPtr, or dctx->tmpIn) */
{ U32 const readBlockCrc = LZ4F_readLE32(selectedIn + dctx->tmpInTarget);
U32 const calcBlockCrc = XXH32(selectedIn, dctx->tmpInTarget, 0);
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if (readBlockCrc != calcBlockCrc)
return err0r(LZ4F_ERROR_blockChecksum_invalid);
+#else
+ (void)readBlockCrc;
+ (void)calcBlockCrc;
+#endif
} }
if ((size_t)(dstEnd-dstPtr) >= dctx->maxBlockSize) {
const char* dict = (const char*)dctx->dict;
size_t dictSize = dctx->dictSize;
@@ -1719,11 +1738,16 @@
} /* if (dctx->dStage == dstage_storeSuffix) */
/* case dstage_checkSuffix: */ /* no direct entry, avoid initialization risks */
{ U32 const readCRC = LZ4F_readLE32(selectedIn);
U32 const resultCRC = XXH32_digest(&(dctx->xxh));
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if (readCRC != resultCRC)
return err0r(LZ4F_ERROR_contentChecksum_invalid);
+#else
+ (void)readCRC;
+ (void)resultCRC;
+#endif
nextSrcSizeHint = 0;
LZ4F_resetDecompressionContext(dctx);
doAnotherStage = 0;
break;
}