Merge pull request #3595 from facebook/dev

v1.5.5 last changes
This commit is contained in:
Yann Collet
2023-04-04 13:13:52 -07:00
committed by GitHub
2 changed files with 41 additions and 42 deletions
-3
View File
@@ -13,15 +13,12 @@ a list of known ports and bindings is provided on [Zstandard homepage](https://f
**Development branch status:** **Development branch status:**
[![Build Status][travisDevBadge]][travisLink] [![Build Status][travisDevBadge]][travisLink]
[![Build status][AppveyorDevBadge]][AppveyorLink]
[![Build status][CircleDevBadge]][CircleLink] [![Build status][CircleDevBadge]][CircleLink]
[![Build status][CirrusDevBadge]][CirrusLink] [![Build status][CirrusDevBadge]][CirrusLink]
[![Fuzzing Status][OSSFuzzBadge]][OSSFuzzLink] [![Fuzzing Status][OSSFuzzBadge]][OSSFuzzLink]
[travisDevBadge]: https://api.travis-ci.com/facebook/zstd.svg?branch=dev "Continuous Integration test suite" [travisDevBadge]: https://api.travis-ci.com/facebook/zstd.svg?branch=dev "Continuous Integration test suite"
[travisLink]: https://travis-ci.com/facebook/zstd [travisLink]: https://travis-ci.com/facebook/zstd
[AppveyorDevBadge]: https://ci.appveyor.com/api/projects/status/xt38wbdxjk5mrbem/branch/dev?svg=true "Windows test suite"
[AppveyorLink]: https://ci.appveyor.com/project/YannCollet/zstd-p0yf0
[CircleDevBadge]: https://circleci.com/gh/facebook/zstd/tree/dev.svg?style=shield "Short test suite" [CircleDevBadge]: https://circleci.com/gh/facebook/zstd/tree/dev.svg?style=shield "Short test suite"
[CircleLink]: https://circleci.com/gh/facebook/zstd [CircleLink]: https://circleci.com/gh/facebook/zstd
[CirrusDevBadge]: https://api.cirrus-ci.com/github/facebook/zstd.svg?branch=dev [CirrusDevBadge]: https://api.cirrus-ci.com/github/facebook/zstd.svg?branch=dev
+39 -37
View File
@@ -589,49 +589,52 @@ static size_t readSkippableFrameSize(void const* src, size_t srcSize)
sizeU32 = MEM_readLE32((BYTE const*)src + ZSTD_FRAMEIDSIZE); sizeU32 = MEM_readLE32((BYTE const*)src + ZSTD_FRAMEIDSIZE);
RETURN_ERROR_IF((U32)(sizeU32 + ZSTD_SKIPPABLEHEADERSIZE) < sizeU32, RETURN_ERROR_IF((U32)(sizeU32 + ZSTD_SKIPPABLEHEADERSIZE) < sizeU32,
frameParameter_unsupported, ""); frameParameter_unsupported, "");
{ { size_t const skippableSize = skippableHeaderSize + sizeU32;
size_t const skippableSize = skippableHeaderSize + sizeU32;
RETURN_ERROR_IF(skippableSize > srcSize, srcSize_wrong, ""); RETURN_ERROR_IF(skippableSize > srcSize, srcSize_wrong, "");
return skippableSize; return skippableSize;
} }
} }
/*! ZSTD_readSkippableFrame() : /*! ZSTD_readSkippableFrame() :
* Retrieves a zstd skippable frame containing data given by src, and writes it to dst buffer. * Retrieves content of a skippable frame, and writes it to dst buffer.
* *
* The parameter magicVariant will receive the magicVariant that was supplied when the frame was written, * The parameter magicVariant will receive the magicVariant that was supplied when the frame was written,
* i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START. This can be NULL if the caller is not interested * i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START. This can be NULL if the caller is not interested
* in the magicVariant. * in the magicVariant.
* *
* Returns an error if destination buffer is not large enough, or if the frame is not skippable. * Returns an error if destination buffer is not large enough, or if this is not a valid skippable frame.
* *
* @return : number of bytes written or a ZSTD error. * @return : number of bytes written or a ZSTD error.
*/ */
ZSTDLIB_API size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity, unsigned* magicVariant, size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity,
const void* src, size_t srcSize) unsigned* magicVariant, /* optional, can be NULL */
const void* src, size_t srcSize)
{ {
U32 const magicNumber = MEM_readLE32(src); RETURN_ERROR_IF(srcSize < ZSTD_SKIPPABLEHEADERSIZE, srcSize_wrong, "");
size_t skippableFrameSize = readSkippableFrameSize(src, srcSize);
size_t skippableContentSize = skippableFrameSize - ZSTD_SKIPPABLEHEADERSIZE;
/* check input validity */ { U32 const magicNumber = MEM_readLE32(src);
RETURN_ERROR_IF(!ZSTD_isSkippableFrame(src, srcSize), frameParameter_unsupported, ""); size_t skippableFrameSize = readSkippableFrameSize(src, srcSize);
RETURN_ERROR_IF(skippableFrameSize < ZSTD_SKIPPABLEHEADERSIZE || skippableFrameSize > srcSize, srcSize_wrong, ""); size_t skippableContentSize = skippableFrameSize - ZSTD_SKIPPABLEHEADERSIZE;
RETURN_ERROR_IF(skippableContentSize > dstCapacity, dstSize_tooSmall, "");
/* deliver payload */ /* check input validity */
if (skippableContentSize > 0 && dst != NULL) RETURN_ERROR_IF(!ZSTD_isSkippableFrame(src, srcSize), frameParameter_unsupported, "");
ZSTD_memcpy(dst, (const BYTE *)src + ZSTD_SKIPPABLEHEADERSIZE, skippableContentSize); RETURN_ERROR_IF(skippableFrameSize < ZSTD_SKIPPABLEHEADERSIZE || skippableFrameSize > srcSize, srcSize_wrong, "");
if (magicVariant != NULL) RETURN_ERROR_IF(skippableContentSize > dstCapacity, dstSize_tooSmall, "");
*magicVariant = magicNumber - ZSTD_MAGIC_SKIPPABLE_START;
return skippableContentSize; /* deliver payload */
if (skippableContentSize > 0 && dst != NULL)
ZSTD_memcpy(dst, (const BYTE *)src + ZSTD_SKIPPABLEHEADERSIZE, skippableContentSize);
if (magicVariant != NULL)
*magicVariant = magicNumber - ZSTD_MAGIC_SKIPPABLE_START;
return skippableContentSize;
}
} }
/** ZSTD_findDecompressedSize() : /** ZSTD_findDecompressedSize() :
* compatible with legacy mode
* `srcSize` must be the exact length of some number of ZSTD compressed and/or * `srcSize` must be the exact length of some number of ZSTD compressed and/or
* skippable frames * skippable frames
* @return : decompressed size of the frames contained */ * note: compatible with legacy mode
* @return : decompressed size of the frames contained */
unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize) unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
{ {
unsigned long long totalDstSize = 0; unsigned long long totalDstSize = 0;
@@ -641,9 +644,7 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
size_t const skippableSize = readSkippableFrameSize(src, srcSize); size_t const skippableSize = readSkippableFrameSize(src, srcSize);
if (ZSTD_isError(skippableSize)) { if (ZSTD_isError(skippableSize)) return ZSTD_CONTENTSIZE_ERROR;
return ZSTD_CONTENTSIZE_ERROR;
}
assert(skippableSize <= srcSize); assert(skippableSize <= srcSize);
src = (const BYTE *)src + skippableSize; src = (const BYTE *)src + skippableSize;
@@ -651,17 +652,17 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
continue; continue;
} }
{ unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize); { unsigned long long const fcs = ZSTD_getFrameContentSize(src, srcSize);
if (ret >= ZSTD_CONTENTSIZE_ERROR) return ret; if (fcs >= ZSTD_CONTENTSIZE_ERROR) return fcs;
/* check for overflow */ if (totalDstSize + fcs < totalDstSize)
if (totalDstSize + ret < totalDstSize) return ZSTD_CONTENTSIZE_ERROR; return ZSTD_CONTENTSIZE_ERROR; /* check for overflow */
totalDstSize += ret; totalDstSize += fcs;
} }
/* skip to next frame */
{ size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize); { size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize);
if (ZSTD_isError(frameSrcSize)) { if (ZSTD_isError(frameSrcSize)) return ZSTD_CONTENTSIZE_ERROR;
return ZSTD_CONTENTSIZE_ERROR; assert(frameSrcSize <= srcSize);
}
src = (const BYTE *)src + frameSrcSize; src = (const BYTE *)src + frameSrcSize;
srcSize -= frameSrcSize; srcSize -= frameSrcSize;
@@ -1091,17 +1092,18 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
} }
#endif #endif
{ U32 const magicNumber = MEM_readLE32(src); if (srcSize >= 4) {
DEBUGLOG(4, "reading magic number %08X (expecting %08X)", U32 const magicNumber = MEM_readLE32(src);
(unsigned)magicNumber, ZSTD_MAGICNUMBER); DEBUGLOG(5, "reading magic number %08X", (unsigned)magicNumber);
if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
/* skippable frame detected : skip it */
size_t const skippableSize = readSkippableFrameSize(src, srcSize); size_t const skippableSize = readSkippableFrameSize(src, srcSize);
FORWARD_IF_ERROR(skippableSize, "readSkippableFrameSize failed"); FORWARD_IF_ERROR(skippableSize, "invalid skippable frame");
assert(skippableSize <= srcSize); assert(skippableSize <= srcSize);
src = (const BYTE *)src + skippableSize; src = (const BYTE *)src + skippableSize;
srcSize -= skippableSize; srcSize -= skippableSize;
continue; continue; /* check next frame */
} } } }
if (ddict) { if (ddict) {