Fixed memory initialization issue, reported by Maciej Adamczyk

dev
Yann Collet 2016-04-07 19:35:23 +02:00
parent d7bee33caf
commit 9e8b09a7bd
3 changed files with 70 additions and 70 deletions

View File

@ -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;
} }
} }

View File

@ -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) :

View File

@ -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;
@ -581,7 +581,7 @@ unsigned long long FIO_decompressFrame(dRess_t ress,
/* Write block */ /* Write block */
{ size_t const sizeCheck = fwrite(ress.dstBuffer, 1, decodedSize, foutput); { size_t const sizeCheck = fwrite(ress.dstBuffer, 1, decodedSize, foutput);
if (sizeCheck != decodedSize) EXM_THROW(37, "Write error : unable to write data block into destination"); } if (sizeCheck != decodedSize) EXM_THROW(37, "Write error : unable to write data block into destination"); }
frameSize += decodedSize; frameSize += decodedSize;
DISPLAYUPDATE(2, "\rDecoded : %u MB... ", (U32)(frameSize>>20) ); DISPLAYUPDATE(2, "\rDecoded : %u MB... ", (U32)(frameSize>>20) );
@ -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)