diff --git a/NEWS b/NEWS index be334975..96ff25fd 100644 --- a/NEWS +++ b/NEWS @@ -2,7 +2,7 @@ v1.1.4 cli : new : can compress in *.gz format, using --format=gzip command, by Przemyslaw Skibinski cli : new : advanced benchmark command --priority=rt cli : fix : write on sparse-enabled file systems in 32-bits mode, by @ds77 -API : new : ZSTD_getFrameCompressedSize(), ZSTD_getFrameContentSize(), ZSTD_findDecompressedSize(), by Sean Purcell +API : new : ZSTD_findFrameCompressedSize(), ZSTD_getFrameContentSize(), ZSTD_findDecompressedSize(), by Sean Purcell API : change : ZSTD_compress*() with srcSize==0 create an empty-frame of known size build:new : meson build system in contrib/meson, by Dima Krasner doc : new : educational decoder, by Sean Purcell diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index eda8b9dd..362da1a7 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -369,7 +369,7 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize) totalDstSize += ret; } { - size_t const frameSrcSize = ZSTD_getFrameCompressedSize(src, srcSize); + size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize); if (ZSTD_isError(frameSrcSize)) { return ZSTD_CONTENTSIZE_ERROR; } @@ -1437,17 +1437,20 @@ size_t ZSTD_generateNxBytes(void* dst, size_t dstCapacity, BYTE byte, size_t len return length; } -/** ZSTD_getFrameCompressedSize() : +/** ZSTD_findFrameCompressedSize() : * compatible with legacy mode * `src` must point to the start of a ZSTD or ZSTD legacy frame * `srcSize` must be at least as large as the frame contained * @return : the compressed size of the frame starting at `src` */ -size_t ZSTD_getFrameCompressedSize(const void *src, size_t srcSize) +size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize) { #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1) - if (ZSTD_isLegacy(src, srcSize)) return ZSTD_getFrameCompressedSizeLegacy(src, srcSize); + if (ZSTD_isLegacy(src, srcSize)) return ZSTD_findFrameCompressedSizeLegacy(src, srcSize); #endif - { + if (srcSize >= ZSTD_skippableHeaderSize && + (MEM_readLE32(src) & 0xFFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { + return ZSTD_skippableHeaderSize + MEM_readLE32((const BYTE*)src + 4); + } else { const BYTE* ip = (const BYTE*)src; const BYTE* const ipstart = ip; size_t remainingSize = srcSize; @@ -1576,7 +1579,7 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx, #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) if (ZSTD_isLegacy(src, srcSize)) { - size_t const frameSize = ZSTD_getFrameCompressedSizeLegacy(src, srcSize); + size_t const frameSize = ZSTD_findFrameCompressedSizeLegacy(src, srcSize); size_t decodedSize; if (ZSTD_isError(frameSize)) return frameSize; diff --git a/lib/legacy/zstd_legacy.h b/lib/legacy/zstd_legacy.h index b0a7b71d..707e76f0 100644 --- a/lib/legacy/zstd_legacy.h +++ b/lib/legacy/zstd_legacy.h @@ -123,26 +123,26 @@ MEM_STATIC size_t ZSTD_decompressLegacy( } } -MEM_STATIC size_t ZSTD_getFrameCompressedSizeLegacy(const void *src, +MEM_STATIC size_t ZSTD_findFrameCompressedSizeLegacy(const void *src, size_t compressedSize) { U32 const version = ZSTD_isLegacy(src, compressedSize); switch(version) { case 1 : - return ZSTDv01_getFrameCompressedSize(src, compressedSize); + return ZSTDv01_findFrameCompressedSize(src, compressedSize); case 2 : - return ZSTDv02_getFrameCompressedSize(src, compressedSize); + return ZSTDv02_findFrameCompressedSize(src, compressedSize); case 3 : - return ZSTDv03_getFrameCompressedSize(src, compressedSize); + return ZSTDv03_findFrameCompressedSize(src, compressedSize); case 4 : - return ZSTDv04_getFrameCompressedSize(src, compressedSize); + return ZSTDv04_findFrameCompressedSize(src, compressedSize); case 5 : - return ZSTDv05_getFrameCompressedSize(src, compressedSize); + return ZSTDv05_findFrameCompressedSize(src, compressedSize); case 6 : - return ZSTDv06_getFrameCompressedSize(src, compressedSize); + return ZSTDv06_findFrameCompressedSize(src, compressedSize); case 7 : - return ZSTDv07_getFrameCompressedSize(src, compressedSize); + return ZSTDv07_findFrameCompressedSize(src, compressedSize); default : return ERROR(prefix_unknown); } diff --git a/lib/legacy/zstd_v01.c b/lib/legacy/zstd_v01.c index a0c78a4b..bcacb8d5 100644 --- a/lib/legacy/zstd_v01.c +++ b/lib/legacy/zstd_v01.c @@ -1992,7 +1992,7 @@ size_t ZSTDv01_decompress(void* dst, size_t maxDstSize, const void* src, size_t return ZSTDv01_decompressDCtx(&ctx, dst, maxDstSize, src, srcSize); } -size_t ZSTDv01_getFrameCompressedSize(const void* src, size_t srcSize) +size_t ZSTDv01_findFrameCompressedSize(const void* src, size_t srcSize) { const BYTE* ip = (const BYTE*)src; size_t remainingSize = srcSize; diff --git a/lib/legacy/zstd_v01.h b/lib/legacy/zstd_v01.h index 21959fcd..13cb3acf 100644 --- a/lib/legacy/zstd_v01.h +++ b/lib/legacy/zstd_v01.h @@ -40,7 +40,7 @@ ZSTDv01_getFrameSrcSize() : get the source length of a ZSTD frame compliant with return : the number of bytes that would be read to decompress this frame or an errorCode if it fails (which can be tested using ZSTDv01_isError()) */ -size_t ZSTDv01_getFrameCompressedSize(const void* src, size_t compressedSize); +size_t ZSTDv01_findFrameCompressedSize(const void* src, size_t compressedSize); /** ZSTDv01_isError() : tells if the result of ZSTDv01_decompress() is an error diff --git a/lib/legacy/zstd_v02.c b/lib/legacy/zstd_v02.c index 6cbf8023..2297b28c 100644 --- a/lib/legacy/zstd_v02.c +++ b/lib/legacy/zstd_v02.c @@ -3378,7 +3378,7 @@ static size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, siz return ZSTD_decompressDCtx(&ctx, dst, maxDstSize, src, srcSize); } -static size_t ZSTD_getFrameCompressedSize(const void *src, size_t srcSize) +static size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize) { const BYTE* ip = (const BYTE*)src; @@ -3524,9 +3524,9 @@ size_t ZSTDv02_decompress( void* dst, size_t maxOriginalSize, return ZSTD_decompress(dst, maxOriginalSize, src, compressedSize); } -size_t ZSTDv02_getFrameCompressedSize(const void *src, size_t compressedSize) +size_t ZSTDv02_findFrameCompressedSize(const void *src, size_t compressedSize) { - return ZSTD_getFrameCompressedSize(src, compressedSize); + return ZSTD_findFrameCompressedSize(src, compressedSize); } ZSTDv02_Dctx* ZSTDv02_createDCtx(void) diff --git a/lib/legacy/zstd_v02.h b/lib/legacy/zstd_v02.h index 9542fc0e..d14f0293 100644 --- a/lib/legacy/zstd_v02.h +++ b/lib/legacy/zstd_v02.h @@ -40,7 +40,7 @@ ZSTDv02_getFrameSrcSize() : get the source length of a ZSTD frame compliant with return : the number of bytes that would be read to decompress this frame or an errorCode if it fails (which can be tested using ZSTDv02_isError()) */ -size_t ZSTDv02_getFrameCompressedSize(const void* src, size_t compressedSize); +size_t ZSTDv02_findFrameCompressedSize(const void* src, size_t compressedSize); /** ZSTDv02_isError() : tells if the result of ZSTDv02_decompress() is an error diff --git a/lib/legacy/zstd_v03.c b/lib/legacy/zstd_v03.c index 98b93c49..ef654931 100644 --- a/lib/legacy/zstd_v03.c +++ b/lib/legacy/zstd_v03.c @@ -3019,7 +3019,7 @@ static size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, siz return ZSTD_decompressDCtx(&ctx, dst, maxDstSize, src, srcSize); } -static size_t ZSTD_getFrameCompressedSize(const void* src, size_t srcSize) +static size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize) { const BYTE* ip = (const BYTE*)src; size_t remainingSize = srcSize; @@ -3165,9 +3165,9 @@ size_t ZSTDv03_decompress( void* dst, size_t maxOriginalSize, return ZSTD_decompress(dst, maxOriginalSize, src, compressedSize); } -size_t ZSTDv03_getFrameCompressedSize(const void* src, size_t srcSize) +size_t ZSTDv03_findFrameCompressedSize(const void* src, size_t srcSize) { - return ZSTD_getFrameCompressedSize(src, srcSize); + return ZSTD_findFrameCompressedSize(src, srcSize); } ZSTDv03_Dctx* ZSTDv03_createDCtx(void) diff --git a/lib/legacy/zstd_v03.h b/lib/legacy/zstd_v03.h index 46969410..07f7597b 100644 --- a/lib/legacy/zstd_v03.h +++ b/lib/legacy/zstd_v03.h @@ -40,7 +40,7 @@ ZSTDv03_getFrameSrcSize() : get the source length of a ZSTD frame compliant with return : the number of bytes that would be read to decompress this frame or an errorCode if it fails (which can be tested using ZSTDv03_isError()) */ -size_t ZSTDv03_getFrameCompressedSize(const void* src, size_t compressedSize); +size_t ZSTDv03_findFrameCompressedSize(const void* src, size_t compressedSize); /** ZSTDv03_isError() : tells if the result of ZSTDv03_decompress() is an error diff --git a/lib/legacy/zstd_v04.c b/lib/legacy/zstd_v04.c index 8c929b05..09040e68 100644 --- a/lib/legacy/zstd_v04.c +++ b/lib/legacy/zstd_v04.c @@ -3326,7 +3326,7 @@ static size_t ZSTD_decompress_usingDict(ZSTD_DCtx* ctx, return op-ostart; } -static size_t ZSTD_getFrameCompressedSize(const void* src, size_t srcSize) +static size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize) { const BYTE* ip = (const BYTE*)src; size_t remainingSize = srcSize; @@ -3782,9 +3782,9 @@ size_t ZSTDv04_decompress(void* dst, size_t maxDstSize, const void* src, size_t #endif } -size_t ZSTDv04_getFrameCompressedSize(const void* src, size_t srcSize) +size_t ZSTDv04_findFrameCompressedSize(const void* src, size_t srcSize) { - return ZSTD_getFrameCompressedSize(src, srcSize); + return ZSTD_findFrameCompressedSize(src, srcSize); } size_t ZSTDv04_resetDCtx(ZSTDv04_Dctx* dctx) { return ZSTD_resetDCtx(dctx); } diff --git a/lib/legacy/zstd_v04.h b/lib/legacy/zstd_v04.h index bcef1fe9..1b5439d3 100644 --- a/lib/legacy/zstd_v04.h +++ b/lib/legacy/zstd_v04.h @@ -40,7 +40,7 @@ ZSTDv04_getFrameSrcSize() : get the source length of a ZSTD frame compliant with return : the number of bytes that would be read to decompress this frame or an errorCode if it fails (which can be tested using ZSTDv04_isError()) */ -size_t ZSTDv04_getFrameCompressedSize(const void* src, size_t compressedSize); +size_t ZSTDv04_findFrameCompressedSize(const void* src, size_t compressedSize); /** ZSTDv04_isError() : tells if the result of ZSTDv04_decompress() is an error diff --git a/lib/legacy/zstd_v05.c b/lib/legacy/zstd_v05.c index 9689b170..a6f5f5db 100644 --- a/lib/legacy/zstd_v05.c +++ b/lib/legacy/zstd_v05.c @@ -3583,7 +3583,7 @@ size_t ZSTDv05_decompress(void* dst, size_t maxDstSize, const void* src, size_t #endif } -size_t ZSTDv05_getFrameCompressedSize(const void *src, size_t srcSize) +size_t ZSTDv05_findFrameCompressedSize(const void *src, size_t srcSize) { const BYTE* ip = (const BYTE*)src; size_t remainingSize = srcSize; diff --git a/lib/legacy/zstd_v05.h b/lib/legacy/zstd_v05.h index 157dbc57..8ce662fd 100644 --- a/lib/legacy/zstd_v05.h +++ b/lib/legacy/zstd_v05.h @@ -38,7 +38,7 @@ ZSTDv05_getFrameSrcSize() : get the source length of a ZSTD frame return : the number of bytes that would be read to decompress this frame or an errorCode if it fails (which can be tested using ZSTDv05_isError()) */ -size_t ZSTDv05_getFrameCompressedSize(const void* src, size_t compressedSize); +size_t ZSTDv05_findFrameCompressedSize(const void* src, size_t compressedSize); /* ************************************* * Helper functions diff --git a/lib/legacy/zstd_v06.c b/lib/legacy/zstd_v06.c index f586db22..a4258b67 100644 --- a/lib/legacy/zstd_v06.c +++ b/lib/legacy/zstd_v06.c @@ -3729,7 +3729,7 @@ size_t ZSTDv06_decompress(void* dst, size_t dstCapacity, const void* src, size_t #endif } -size_t ZSTDv06_getFrameCompressedSize(const void* src, size_t srcSize) +size_t ZSTDv06_findFrameCompressedSize(const void* src, size_t srcSize) { const BYTE* ip = (const BYTE*)src; size_t remainingSize = srcSize; diff --git a/lib/legacy/zstd_v06.h b/lib/legacy/zstd_v06.h index ef1feb2f..10c9c772 100644 --- a/lib/legacy/zstd_v06.h +++ b/lib/legacy/zstd_v06.h @@ -47,7 +47,7 @@ ZSTDv06_getFrameSrcSize() : get the source length of a ZSTD frame return : the number of bytes that would be read to decompress this frame or an errorCode if it fails (which can be tested using ZSTDv06_isError()) */ -size_t ZSTDv06_getFrameCompressedSize(const void* src, size_t compressedSize); +size_t ZSTDv06_findFrameCompressedSize(const void* src, size_t compressedSize); /* ************************************* * Helper functions diff --git a/lib/legacy/zstd_v07.c b/lib/legacy/zstd_v07.c index 07099d5a..e67916b3 100644 --- a/lib/legacy/zstd_v07.c +++ b/lib/legacy/zstd_v07.c @@ -3968,7 +3968,7 @@ size_t ZSTDv07_decompress(void* dst, size_t dstCapacity, const void* src, size_t #endif } -size_t ZSTDv07_getFrameCompressedSize(const void* src, size_t srcSize) +size_t ZSTDv07_findFrameCompressedSize(const void* src, size_t srcSize) { const BYTE* ip = (const BYTE*)src; size_t remainingSize = srcSize; diff --git a/lib/legacy/zstd_v07.h b/lib/legacy/zstd_v07.h index a79cbb88..cc95c661 100644 --- a/lib/legacy/zstd_v07.h +++ b/lib/legacy/zstd_v07.h @@ -54,7 +54,7 @@ ZSTDv07_getFrameSrcSize() : get the source length of a ZSTD frame return : the number of bytes that would be read to decompress this frame or an errorCode if it fails (which can be tested using ZSTDv07_isError()) */ -size_t ZSTDv07_getFrameCompressedSize(const void* src, size_t compressedSize); +size_t ZSTDv07_findFrameCompressedSize(const void* src, size_t compressedSize); /*====== Helper functions ======*/ ZSTDLIBv07_API unsigned ZSTDv07_isError(size_t code); /*!< tells if a `size_t` function result is an error code */ diff --git a/lib/zstd.h b/lib/zstd.h index c0a1c7d1..9820b537 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -400,12 +400,12 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v * Compressed size functions ***************************************/ -/*! ZSTD_getFrameCompressedSize() : +/*! ZSTD_findFrameCompressedSize() : * `src` should point to the start of a ZSTD encoded frame * `srcSize` must be at least as large as the frame * @return : the compressed size of the frame pointed to by `src`, suitable to pass to * `ZSTD_decompress` or similar, or an error code if given invalid input. */ -ZSTDLIB_API size_t ZSTD_getFrameCompressedSize(const void* src, size_t srcSize); +ZSTDLIB_API size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize); /*************************************** * Decompressed size functions diff --git a/tests/fuzzer.c b/tests/fuzzer.c index 590bcb39..03399852 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -545,6 +545,13 @@ static int basicUnitTests(U32 seed, double compressibility) if (r != _3BYTESTESTLENGTH) goto _output_error; } DISPLAYLEVEL(4, "OK \n"); + /* findFrameCompressedSize on skippable frames */ + DISPLAYLEVEL(4, "test%3i : frame compressed size of skippable frame : ", testNb++); + { const char* frame = "\x50\x2a\x4d\x18\x05\x0\x0\0abcde"; + size_t const frameSrcSize = 13; + if (ZSTD_findFrameCompressedSize(frame, frameSrcSize) != frameSrcSize) goto _output_error; } + DISPLAYLEVEL(4, "OK \n"); + /* error string tests */ DISPLAYLEVEL(4, "test%3i : testing ZSTD error code strings : ", testNb++); if (strcmp("No error detected", ZSTD_getErrorName((ZSTD_ErrorCode)(0-ZSTD_error_no_error))) != 0) goto _output_error; diff --git a/tests/symbols.c b/tests/symbols.c index afdb0006..7dacfc05 100644 --- a/tests/symbols.c +++ b/tests/symbols.c @@ -16,6 +16,7 @@ static const void *symbols[] = { &ZSTD_decompress, &ZSTD_getDecompressedSize, &ZSTD_findDecompressedSize, + &ZSTD_findFrameCompressedSize, &ZSTD_getFrameContentSize, &ZSTD_maxCLevel, &ZSTD_compressBound,