diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 4c47930c..b6a3865c 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -193,7 +193,24 @@ static void ZSTD_refDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx) * Decompression section ***************************************************************/ -/* See compression format details in : doc/zstd_compression_format.md */ +/*! ZSTD_isFrame() : + * Tells if the content of `buffer` starts with a valid Frame Identifier. + * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. + * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. + * Note 3 : Skippable Frame Identifiers are considered valid. */ +unsigned ZSTD_isFrame(const void* buffer, size_t size) +{ + if (size < 4) return 0; + { U32 const magic = MEM_readLE32(buffer); + if (magic == ZSTD_MAGICNUMBER) return 1; + if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) return 1; + } +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) + if (ZSTD_isLegacy(buffer, size)) return 1; +#endif + return 0; +} + /** ZSTD_frameHeaderSize() : * srcSize must be >= ZSTD_frameHeaderSize_prefix. diff --git a/lib/zstd.h b/lib/zstd.h index ea5caf14..c18fd0d3 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -433,6 +433,13 @@ ZSTDLIB_API size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx, /*--- Advanced decompression functions ---*/ +/*! ZSTD_isFrame() : + * Tells if the content of `buffer` starts with a valid Frame Identifier. + * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. + * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. + * Note 3 : Skippable Frame Identifiers are considered valid. */ +ZSTDLIB_API unsigned ZSTD_isFrame(const void* buffer, size_t size); + /*! ZSTD_estimateDCtxSize() : * Gives the potential amount of memory allocated to create a ZSTD_DCtx */ ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void); diff --git a/programs/fileio.c b/programs/fileio.c index c4c308e0..fe321015 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -8,16 +8,6 @@ */ -/* ************************************* - * Tuning options - ***************************************/ -#ifndef ZSTD_LEGACY_SUPPORT -/* LEGACY_SUPPORT : - * decompressor can decode older formats (starting from zstd 0.1+) */ -# define ZSTD_LEGACY_SUPPORT 1 -#endif - - /* ************************************* * Compiler Options ***************************************/ @@ -29,6 +19,7 @@ # define _POSIX_SOURCE 1 /* disable %llu warnings with MinGW on Windows */ #endif + /*-************************************* * Includes ***************************************/ @@ -44,10 +35,6 @@ #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_magicNumber, ZSTD_frameHeaderSize_max */ #include "zstd.h" -#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1) -# include "zstd_legacy.h" /* ZSTD_isLegacy */ -#endif - /*-************************************* * OS-specific Includes @@ -634,7 +621,7 @@ unsigned long long FIO_decompressFrame(dRess_t ress, @return : 0 (no error) */ static unsigned FIO_passThrough(FILE* foutput, FILE* finput, void* buffer, size_t bufferSize) { - size_t const blockSize = MIN (64 KB, bufferSize); + size_t const blockSize = MIN(64 KB, bufferSize); size_t readFromInput = 1; unsigned storedSkips = 0; @@ -682,21 +669,16 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName) } readSomething = 1; /* there is at least >= 4 bytes in srcFile */ if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ - { U32 const magic = MEM_readLE32(ress.srcBuffer); - if (((magic & 0xFFFFFFF0U) != ZSTD_MAGIC_SKIPPABLE_START) & (magic != ZSTD_MAGICNUMBER) -#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) - & (!ZSTD_isLegacy(ress.srcBuffer, toRead)) -#endif - ) { - if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */ - unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); - if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ - return result; - } else { - DISPLAYLEVEL(1, "zstd: %s: not in zstd format \n", srcFileName); - fclose(srcFile); - return 1; - } } } + if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { + if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */ + unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize); + if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ + return result; + } else { + DISPLAYLEVEL(1, "zstd: %s: not in zstd format \n", srcFileName); + fclose(srcFile); + return 1; + } } filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead); }