Fixed memory initialization issue, reported by Maciej Adamczyk
parent
d7bee33caf
commit
9e8b09a7bd
130
lib/zbuff.c
130
lib/zbuff.c
|
@ -319,7 +319,7 @@ typedef enum { ZBUFFds_init, ZBUFFds_readHeader,
|
||||||
|
|
||||||
/* *** Resource management *** */
|
/* *** Resource management *** */
|
||||||
struct ZBUFF_DCtx_s {
|
struct ZBUFF_DCtx_s {
|
||||||
ZSTD_DCtx* zc;
|
ZSTD_DCtx* zd;
|
||||||
ZSTD_frameParams fParams;
|
ZSTD_frameParams fParams;
|
||||||
size_t blockSize;
|
size_t blockSize;
|
||||||
char* inBuff;
|
char* inBuff;
|
||||||
|
@ -335,63 +335,63 @@ struct ZBUFF_DCtx_s {
|
||||||
|
|
||||||
ZBUFF_DCtx* ZBUFF_createDCtx(void)
|
ZBUFF_DCtx* ZBUFF_createDCtx(void)
|
||||||
{
|
{
|
||||||
ZBUFF_DCtx* zbc = (ZBUFF_DCtx*)malloc(sizeof(ZBUFF_DCtx));
|
ZBUFF_DCtx* zbd = (ZBUFF_DCtx*)malloc(sizeof(ZBUFF_DCtx));
|
||||||
if (zbc==NULL) return NULL;
|
if (zbd==NULL) return NULL;
|
||||||
memset(zbc, 0, sizeof(*zbc));
|
memset(zbd, 0, sizeof(*zbd));
|
||||||
zbc->zc = ZSTD_createDCtx();
|
zbd->zd = ZSTD_createDCtx();
|
||||||
zbc->stage = ZBUFFds_init;
|
zbd->stage = ZBUFFds_init;
|
||||||
return zbc;
|
return zbd;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZBUFF_freeDCtx(ZBUFF_DCtx* zbc)
|
size_t ZBUFF_freeDCtx(ZBUFF_DCtx* zbd)
|
||||||
{
|
{
|
||||||
if (zbc==NULL) return 0; /* support free on null */
|
if (zbd==NULL) return 0; /* support free on null */
|
||||||
ZSTD_freeDCtx(zbc->zc);
|
ZSTD_freeDCtx(zbd->zd);
|
||||||
free(zbc->inBuff);
|
free(zbd->inBuff);
|
||||||
free(zbc->outBuff);
|
free(zbd->outBuff);
|
||||||
free(zbc);
|
free(zbd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *** Initialization *** */
|
/* *** Initialization *** */
|
||||||
|
|
||||||
size_t ZBUFF_decompressInitDictionary(ZBUFF_DCtx* zbc, const void* dict, size_t dictSize)
|
size_t ZBUFF_decompressInitDictionary(ZBUFF_DCtx* zbd, const void* dict, size_t dictSize)
|
||||||
{
|
{
|
||||||
zbc->stage = ZBUFFds_readHeader;
|
zbd->stage = ZBUFFds_readHeader;
|
||||||
zbc->inPos = zbc->outStart = zbc->outEnd = 0;
|
zbd->inPos = zbd->outStart = zbd->outEnd = 0;
|
||||||
return ZSTD_decompressBegin_usingDict(zbc->zc, dict, dictSize);
|
return ZSTD_decompressBegin_usingDict(zbd->zd, dict, dictSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZBUFF_decompressInit(ZBUFF_DCtx* zbc)
|
size_t ZBUFF_decompressInit(ZBUFF_DCtx* zbd)
|
||||||
{
|
{
|
||||||
return ZBUFF_decompressInitDictionary(zbc, NULL, 0);
|
return ZBUFF_decompressInitDictionary(zbd, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *** Decompression *** */
|
/* *** Decompression *** */
|
||||||
|
|
||||||
size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbc,
|
size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd,
|
||||||
void* dst, size_t* dstCapacityPtr,
|
void* dst, size_t* dstCapacityPtr,
|
||||||
const void* src, size_t* srcSizePtr)
|
const void* src, size_t* srcSizePtr)
|
||||||
{
|
{
|
||||||
const char* const istart = (const char*)src;
|
const char* const istart = (const char*)src;
|
||||||
const char* ip = istart;
|
|
||||||
const char* const iend = istart + *srcSizePtr;
|
const char* const iend = istart + *srcSizePtr;
|
||||||
|
const char* ip = istart;
|
||||||
char* const ostart = (char*)dst;
|
char* const ostart = (char*)dst;
|
||||||
char* op = ostart;
|
|
||||||
char* const oend = ostart + *dstCapacityPtr;
|
char* const oend = ostart + *dstCapacityPtr;
|
||||||
|
char* op = ostart;
|
||||||
U32 notDone = 1;
|
U32 notDone = 1;
|
||||||
|
|
||||||
while (notDone) {
|
while (notDone) {
|
||||||
switch(zbc->stage)
|
switch(zbd->stage)
|
||||||
{
|
{
|
||||||
case ZBUFFds_init :
|
case ZBUFFds_init :
|
||||||
return ERROR(init_missing);
|
return ERROR(init_missing);
|
||||||
|
|
||||||
case ZBUFFds_readHeader :
|
case ZBUFFds_readHeader :
|
||||||
/* read header from src */
|
/* read header from src */
|
||||||
{ size_t const headerSize = ZSTD_getFrameParams(&(zbc->fParams), src, *srcSizePtr);
|
{ size_t const headerSize = ZSTD_getFrameParams(&(zbd->fParams), src, *srcSizePtr);
|
||||||
if (ZSTD_isError(headerSize)) return headerSize;
|
if (ZSTD_isError(headerSize)) return headerSize;
|
||||||
if (headerSize) {
|
if (headerSize) {
|
||||||
/* not enough input to decode header : needs headerSize > *srcSizePtr */
|
/* not enough input to decode header : needs headerSize > *srcSizePtr */
|
||||||
|
@ -401,76 +401,76 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbc,
|
||||||
} }
|
} }
|
||||||
|
|
||||||
/* Frame header instruct buffer sizes */
|
/* Frame header instruct buffer sizes */
|
||||||
{ size_t const blockSize = MIN(1 << zbc->fParams.windowLog, ZSTD_BLOCKSIZE_MAX);
|
{ size_t const blockSize = MIN(1 << zbd->fParams.windowLog, ZSTD_BLOCKSIZE_MAX);
|
||||||
zbc->blockSize = blockSize;
|
zbd->blockSize = blockSize;
|
||||||
if (zbc->inBuffSize < blockSize) {
|
if (zbd->inBuffSize < blockSize) {
|
||||||
free(zbc->inBuff);
|
free(zbd->inBuff);
|
||||||
zbc->inBuffSize = blockSize;
|
zbd->inBuffSize = blockSize;
|
||||||
zbc->inBuff = (char*)malloc(blockSize);
|
zbd->inBuff = (char*)malloc(blockSize);
|
||||||
if (zbc->inBuff == NULL) return ERROR(memory_allocation);
|
if (zbd->inBuff == NULL) return ERROR(memory_allocation);
|
||||||
}
|
}
|
||||||
{ size_t const neededOutSize = ((size_t)1 << zbc->fParams.windowLog) + blockSize;
|
{ size_t const neededOutSize = ((size_t)1 << zbd->fParams.windowLog) + blockSize;
|
||||||
if (zbc->outBuffSize < neededOutSize) {
|
if (zbd->outBuffSize < neededOutSize) {
|
||||||
free(zbc->outBuff);
|
free(zbd->outBuff);
|
||||||
zbc->outBuffSize = neededOutSize;
|
zbd->outBuffSize = neededOutSize;
|
||||||
zbc->outBuff = (char*)malloc(neededOutSize);
|
zbd->outBuff = (char*)malloc(neededOutSize);
|
||||||
if (zbc->outBuff == NULL) return ERROR(memory_allocation);
|
if (zbd->outBuff == NULL) return ERROR(memory_allocation);
|
||||||
} } }
|
} } }
|
||||||
zbc->stage = ZBUFFds_read;
|
zbd->stage = ZBUFFds_read;
|
||||||
|
|
||||||
case ZBUFFds_read:
|
case ZBUFFds_read:
|
||||||
{ size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zbc->zc);
|
{ size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zbd->zd);
|
||||||
if (neededInSize==0) { /* end of frame */
|
if (neededInSize==0) { /* end of frame */
|
||||||
zbc->stage = ZBUFFds_init;
|
zbd->stage = ZBUFFds_init;
|
||||||
notDone = 0;
|
notDone = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((size_t)(iend-ip) >= neededInSize) {
|
if ((size_t)(iend-ip) >= neededInSize) {
|
||||||
/* directly decode from src */
|
/* directly decode from src */
|
||||||
size_t const decodedSize = ZSTD_decompressContinue(zbc->zc,
|
size_t const decodedSize = ZSTD_decompressContinue(zbd->zd,
|
||||||
zbc->outBuff + zbc->outStart, zbc->outBuffSize - zbc->outStart,
|
zbd->outBuff + zbd->outStart, zbd->outBuffSize - zbd->outStart,
|
||||||
ip, neededInSize);
|
ip, neededInSize);
|
||||||
if (ZSTD_isError(decodedSize)) return decodedSize;
|
if (ZSTD_isError(decodedSize)) return decodedSize;
|
||||||
ip += neededInSize;
|
ip += neededInSize;
|
||||||
if (!decodedSize) break; /* this was just a header */
|
if (!decodedSize) break; /* this was just a header */
|
||||||
zbc->outEnd = zbc->outStart + decodedSize;
|
zbd->outEnd = zbd->outStart + decodedSize;
|
||||||
zbc->stage = ZBUFFds_flush;
|
zbd->stage = ZBUFFds_flush;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ip==iend) { notDone = 0; break; } /* no more input */
|
if (ip==iend) { notDone = 0; break; } /* no more input */
|
||||||
zbc->stage = ZBUFFds_load;
|
zbd->stage = ZBUFFds_load;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ZBUFFds_load:
|
case ZBUFFds_load:
|
||||||
{ size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zbc->zc);
|
{ size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zbd->zd);
|
||||||
size_t const toLoad = neededInSize - zbc->inPos; /* should always be <= remaining space within inBuff */
|
size_t const toLoad = neededInSize - zbd->inPos; /* should always be <= remaining space within inBuff */
|
||||||
size_t loadedSize;
|
size_t loadedSize;
|
||||||
if (toLoad > zbc->inBuffSize - zbc->inPos) return ERROR(corruption_detected); /* should never happen */
|
if (toLoad > zbd->inBuffSize - zbd->inPos) return ERROR(corruption_detected); /* should never happen */
|
||||||
loadedSize = ZBUFF_limitCopy(zbc->inBuff + zbc->inPos, toLoad, ip, iend-ip);
|
loadedSize = ZBUFF_limitCopy(zbd->inBuff + zbd->inPos, toLoad, ip, iend-ip);
|
||||||
ip += loadedSize;
|
ip += loadedSize;
|
||||||
zbc->inPos += loadedSize;
|
zbd->inPos += loadedSize;
|
||||||
if (loadedSize < toLoad) { notDone = 0; break; } /* not enough input, wait for more */
|
if (loadedSize < toLoad) { notDone = 0; break; } /* not enough input, wait for more */
|
||||||
/* decode loaded input */
|
/* decode loaded input */
|
||||||
{ size_t const decodedSize = ZSTD_decompressContinue(zbc->zc,
|
{ size_t const decodedSize = ZSTD_decompressContinue(zbd->zd,
|
||||||
zbc->outBuff + zbc->outStart, zbc->outBuffSize - zbc->outStart,
|
zbd->outBuff + zbd->outStart, zbd->outBuffSize - zbd->outStart,
|
||||||
zbc->inBuff, neededInSize);
|
zbd->inBuff, neededInSize);
|
||||||
if (ZSTD_isError(decodedSize)) return decodedSize;
|
if (ZSTD_isError(decodedSize)) return decodedSize;
|
||||||
zbc->inPos = 0; /* input is consumed */
|
zbd->inPos = 0; /* input is consumed */
|
||||||
if (!decodedSize) { zbc->stage = ZBUFFds_read; break; } /* this was just a header */
|
if (!decodedSize) { zbd->stage = ZBUFFds_read; break; } /* this was just a header */
|
||||||
zbc->outEnd = zbc->outStart + decodedSize;
|
zbd->outEnd = zbd->outStart + decodedSize;
|
||||||
zbc->stage = ZBUFFds_flush;
|
zbd->stage = ZBUFFds_flush;
|
||||||
// break; /* ZBUFFds_flush follows */
|
// break; /* ZBUFFds_flush follows */
|
||||||
} }
|
} }
|
||||||
|
|
||||||
case ZBUFFds_flush:
|
case ZBUFFds_flush:
|
||||||
{ size_t const toFlushSize = zbc->outEnd - zbc->outStart;
|
{ size_t const toFlushSize = zbd->outEnd - zbd->outStart;
|
||||||
size_t const flushedSize = ZBUFF_limitCopy(op, oend-op, zbc->outBuff + zbc->outStart, toFlushSize);
|
size_t const flushedSize = ZBUFF_limitCopy(op, oend-op, zbd->outBuff + zbd->outStart, toFlushSize);
|
||||||
op += flushedSize;
|
op += flushedSize;
|
||||||
zbc->outStart += flushedSize;
|
zbd->outStart += flushedSize;
|
||||||
if (flushedSize == toFlushSize) {
|
if (flushedSize == toFlushSize) {
|
||||||
zbc->stage = ZBUFFds_read;
|
zbd->stage = ZBUFFds_read;
|
||||||
if (zbc->outStart + zbc->blockSize > zbc->outBuffSize)
|
if (zbd->outStart + zbd->blockSize > zbd->outBuffSize)
|
||||||
zbc->outStart = zbc->outEnd = 0;
|
zbd->outStart = zbd->outEnd = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* cannot flush everything */
|
/* cannot flush everything */
|
||||||
|
@ -483,9 +483,9 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbc,
|
||||||
/* result */
|
/* result */
|
||||||
*srcSizePtr = ip-istart;
|
*srcSizePtr = ip-istart;
|
||||||
*dstCapacityPtr = op-ostart;
|
*dstCapacityPtr = op-ostart;
|
||||||
{ size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zbc->zc);
|
{ size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zbd->zd);
|
||||||
if (nextSrcSizeHint > ZSTD_blockHeaderSize) nextSrcSizeHint+= ZSTD_blockHeaderSize; /* get following block header too */
|
if (nextSrcSizeHint > ZSTD_blockHeaderSize) nextSrcSizeHint+= ZSTD_blockHeaderSize; /* get following block header too */
|
||||||
nextSrcSizeHint -= zbc->inPos; /* already loaded*/
|
nextSrcSizeHint -= zbd->inPos; /* already loaded*/
|
||||||
return nextSrcSizeHint;
|
return nextSrcSizeHint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -400,6 +400,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(corruption_detected);
|
if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(corruption_detected);
|
||||||
|
if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
|
||||||
|
|
||||||
if (HUF_isError(singleStream ?
|
if (HUF_isError(singleStream ?
|
||||||
HUF_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
|
HUF_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
|
||||||
|
|
|
@ -567,7 +567,7 @@ unsigned long long FIO_decompressFrame(dRess_t ress,
|
||||||
/* Complete Header loading */
|
/* Complete Header loading */
|
||||||
{ size_t const toLoad = ZSTD_frameHeaderSize_max - alreadyLoaded; /* assumption : alreadyLoaded <= ZSTD_frameHeaderSize_max */
|
{ size_t const toLoad = ZSTD_frameHeaderSize_max - alreadyLoaded; /* assumption : alreadyLoaded <= ZSTD_frameHeaderSize_max */
|
||||||
size_t const checkSize = fread(((char*)ress.srcBuffer) + alreadyLoaded, 1, toLoad, finput);
|
size_t const checkSize = fread(((char*)ress.srcBuffer) + alreadyLoaded, 1, toLoad, finput);
|
||||||
if (checkSize != toLoad) EXM_THROW(32, "Read error");
|
if (checkSize != toLoad) EXM_THROW(32, "Read error"); /* assumption : srcSize >= ZSTD_frameHeaderSize_max */
|
||||||
}
|
}
|
||||||
readSize = ZSTD_frameHeaderSize_max;
|
readSize = ZSTD_frameHeaderSize_max;
|
||||||
|
|
||||||
|
@ -613,10 +613,9 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName)
|
||||||
|
|
||||||
/* for each frame */
|
/* for each frame */
|
||||||
for ( ; ; ) {
|
for ( ; ; ) {
|
||||||
size_t sizeCheck;
|
|
||||||
/* check magic number -> version */
|
/* check magic number -> version */
|
||||||
size_t toRead = 4;
|
size_t const toRead = 4;
|
||||||
sizeCheck = fread(ress.srcBuffer, (size_t)1, toRead, srcFile);
|
size_t const sizeCheck = fread(ress.srcBuffer, (size_t)1, toRead, srcFile);
|
||||||
if (sizeCheck==0) break; /* no more input */
|
if (sizeCheck==0) break; /* no more input */
|
||||||
if (sizeCheck != toRead) EXM_THROW(31, "zstd: %s read error : cannot read header", srcFileName);
|
if (sizeCheck != toRead) EXM_THROW(31, "zstd: %s read error : cannot read header", srcFileName);
|
||||||
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
|
||||||
|
|
Loading…
Reference in New Issue