From: Yann Collet Date: Fri, 29 Sep 2017 22:54:09 +0000 (-0700) Subject: decode more data before triggering error X-Git-Tag: v1.3.2~3^2~20^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F875%2Fhead;p=thirdparty%2Fzstd.git decode more data before triggering error fixes #874 : when a frame is not properly terminated by a "last block" signal, zstd -d used to detect it immediately and error out. This version will decode and flush the last block, and only then issue an error. --- diff --git a/programs/fileio.c b/programs/fileio.c index 9c5e2c40b..ab1644eb9 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1213,14 +1213,18 @@ unsigned long long FIO_decompressZstdFrame(dRess_t* ress, U64 frameSize = 0; U32 storedSkips = 0; + size_t const srcFileLength = strlen(srcFileName); + if (srcFileLength>20) srcFileName += srcFileLength-20; /* display last 20 characters only */ + ZSTD_resetDStream(ress->dctx); - if (strlen(srcFileName)>20) srcFileName += strlen(srcFileName)-20; /* display last 20 characters */ /* Header loading : ensures ZSTD_getFrameHeader() will succeed */ - { size_t const toRead = ZSTD_FRAMEHEADERSIZE_MAX; - if (ress->srcBufferLoaded < toRead) - ress->srcBufferLoaded += fread(((char*)ress->srcBuffer) + ress->srcBufferLoaded, 1, toRead - ress->srcBufferLoaded, finput); - } + { size_t const toDecode = ZSTD_FRAMEHEADERSIZE_MAX; + if (ress->srcBufferLoaded < toDecode) { + size_t const toRead = toDecode - ress->srcBufferLoaded; + void* const startPosition = (char*)ress->srcBuffer + ress->srcBufferLoaded; + ress->srcBufferLoaded += fread(startPosition, 1, toRead, finput); + } } /* Main decompression Loop */ while (1) { @@ -1253,14 +1257,17 @@ unsigned long long FIO_decompressZstdFrame(dRess_t* ress, } /* Fill input buffer */ - { size_t const toRead = MIN(readSizeHint, ress->srcBufferSize); /* support large skippable frames */ - if (ress->srcBufferLoaded < toRead) - ress->srcBufferLoaded += fread((char*)ress->srcBuffer + ress->srcBufferLoaded, - 1, toRead - ress->srcBufferLoaded, finput); - if (ress->srcBufferLoaded < toRead) { - DISPLAYLEVEL(1, "%s : Read error (39) : premature end \n", - srcFileName); - return FIO_ERROR_FRAME_DECODING; + { size_t const toDecode = MIN(readSizeHint, ress->srcBufferSize); /* support large skippable frames */ + if (ress->srcBufferLoaded < toDecode) { + size_t const toRead = toDecode - ress->srcBufferLoaded; /* > 0 */ + void* const startPosition = (char*)ress->srcBuffer + ress->srcBufferLoaded; + size_t const readSize = fread(startPosition, 1, toRead, finput); + if (readSize==0) { + DISPLAYLEVEL(1, "%s : Read error (39) : premature end \n", + srcFileName); + return FIO_ERROR_FRAME_DECODING; + } + ress->srcBufferLoaded += readSize; } } } FIO_fwriteSparseEnd(ress->dstFile, storedSkips);