From ecf90ca24b7031444133bc236a51683bd059dfc7 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 13 Feb 2017 18:27:34 -0800 Subject: [PATCH 01/23] [zstdmt] Fix MSAN failure with ZSTD_p_forceWindow Reproduction steps: ``` make zstreamtest CC=clang CFLAGS="-O3 -g -fsanitize=memory -fsanitize-memory-track-origins" ./zstreamtest -vv -t4178 -i4178 -s4531 ``` How to get to the error in gdb (may be a more efficient way): * 2 breaks at zstd_compress.c:2418 -- in ZSTD_compressContinue_internal() * 2 breaks at zstd_compress.c:2276 -- in ZSTD_compressBlock_internal() * 1 break at zstd_compress.c:1547 Why the error occurred: When `zc->forceWindow == 1`, after calling `ZSTD_loadDictionaryContent()` we have `zc->loadedDictEnd == zc->nextToUpdate == 0`. But, we've really loaded up to `iend` into the dictionary. Then in `ZSTD_compressBlock_internal()` we see that `current > zc->nextToUpdate + 384`, so we load the last 192 bytes a second time. In this case the bytes we are loading are a block of all 0s, starting in the previous block. So when we are loading the last 192 bytes, we find a `match` in the future, 183 bytes beyond `ip`. Since the block is all 0s, the match extends to the end of the block. But in `ZSTD_count()` we only check that `pIn < pInLoopLimit`, but since `pMatch > pIn`, `pMatch` eventually points past the end of the buffer, causing the MSAN failure. The fix: The line changed sets sets `zc->nextToUpdate` to the end of the dictionary. This is the behavior that existed before `ZSTD_p_forceWindow` was introduced. This fixes the exposing test case. Since the code doesn't fail without `zc->forceWindow`, it makes sense that this works. I've run the command `./zstreamtest -T2mn` 64 times without failures. CI should also verify nothing obvious broke. --- lib/compress/zstd_compress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 765c8e34d..91e81d9c2 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2512,7 +2512,7 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t return ERROR(GENERIC); /* strategy doesn't exist; impossible */ } - zc->nextToUpdate = zc->loadedDictEnd; + zc->nextToUpdate = (U32)(iend - zc->base); return 0; } From 74b81ada256f45b0ea69f50c3b9b3918faacc91a Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Tue, 14 Feb 2017 10:08:14 -0800 Subject: [PATCH 02/23] Don't run test-pool with QEMU > make test -n ... ./pool > make test -n QEMU_SYS=valgrind ... ./legacy # ./pool not run --- tests/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Makefile b/tests/Makefile index f64be1695..2b58c949c 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -231,7 +231,7 @@ zstd-playTests: datagen ZSTD="$(QEMU_SYS) $(ZSTD)" ./playTests.sh $(ZSTDRTTEST) test: test-zstd test-fullbench test-fuzzer test-zstream test-invalidDictionaries test-legacy -ifneq ($(QEMU_SYS),qemu-ppc64-static) +ifeq ($(QEMU_SYS),) test: test-pool endif From 9b5a1e9d973dca9d4cc312c8dc6e441d4ab94dfd Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Tue, 14 Feb 2017 20:06:41 +0100 Subject: [PATCH 03/23] added circle.yml --- circle.yml | 42 ++++++++++++++++++++++++++++++++++++++++++ tests/Makefile | 2 +- 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 circle.yml diff --git a/circle.yml b/circle.yml new file mode 100644 index 000000000..c189d3b65 --- /dev/null +++ b/circle.yml @@ -0,0 +1,42 @@ +dependencies: + override: + - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; sudo apt-get -y -qq update + - sudo apt-get -y install qemu-system-ppc qemu-user-static gcc-powerpc-linux-gnu + - sudo apt-get -y install qemu-system-arm gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross + - sudo apt-get -y install libc6-dev-i386 clang gcc-5 gcc-6 valgrind + +test: + override: + # Tests compilers and C standards + - clang -v; make clangtest && make clean + - g++ -v; make gpptest && make clean + - gcc -v; make gnu90test && make clean + - gcc -v; make c99test && make clean + - gcc -v; make gnu99test && make clean + - gcc-5 -v; make gcc5test && make clean + - gcc-6 -v; make gcc6test && make clean + # Shorter tests + - make cmaketest && make clean + - make zlibwrapper && make clean + - make -C lib all && make clean + - make -C tests dll && make clean + - make -C tests test-symbols && make clean + - make -C tests test-zstd-nolegacy && make clean + - make -C tests test-longmatch && make clean + - pyenv global 3.4.4; make -C tests versionsTest && make clean + - make -C programs zstd-small zstd-decompress zstd-compress && make -C programs clean + - make travis-install && make clean + # Longer tests + - make test && make clean + - gcc -v; make -C tests test32 MOREFLAGS="-I/usr/include/x86_64-linux-gnu" && make clean + - make usan && make clean + - make asan && make clean + - make asan32 && make clean + # Valgrind tests + - CFLAGS="-O1 -g" make -C zlibWrapper valgrindTest && make clean + - make -C tests valgrindTest && make clean + # ARM, AArch64, PowerPC, PowerPC64 tests + - make ppctest && make clean + - make ppc64test && make clean + - make armtest && make clean + - make aarch64test && make clean diff --git a/tests/Makefile b/tests/Makefile index f64be1695..17b0146e2 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -184,7 +184,7 @@ clean: fuzzer-dll$(EXT) zstreamtest-dll$(EXT) zbufftest-dll$(EXT)\ zstreamtest$(EXT) zstreamtest32$(EXT) \ datagen$(EXT) paramgrill$(EXT) roundTripCrash$(EXT) longmatch$(EXT) \ - symbols$(EXT) invalidDictionaries$(EXT) pool$(EXT) + symbols$(EXT) invalidDictionaries$(EXT) legacy$(EXT) pool$(EXT) @echo Cleaning completed From 90e5412a4e2ea9c059a37b5d71ec5bb4105361ad Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Tue, 14 Feb 2017 23:30:23 +0100 Subject: [PATCH 04/23] added -I/usr/include/x86_64-linux-gnu for asan32 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d86db7cb3..3ce12e67d 100644 --- a/Makefile +++ b/Makefile @@ -138,7 +138,7 @@ msan: clean $(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=memory -fno-omit-frame-pointer" # datagen.c fails this test for no obvious reason asan32: clean - $(MAKE) -C $(TESTDIR) test32 CC=clang MOREFLAGS="-g -fsanitize=address" + $(MAKE) -C $(TESTDIR) test32 CC=clang MOREFLAGS="-g -fsanitize=address -I/usr/include/x86_64-linux-gnu" uasan: clean $(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address -fsanitize=undefined" From 4596037042851fbcf3800fe33fa9424ae52e99d0 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 15 Feb 2017 12:00:03 -0800 Subject: [PATCH 05/23] updated fse version feature minor refactoring (removing FSE_abs()) also : fix a few minor issues recently introduced in examples --- examples/dictionary_decompression.c | 1 + examples/simple_compression.c | 6 +-- examples/simple_decompression.c | 21 +++++---- lib/common/entropy_common.c | 24 +++++----- lib/common/fse.h | 70 ++++++++++++++++++++--------- lib/compress/fse_compress.c | 10 ++--- 6 files changed, 80 insertions(+), 52 deletions(-) diff --git a/examples/dictionary_decompression.c b/examples/dictionary_decompression.c index 2aa71b268..75183505d 100644 --- a/examples/dictionary_decompression.c +++ b/examples/dictionary_decompression.c @@ -13,6 +13,7 @@ #include // strerror #include // errno #include // stat +#define ZSTD_STATIC_LINKING_ONLY // ZSTD_findDecompressedSize #include // presumes zstd library is installed diff --git a/examples/simple_compression.c b/examples/simple_compression.c index 2aab48f47..9d448712e 100644 --- a/examples/simple_compression.c +++ b/examples/simple_compression.c @@ -102,7 +102,7 @@ static void compress_orDie(const char* fname, const char* oname) } -static const char* createOutFilename_orDie(const char* filename) +static char* createOutFilename_orDie(const char* filename) { size_t const inL = strlen(filename); size_t const outL = inL + 5; @@ -110,7 +110,7 @@ static const char* createOutFilename_orDie(const char* filename) memset(outSpace, 0, outL); strcat(outSpace, filename); strcat(outSpace, ".zst"); - return (const char*)outSpace; + return (char*)outSpace; } int main(int argc, const char** argv) @@ -125,7 +125,7 @@ int main(int argc, const char** argv) return 1; } - const char* const outFilename = createOutFilename_orDie(inFilename); + char* const outFilename = createOutFilename_orDie(inFilename); compress_orDie(inFilename, outFilename); free(outFilename); return 0; diff --git a/examples/simple_decompression.c b/examples/simple_decompression.c index 3a75e164c..09b27baa6 100644 --- a/examples/simple_decompression.c +++ b/examples/simple_decompression.c @@ -6,17 +6,16 @@ * LICENSE-examples file in the root directory of this source tree. */ - - #include // malloc, exit #include // printf #include // strerror #include // errno #include // stat +#define ZSTD_STATIC_LINKING_ONLY // ZSTD_findDecompressedSize #include // presumes zstd library is installed -static off_t fsize_X(const char *filename) +static off_t fsize_orDie(const char *filename) { struct stat st; if (stat(filename, &st) == 0) return st.st_size; @@ -25,7 +24,7 @@ static off_t fsize_X(const char *filename) exit(1); } -static FILE* fopen_X(const char *filename, const char *instruction) +static FILE* fopen_orDie(const char *filename, const char *instruction) { FILE* const inFile = fopen(filename, instruction); if (inFile) return inFile; @@ -34,7 +33,7 @@ static FILE* fopen_X(const char *filename, const char *instruction) exit(2); } -static void* malloc_X(size_t size) +static void* malloc_orDie(size_t size) { void* const buff = malloc(size); if (buff) return buff; @@ -43,11 +42,11 @@ static void* malloc_X(size_t size) exit(3); } -static void* loadFile_X(const char* fileName, size_t* size) +static void* loadFile_orDie(const char* fileName, size_t* size) { - off_t const buffSize = fsize_X(fileName); - FILE* const inFile = fopen_X(fileName, "rb"); - void* const buffer = malloc_X(buffSize); + off_t const buffSize = fsize_orDie(fileName); + FILE* const inFile = fopen_orDie(fileName, "rb"); + void* const buffer = malloc_orDie(buffSize); size_t const readSize = fread(buffer, 1, buffSize, inFile); if (readSize != (size_t)buffSize) { printf("fread: %s : %s \n", fileName, strerror(errno)); @@ -62,13 +61,13 @@ static void* loadFile_X(const char* fileName, size_t* size) static void decompress(const char* fname) { size_t cSize; - void* const cBuff = loadFile_X(fname, &cSize); + void* const cBuff = loadFile_orDie(fname, &cSize); unsigned long long const rSize = ZSTD_findDecompressedSize(cBuff, cSize); if (rSize==0) { printf("%s : original size unknown. Use streaming decompression instead. \n", fname); exit(5); } - void* const rBuff = malloc_X((size_t)rSize); + void* const rBuff = malloc_orDie((size_t)rSize); size_t const dSize = ZSTD_decompress(rBuff, rSize, cBuff, cSize); diff --git a/lib/common/entropy_common.c b/lib/common/entropy_common.c index 83fd97154..72bc398da 100644 --- a/lib/common/entropy_common.c +++ b/lib/common/entropy_common.c @@ -43,6 +43,12 @@ #include "huf.h" +/*-**************************************** +* Version +******************************************/ +unsigned FSE_versionNumber(void) { return FSE_VERSION_NUMBER; } + + /*-**************************************** * FSE Error Management ******************************************/ @@ -62,8 +68,6 @@ const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); } /*-************************************************************** * FSE NCount encoding-decoding ****************************************************************/ -static short FSE_abs(short a) { return (short)(a<0 ? -a : a); } - size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, const void* headerBuffer, size_t hbSize) { @@ -117,21 +121,21 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t } else { bitStream >>= 2; } } - { short const max = (short)((2*threshold-1)-remaining); - short count; + { int const max = (2*threshold-1) - remaining; + int count; if ((bitStream & (threshold-1)) < (U32)max) { - count = (short)(bitStream & (threshold-1)); - bitCount += nbBits-1; + count = bitStream & (threshold-1); + bitCount += nbBits-1; } else { - count = (short)(bitStream & (2*threshold-1)); + count = bitStream & (2*threshold-1); if (count >= threshold) count -= max; - bitCount += nbBits; + bitCount += nbBits; } count--; /* extra accuracy */ - remaining -= FSE_abs(count); - normalizedCounter[charnum++] = count; + remaining -= count < 0 ? -count : count; /* -1 means +1 */ + normalizedCounter[charnum++] = (short)count; previous0 = !count; while (remaining < threshold) { nbBits--; diff --git a/lib/common/fse.h b/lib/common/fse.h index 8b07d184d..baac39032 100644 --- a/lib/common/fse.h +++ b/lib/common/fse.h @@ -45,6 +45,32 @@ extern "C" { #include /* size_t, ptrdiff_t */ +/*-***************************************** +* FSE_PUBLIC_API : control library symbols visibility +******************************************/ +#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4) +# define FSE_PUBLIC_API __attribute__ ((visibility ("default"))) +#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) /* Visual expected */ +# define FSE_PUBLIC_API __declspec(dllexport) +#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1) +# define FSE_PUBLIC_API __declspec(dllimport) /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +#else +# define FSE_PUBLIC_API +#endif + +/*------ Version ------*/ +#define FSE_VERSION_MAJOR 0 +#define FSE_VERSION_MINOR 9 +#define FSE_VERSION_RELEASE 0 + +#define FSE_LIB_VERSION FSE_VERSION_MAJOR.FSE_VERSION_MINOR.FSE_VERSION_RELEASE +#define FSE_QUOTE(str) #str +#define FSE_EXPAND_AND_QUOTE(str) FSE_QUOTE(str) +#define FSE_VERSION_STRING FSE_EXPAND_AND_QUOTE(FSE_LIB_VERSION) + +#define FSE_VERSION_NUMBER (FSE_VERSION_MAJOR *100*100 + FSE_VERSION_MINOR *100 + FSE_VERSION_RELEASE) +FSE_PUBLIC_API unsigned FSE_versionNumber(void); /**< library version number; to be used when checking dll version */ + /*-**************************************** * FSE simple functions ******************************************/ @@ -56,8 +82,8 @@ extern "C" { if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression instead. if FSE_isError(return), compression failed (more details using FSE_getErrorName()) */ -size_t FSE_compress(void* dst, size_t dstCapacity, - const void* src, size_t srcSize); +FSE_PUBLIC_API size_t FSE_compress(void* dst, size_t dstCapacity, + const void* src, size_t srcSize); /*! FSE_decompress(): Decompress FSE data from buffer 'cSrc', of size 'cSrcSize', @@ -69,18 +95,18 @@ size_t FSE_compress(void* dst, size_t dstCapacity, Why ? : making this distinction requires a header. Header management is intentionally delegated to the user layer, which can better manage special cases. */ -size_t FSE_decompress(void* dst, size_t dstCapacity, - const void* cSrc, size_t cSrcSize); +FSE_PUBLIC_API size_t FSE_decompress(void* dst, size_t dstCapacity, + const void* cSrc, size_t cSrcSize); /*-***************************************** * Tool functions ******************************************/ -size_t FSE_compressBound(size_t size); /* maximum compressed size */ +FSE_PUBLIC_API size_t FSE_compressBound(size_t size); /* maximum compressed size */ /* Error Management */ -unsigned FSE_isError(size_t code); /* tells if a return value is an error code */ -const char* FSE_getErrorName(size_t code); /* provides error code string (useful for debugging) */ +FSE_PUBLIC_API unsigned FSE_isError(size_t code); /* tells if a return value is an error code */ +FSE_PUBLIC_API const char* FSE_getErrorName(size_t code); /* provides error code string (useful for debugging) */ /*-***************************************** @@ -94,7 +120,7 @@ const char* FSE_getErrorName(size_t code); /* provides error code string (usef if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression. if FSE_isError(return), it's an error code. */ -size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); +FSE_PUBLIC_API size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); /*-***************************************** @@ -127,50 +153,50 @@ or to save and provide normalized distribution using external method. @return : the count of the most frequent symbol (which is not identified). if return == srcSize, there is only one symbol. Can also return an error code, which can be tested with FSE_isError(). */ -size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize); +FSE_PUBLIC_API size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize); /*! FSE_optimalTableLog(): dynamically downsize 'tableLog' when conditions are met. It saves CPU time, by using smaller tables, while preserving or even improving compression ratio. @return : recommended tableLog (necessarily <= 'maxTableLog') */ -unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); +FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); /*! FSE_normalizeCount(): normalize counts so that sum(count[]) == Power_of_2 (2^tableLog) 'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1). @return : tableLog, or an errorCode, which can be tested using FSE_isError() */ -size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog, const unsigned* count, size_t srcSize, unsigned maxSymbolValue); +FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog, const unsigned* count, size_t srcSize, unsigned maxSymbolValue); /*! FSE_NCountWriteBound(): Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'. Typically useful for allocation purpose. */ -size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog); +FSE_PUBLIC_API size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog); /*! FSE_writeNCount(): Compactly save 'normalizedCounter' into 'buffer'. @return : size of the compressed table, or an errorCode, which can be tested using FSE_isError(). */ -size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); +FSE_PUBLIC_API size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); /*! Constructor and Destructor of FSE_CTable. Note that FSE_CTable size depends on 'tableLog' and 'maxSymbolValue' */ typedef unsigned FSE_CTable; /* don't allocate that. It's only meant to be more restrictive than void* */ -FSE_CTable* FSE_createCTable (unsigned tableLog, unsigned maxSymbolValue); -void FSE_freeCTable (FSE_CTable* ct); +FSE_PUBLIC_API FSE_CTable* FSE_createCTable (unsigned tableLog, unsigned maxSymbolValue); +FSE_PUBLIC_API void FSE_freeCTable (FSE_CTable* ct); /*! FSE_buildCTable(): Builds `ct`, which must be already allocated, using FSE_createCTable(). @return : 0, or an errorCode, which can be tested using FSE_isError() */ -size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); +FSE_PUBLIC_API size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); /*! FSE_compress_usingCTable(): Compress `src` using `ct` into `dst` which must be already allocated. @return : size of compressed data (<= `dstCapacity`), or 0 if compressed data could not fit into `dst`, or an errorCode, which can be tested using FSE_isError() */ -size_t FSE_compress_usingCTable (void* dst, size_t dstCapacity, const void* src, size_t srcSize, const FSE_CTable* ct); +FSE_PUBLIC_API size_t FSE_compress_usingCTable (void* dst, size_t dstCapacity, const void* src, size_t srcSize, const FSE_CTable* ct); /*! Tutorial : @@ -223,25 +249,25 @@ If there is an error, the function will return an ErrorCode (which can be tested @return : size read from 'rBuffer', or an errorCode, which can be tested using FSE_isError(). maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */ -size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, const void* rBuffer, size_t rBuffSize); +FSE_PUBLIC_API size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, const void* rBuffer, size_t rBuffSize); /*! Constructor and Destructor of FSE_DTable. Note that its size depends on 'tableLog' */ typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */ -FSE_DTable* FSE_createDTable(unsigned tableLog); -void FSE_freeDTable(FSE_DTable* dt); +FSE_PUBLIC_API FSE_DTable* FSE_createDTable(unsigned tableLog); +FSE_PUBLIC_API void FSE_freeDTable(FSE_DTable* dt); /*! FSE_buildDTable(): Builds 'dt', which must be already allocated, using FSE_createDTable(). return : 0, or an errorCode, which can be tested using FSE_isError() */ -size_t FSE_buildDTable (FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); +FSE_PUBLIC_API size_t FSE_buildDTable (FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); /*! FSE_decompress_usingDTable(): Decompress compressed source `cSrc` of size `cSrcSize` using `dt` into `dst` which must be already allocated. @return : size of regenerated data (necessarily <= `dstCapacity`), or an errorCode, which can be tested using FSE_isError() */ -size_t FSE_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSE_DTable* dt); +FSE_PUBLIC_API size_t FSE_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSE_DTable* dt); /*! Tutorial : diff --git a/lib/compress/fse_compress.c b/lib/compress/fse_compress.c index 6627facfe..337b7a6ff 100644 --- a/lib/compress/fse_compress.c +++ b/lib/compress/fse_compress.c @@ -201,8 +201,6 @@ size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog) return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */ } -static short FSE_abs(short a) { return (short)(a<0 ? -a : a); } - static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, unsigned writeIsSafe) @@ -258,16 +256,16 @@ static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize, bitStream >>= 16; bitCount -= 16; } } - { short count = normalizedCounter[charnum++]; - const short max = (short)((2*threshold-1)-remaining); - remaining -= FSE_abs(count); - if (remaining<1) return ERROR(GENERIC); + { int count = normalizedCounter[charnum++]; + int const max = (2*threshold-1)-remaining; + remaining -= count < 0 ? -count : count; count++; /* +1 for extra accuracy */ if (count>=threshold) count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */ bitStream += count << bitCount; bitCount += nbBits; bitCount -= (count>=1; } if (bitCount>16) { From 887eaa9e21d5a35614ed35e1cae0025e5f071fa8 Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Wed, 15 Feb 2017 16:43:45 -0800 Subject: [PATCH 06/23] Fix wildcopy overwriting data still in window --- lib/decompress/zstd_decompress.c | 2 +- lib/legacy/zstd_v06.c | 2 +- lib/legacy/zstd_v07.c | 2 +- tests/zstreamtest.c | 24 ++++++++++++++++++++++++ 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index b8670315c..52949be99 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -2260,7 +2260,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB /* Adapt buffer sizes to frame header instructions */ { size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX); - size_t const neededOutSize = zds->fParams.windowSize + blockSize; + size_t const neededOutSize = zds->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH; zds->blockSize = blockSize; if (zds->inBuffSize < blockSize) { ZSTD_free(zds->inBuff, zds->customMem); diff --git a/lib/legacy/zstd_v06.c b/lib/legacy/zstd_v06.c index 4c8f06823..1d65e8f7d 100644 --- a/lib/legacy/zstd_v06.c +++ b/lib/legacy/zstd_v06.c @@ -4108,7 +4108,7 @@ size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* zbd, zbd->inBuff = (char*)malloc(blockSize); if (zbd->inBuff == NULL) return ERROR(memory_allocation); } - { size_t const neededOutSize = ((size_t)1 << zbd->fParams.windowLog) + blockSize; + { size_t const neededOutSize = ((size_t)1 << zbd->fParams.windowLog) + blockSize + WILDCOPY_OVERLENGTH; if (zbd->outBuffSize < neededOutSize) { free(zbd->outBuff); zbd->outBuffSize = neededOutSize; diff --git a/lib/legacy/zstd_v07.c b/lib/legacy/zstd_v07.c index 441e4bc39..c93a217f4 100644 --- a/lib/legacy/zstd_v07.c +++ b/lib/legacy/zstd_v07.c @@ -4483,7 +4483,7 @@ size_t ZBUFFv07_decompressContinue(ZBUFFv07_DCtx* zbd, zbd->inBuff = (char*)zbd->customMem.customAlloc(zbd->customMem.opaque, blockSize); if (zbd->inBuff == NULL) return ERROR(memory_allocation); } - { size_t const neededOutSize = zbd->fParams.windowSize + blockSize; + { size_t const neededOutSize = zbd->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH; if (zbd->outBuffSize < neededOutSize) { zbd->customMem.customFree(zbd->customMem.opaque, zbd->outBuff); zbd->outBuffSize = neededOutSize; diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index 5680d27c1..323a087ce 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -467,6 +467,30 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo if (ZSTD_findDecompressedSize(compressedBuffer, cSize) != ZSTD_CONTENTSIZE_UNKNOWN) goto _output_error; DISPLAYLEVEL(3, "OK \n"); + /* Overlen overwriting window data bug */ + DISPLAYLEVEL(3, "test%3i : wildcopy doesn't overwrite potential match data : ", testNb++); + { const char* testCase = + "\x28\xB5\x2F\xFD\x04\x00\x4C\x00\x00\x10\x61\x61\x01\x00\xFC\x2A" + "\xC0\x02\x44\x00\x00\x08\x62\x01\x00\xFC\x2A\x10\x02\x00\x00\x00" + "\x4D\x00\x00\x00\x02\x40\x00\x01\x64\xE0\xE6\x19\xC1\xFB\x54\x9E"; + ZSTD_DStream* zds = ZSTD_createDStream(); + + ZSTD_initDStream(zds); + inBuff.src = testCase; + inBuff.size = 48; + inBuff.pos = 0; + outBuff.dst = decodedBuffer; + outBuff.size = CNBufferSize; + outBuff.pos = 0; + + while (inBuff.pos < inBuff.size) { + size_t const r = ZSTD_decompressStream(zds, &outBuff, &inBuff); + /* Bug will cause checksum to fail */ + if (ZSTD_isError(r)) goto _output_error; + } + } + DISPLAYLEVEL(3, "OK \n"); + _end: FUZ_freeDictionary(dictionary); ZSTD_freeCStream(zc); From e0d2a146d1ef7d5d357a3fabe2db5e6c06012784 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 16 Feb 2017 12:29:08 +0100 Subject: [PATCH 07/23] .travis.yml: detect "$TRAVIS_EVENT_TYPE" = "cron" --- .travis.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 885e4517a..b87d7d476 100644 --- a/.travis.yml +++ b/.travis.yml @@ -169,7 +169,13 @@ matrix: script: - JOB_NUMBER=$(echo $TRAVIS_JOB_NUMBER | sed -e 's:[0-9][0-9]*\.\(.*\):\1:') - # dev => normal tests; other feature branches => short tests (number > 11) - - if [ "$TRAVIS_PULL_REQUEST" = "true" ] || [ $JOB_NUMBER -gt 11 ] || [ "$TRAVIS_BRANCH" = "dev" ] && [ "$TRAVIS_BRANCH" != "master" ]; then sh -c "$Cmd"; fi - # master => long tests, as this is the final step towards a Release - - if [ "$TRAVIS_BRANCH" = "master" ]; then FUZZERTEST=-T10mn sh -c "$Cmd"; fi + + # cron & master => long tests, as this is the final step towards a Release + - if [ "$TRAVIS_EVENT_TYPE" = "cron" ] || [ "$TRAVIS_BRANCH" = "master" ]; then + FUZZERTEST=-T10mn sh -c "$Cmd" || travis_terminate 1; + else + # dev => normal tests; other feature branches => short tests (number > 11) + if [ "$TRAVIS_PULL_REQUEST" = "true" ] || [ $JOB_NUMBER -gt 11 ] || [ "$TRAVIS_BRANCH" = "dev" ]; then + sh -c "$Cmd" || travis_terminate 1; + fi + fi From b0511aeca541d4e274b33d58c379b1d793eef345 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 16 Feb 2017 12:33:25 +0100 Subject: [PATCH 08/23] fix travis.yml --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index b87d7d476..82b2b03bb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -170,11 +170,11 @@ matrix: script: - JOB_NUMBER=$(echo $TRAVIS_JOB_NUMBER | sed -e 's:[0-9][0-9]*\.\(.*\):\1:') - # cron & master => long tests, as this is the final step towards a Release + # cron & master => long tests, as this is the final step towards a Release + # dev => normal tests; other feature branches => short tests (number > 11) - if [ "$TRAVIS_EVENT_TYPE" = "cron" ] || [ "$TRAVIS_BRANCH" = "master" ]; then FUZZERTEST=-T10mn sh -c "$Cmd" || travis_terminate 1; else - # dev => normal tests; other feature branches => short tests (number > 11) if [ "$TRAVIS_PULL_REQUEST" = "true" ] || [ $JOB_NUMBER -gt 11 ] || [ "$TRAVIS_BRANCH" = "dev" ]; then sh -c "$Cmd" || travis_terminate 1; fi From f8a5749c224e678286de8da97e367617dfa661d3 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 16 Feb 2017 13:08:30 +0100 Subject: [PATCH 09/23] circle.yml: run only short tests --- circle.yml | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/circle.yml b/circle.yml index c189d3b65..2f531a91f 100644 --- a/circle.yml +++ b/circle.yml @@ -16,27 +16,31 @@ test: - gcc-5 -v; make gcc5test && make clean - gcc-6 -v; make gcc6test && make clean # Shorter tests - - make cmaketest && make clean - - make zlibwrapper && make clean - - make -C lib all && make clean - - make -C tests dll && make clean - - make -C tests test-symbols && make clean - - make -C tests test-zstd-nolegacy && make clean + - make cmaketest && make clean + - make -C lib all && make clean + - make -C tests dll && make clean + - make -C tests test-zstd && make clean + - make -C tests test-fullbench && make clean + - make -C tests test-fuzzer && make clean + - make -C tests test-zstream && make clean + - make -C tests test-invalidDictionaries && make clean + - make -C tests test-legacy && make clean + - make -C tests test-symbols && make clean - make -C tests test-longmatch && make clean - - pyenv global 3.4.4; make -C tests versionsTest && make clean - make -C programs zstd-small zstd-decompress zstd-compress && make -C programs clean - make travis-install && make clean # Longer tests - - make test && make clean - - gcc -v; make -C tests test32 MOREFLAGS="-I/usr/include/x86_64-linux-gnu" && make clean - - make usan && make clean - - make asan && make clean - - make asan32 && make clean + #- make -C tests test-zstd-nolegacy && make clean + #- pyenv global 3.4.4; make -C tests versionsTest && make clean + #- make zlibwrapper && make clean + #- gcc -v; make -C tests test32 MOREFLAGS="-I/usr/include/x86_64-linux-gnu" && make clean + #- make uasan && make clean + #- make asan32 && make clean # Valgrind tests - - CFLAGS="-O1 -g" make -C zlibWrapper valgrindTest && make clean - - make -C tests valgrindTest && make clean + #- CFLAGS="-O1 -g" make -C zlibWrapper valgrindTest && make clean + #- make -C tests valgrindTest && make clean # ARM, AArch64, PowerPC, PowerPC64 tests - - make ppctest && make clean - - make ppc64test && make clean - - make armtest && make clean - - make aarch64test && make clean + #- make ppctest && make clean + #- make ppc64test && make clean + #- make armtest && make clean + #- make aarch64test && make clean From 9e97a8a45a395481e30c9f7110245aa7a08dc0e1 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 16 Feb 2017 13:36:12 +0100 Subject: [PATCH 10/23] check $CIRCLE_NODE_INDEX --- circle.yml | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/circle.yml b/circle.yml index 2f531a91f..c04dd46b3 100644 --- a/circle.yml +++ b/circle.yml @@ -8,27 +8,29 @@ dependencies: test: override: # Tests compilers and C standards - - clang -v; make clangtest && make clean - - g++ -v; make gpptest && make clean - - gcc -v; make gnu90test && make clean - - gcc -v; make c99test && make clean - - gcc -v; make gnu99test && make clean - - gcc-5 -v; make gcc5test && make clean - - gcc-6 -v; make gcc6test && make clean + - [[ "$CIRCLE_NODE_INDEX" == "0" ]] && clang -v && make clangtest && make clean + parallel: true + #- g++ -v; make gpptest && make clean + #- gcc -v; make gnu90test && make clean + #- gcc -v; make c99test && make clean + #- gcc -v; make gnu99test && make clean + #- gcc-5 -v; make gcc5test && make clean + #- gcc-6 -v; make gcc6test && make clean # Shorter tests - - make cmaketest && make clean - - make -C lib all && make clean - - make -C tests dll && make clean - - make -C tests test-zstd && make clean - - make -C tests test-fullbench && make clean - - make -C tests test-fuzzer && make clean - - make -C tests test-zstream && make clean - - make -C tests test-invalidDictionaries && make clean - - make -C tests test-legacy && make clean - - make -C tests test-symbols && make clean - - make -C tests test-longmatch && make clean - - make -C programs zstd-small zstd-decompress zstd-compress && make -C programs clean - - make travis-install && make clean + - if [[ "$CIRCLE_NODE_TOTAL" < "2" ] || [ "$CIRCLE_NODE_INDEX" == "1" ]] && make cmaketest && make clean + parallel: true + #- make -C lib all && make clean + #- make -C tests dll && make clean + #- make -C tests test-zstd && make clean + #- make -C tests test-fullbench && make clean + #- make -C tests test-fuzzer && make clean + #- make -C tests test-zstream && make clean + #- make -C tests test-invalidDictionaries && make clean + #- make -C tests test-legacy && make clean + #- make -C tests test-symbols && make clean + #- make -C tests test-longmatch && make clean + #- make -C programs zstd-small zstd-decompress zstd-compress && make -C programs clean + #- make travis-install && make clean # Longer tests #- make -C tests test-zstd-nolegacy && make clean #- pyenv global 3.4.4; make -C tests versionsTest && make clean From d3ff834562a87475618ea1069bf394c414807375 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 16 Feb 2017 13:45:40 +0100 Subject: [PATCH 11/23] check CIRCLE_NODE_TOTAL --- circle.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/circle.yml b/circle.yml index c04dd46b3..716507e6b 100644 --- a/circle.yml +++ b/circle.yml @@ -8,18 +8,22 @@ dependencies: test: override: # Tests compilers and C standards - - [[ "$CIRCLE_NODE_INDEX" == "0" ]] && clang -v && make clangtest && make clean + - | + [[ "$CIRCLE_NODE_INDEX" == "0" ]] && clang -v && make clangtest && make clean + parallel: true + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then g++ -v; make gpptest && make clean; fi parallel: true - #- g++ -v; make gpptest && make clean #- gcc -v; make gnu90test && make clean #- gcc -v; make c99test && make clean #- gcc -v; make gnu99test && make clean #- gcc-5 -v; make gcc5test && make clean #- gcc-6 -v; make gcc6test && make clean # Shorter tests - - if [[ "$CIRCLE_NODE_TOTAL" < "2" ] || [ "$CIRCLE_NODE_INDEX" == "1" ]] && make cmaketest && make clean + - | + [[ "$CIRCLE_NODE_TOTAL" < "2" ] || [ "$CIRCLE_NODE_INDEX" == "1" ]] && make cmaketest && make clean + parallel: true + - if [[ "$CIRCLE_NODE_TOTAL" < "2" ] || [ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C lib all && make clean; fi parallel: true - #- make -C lib all && make clean #- make -C tests dll && make clean #- make -C tests test-zstd && make clean #- make -C tests test-fullbench && make clean From cb7694486164b2af8eac47c87f4e8742545ff035 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 16 Feb 2017 13:51:21 +0100 Subject: [PATCH 12/23] final colon --- circle.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/circle.yml b/circle.yml index 716507e6b..c9245d3da 100644 --- a/circle.yml +++ b/circle.yml @@ -9,9 +9,9 @@ test: override: # Tests compilers and C standards - | - [[ "$CIRCLE_NODE_INDEX" == "0" ]] && clang -v && make clangtest && make clean + [[ "$CIRCLE_NODE_INDEX" == "0" ]] && clang -v && make clangtest && make clean: parallel: true - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then g++ -v; make gpptest && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then g++ -v; make gpptest && make clean; fi: parallel: true #- gcc -v; make gnu90test && make clean #- gcc -v; make c99test && make clean @@ -20,9 +20,9 @@ test: #- gcc-6 -v; make gcc6test && make clean # Shorter tests - | - [[ "$CIRCLE_NODE_TOTAL" < "2" ] || [ "$CIRCLE_NODE_INDEX" == "1" ]] && make cmaketest && make clean + [[ "$CIRCLE_NODE_TOTAL" < "2" ] || [ "$CIRCLE_NODE_INDEX" == "1" ]] && make cmaketest && make clean: parallel: true - - if [[ "$CIRCLE_NODE_TOTAL" < "2" ] || [ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C lib all && make clean; fi + - if [[ "$CIRCLE_NODE_TOTAL" < "2" ] || [ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C lib all && make clean; fi: parallel: true #- make -C tests dll && make clean #- make -C tests test-zstd && make clean From fa492a3eca53ece95dab01cecdfa6d598be81837 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 16 Feb 2017 14:39:21 +0100 Subject: [PATCH 13/23] Tests for thread 1 (when CIRCLE_NODE_TOTAL=1) or thread 2 --- circle.yml | 54 ++++++++++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/circle.yml b/circle.yml index c9245d3da..aaf25617d 100644 --- a/circle.yml +++ b/circle.yml @@ -5,36 +5,34 @@ dependencies: - sudo apt-get -y install qemu-system-arm gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross - sudo apt-get -y install libc6-dev-i386 clang gcc-5 gcc-6 valgrind -test: - override: - # Tests compilers and C standards + # use default "parallel: true" for commands in the machine, checkout, dependencies and database build phase + post: + # Tests for thread 1 - | - [[ "$CIRCLE_NODE_INDEX" == "0" ]] && clang -v && make clangtest && make clean: - parallel: true - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then g++ -v; make gpptest && make clean; fi: - parallel: true - #- gcc -v; make gnu90test && make clean - #- gcc -v; make c99test && make clean - #- gcc -v; make gnu99test && make clean - #- gcc-5 -v; make gcc5test && make clean - #- gcc-6 -v; make gcc6test && make clean - # Shorter tests + [[ "$CIRCLE_NODE_INDEX" == "0" ]] && clang -v && make clangtest && make clean + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then g++ -v; make gpptest && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc -v; make gnu90test && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc -v; make c99test && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc -v; make gnu99test && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc-5 -v; make gcc5test && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc-6 -v; make gcc6test && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then make cmaketest && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then make travis-install && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then make lib && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then make -C programs zstd-small zstd-decompress zstd-compress && make clean; fi + + # Tests for thread 1 (when CIRCLE_NODE_TOTAL=1) or thread 2 - | - [[ "$CIRCLE_NODE_TOTAL" < "2" ] || [ "$CIRCLE_NODE_INDEX" == "1" ]] && make cmaketest && make clean: - parallel: true - - if [[ "$CIRCLE_NODE_TOTAL" < "2" ] || [ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C lib all && make clean; fi: - parallel: true - #- make -C tests dll && make clean - #- make -C tests test-zstd && make clean - #- make -C tests test-fullbench && make clean - #- make -C tests test-fuzzer && make clean - #- make -C tests test-zstream && make clean - #- make -C tests test-invalidDictionaries && make clean - #- make -C tests test-legacy && make clean - #- make -C tests test-symbols && make clean - #- make -C tests test-longmatch && make clean - #- make -C programs zstd-small zstd-decompress zstd-compress && make -C programs clean - #- make travis-install && make clean + [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]] && make -C tests test-zstd && make clean + - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-fullbench && make clean; fi + - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-fuzzer && make clean; fi + - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-zstream && make clean; fi + - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-legacy && make clean; fi + - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-symbols && make clean; fi + - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-longmatch && make clean; fi + - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-invalidDictionaries && make clean; fi + - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests dll && make clean; fi + # Longer tests #- make -C tests test-zstd-nolegacy && make clean #- pyenv global 3.4.4; make -C tests versionsTest && make clean From 9a0161d376585c5b237d2f651fb8618a6f71e364 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 16 Feb 2017 15:13:33 +0100 Subject: [PATCH 14/23] imporved test-zstd --- circle.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/circle.yml b/circle.yml index aaf25617d..1723628a1 100644 --- a/circle.yml +++ b/circle.yml @@ -22,8 +22,7 @@ dependencies: - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then make -C programs zstd-small zstd-decompress zstd-compress && make clean; fi # Tests for thread 1 (when CIRCLE_NODE_TOTAL=1) or thread 2 - - | - [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]] && make -C tests test-zstd && make clean + - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-zstd && make clean; fi - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-fullbench && make clean; fi - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-fuzzer && make clean; fi - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-zstream && make clean; fi From 6b64abb2870aa19691b7fe97ffdafcd9c4aeb244 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 16 Feb 2017 15:28:08 +0100 Subject: [PATCH 15/23] improved clangtest --- circle.yml | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/circle.yml b/circle.yml index 1723628a1..feb0fed0a 100644 --- a/circle.yml +++ b/circle.yml @@ -8,17 +8,16 @@ dependencies: # use default "parallel: true" for commands in the machine, checkout, dependencies and database build phase post: # Tests for thread 1 - - | - [[ "$CIRCLE_NODE_INDEX" == "0" ]] && clang -v && make clangtest && make clean - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then g++ -v; make gpptest && make clean; fi - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc -v; make gnu90test && make clean; fi - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc -v; make c99test && make clean; fi - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc -v; make gnu99test && make clean; fi - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc-5 -v; make gcc5test && make clean; fi - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc-6 -v; make gcc6test && make clean; fi - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then make cmaketest && make clean; fi - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then make travis-install && make clean; fi - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then make lib && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then clang -v; make clangtest && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then g++ -v; make gpptest && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc -v; make gnu90test && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc -v; make c99test && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc -v; make gnu99test && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc-5 -v; make gcc5test && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc-6 -v; make gcc6test && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then make cmaketest && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then make travis-install && make clean; fi + - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then make lib && make clean; fi - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then make -C programs zstd-small zstd-decompress zstd-compress && make clean; fi # Tests for thread 1 (when CIRCLE_NODE_TOTAL=1) or thread 2 From 21d9022b8896991f2f9140fce8d6b40ee26da018 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 16 Feb 2017 15:59:00 +0100 Subject: [PATCH 16/23] two groups of tests --- circle.yml | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/circle.yml b/circle.yml index feb0fed0a..bb2a35a4b 100644 --- a/circle.yml +++ b/circle.yml @@ -7,29 +7,31 @@ dependencies: # use default "parallel: true" for commands in the machine, checkout, dependencies and database build phase post: - # Tests for thread 1 - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then clang -v; make clangtest && make clean; fi - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then g++ -v; make gpptest && make clean; fi - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc -v; make gnu90test && make clean; fi - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc -v; make c99test && make clean; fi - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc -v; make gnu99test && make clean; fi - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc-5 -v; make gcc5test && make clean; fi - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc-6 -v; make gcc6test && make clean; fi - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then make cmaketest && make clean; fi - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then make travis-install && make clean; fi - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then make lib && make clean; fi - - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then make -C programs zstd-small zstd-decompress zstd-compress && make clean; fi - - # Tests for thread 1 (when CIRCLE_NODE_TOTAL=1) or thread 2 - - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-zstd && make clean; fi - - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-fullbench && make clean; fi - - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-fuzzer && make clean; fi - - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-zstream && make clean; fi - - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-legacy && make clean; fi - - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-symbols && make clean; fi - - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-longmatch && make clean; fi - - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-invalidDictionaries && make clean; fi - - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests dll && make clean; fi + - | + if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then + clang -v; make clangtest + g++ -v; make gpptest + gcc -v; make gnu90test + gcc -v; make c99test + gcc -v; make gnu99test + make gcc5test + gcc-6 -v; make gcc6test + make cmaketest + make travis-install + make lib + make -C programs zstd-small zstd-decompress zstd-compress; + fi + if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then + make -C tests test-zstd + make -C tests test-fullbench + make -C tests test-fuzzer + make -C tests test-zstream + make -C tests test-legacy + make -C tests test-symbols + make -C tests test-longmatch + make -C tests test-invalidDictionaries + make -C tests dll + fi # Longer tests #- make -C tests test-zstd-nolegacy && make clean From 84452ca29faf49c211c0137ae30cf1af278d170c Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 16 Feb 2017 16:27:40 +0100 Subject: [PATCH 17/23] more balanced tests --- circle.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/circle.yml b/circle.yml index bb2a35a4b..dc9ae7f1f 100644 --- a/circle.yml +++ b/circle.yml @@ -14,17 +14,17 @@ dependencies: gcc -v; make gnu90test gcc -v; make c99test gcc -v; make gnu99test - make gcc5test + gcc-5 -v; make gcc5test gcc-6 -v; make gcc6test make cmaketest make travis-install make lib - make -C programs zstd-small zstd-decompress zstd-compress; + make -C programs zstd-small zstd-decompress zstd-compress + make -C tests test-fuzzer fi if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-zstd make -C tests test-fullbench - make -C tests test-fuzzer make -C tests test-zstream make -C tests test-legacy make -C tests test-symbols @@ -33,6 +33,10 @@ dependencies: make -C tests dll fi +test: + override: + - echo Circle CI tests finished + # Longer tests #- make -C tests test-zstd-nolegacy && make clean #- pyenv global 3.4.4; make -C tests versionsTest && make clean From 6babbff58dbcd61e2b7268c32bacbd16681b77e9 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 16 Feb 2017 17:52:49 +0100 Subject: [PATCH 18/23] move MOREFLAGS to circle.yml --- Makefile | 2 +- circle.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3ce12e67d..d86db7cb3 100644 --- a/Makefile +++ b/Makefile @@ -138,7 +138,7 @@ msan: clean $(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=memory -fno-omit-frame-pointer" # datagen.c fails this test for no obvious reason asan32: clean - $(MAKE) -C $(TESTDIR) test32 CC=clang MOREFLAGS="-g -fsanitize=address -I/usr/include/x86_64-linux-gnu" + $(MAKE) -C $(TESTDIR) test32 CC=clang MOREFLAGS="-g -fsanitize=address" uasan: clean $(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address -fsanitize=undefined" diff --git a/circle.yml b/circle.yml index dc9ae7f1f..02a5dd6cc 100644 --- a/circle.yml +++ b/circle.yml @@ -44,6 +44,7 @@ test: #- gcc -v; make -C tests test32 MOREFLAGS="-I/usr/include/x86_64-linux-gnu" && make clean #- make uasan && make clean #- make asan32 && make clean + #- make -C tests test32 CC=clang MOREFLAGS="-g -fsanitize=address -I/usr/include/x86_64-linux-gnu" # Valgrind tests #- CFLAGS="-O1 -g" make -C zlibWrapper valgrindTest && make clean #- make -C tests valgrindTest && make clean From 40dadd65cc118781c70595059a531a5689780051 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 16 Feb 2017 18:19:36 +0100 Subject: [PATCH 19/23] join tests into pairs --- circle.yml | 50 ++++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/circle.yml b/circle.yml index 02a5dd6cc..5af1bd24e 100644 --- a/circle.yml +++ b/circle.yml @@ -8,30 +8,32 @@ dependencies: # use default "parallel: true" for commands in the machine, checkout, dependencies and database build phase post: - | - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then - clang -v; make clangtest - g++ -v; make gpptest - gcc -v; make gnu90test - gcc -v; make c99test - gcc -v; make gnu99test - gcc-5 -v; make gcc5test - gcc-6 -v; make gcc6test - make cmaketest - make travis-install - make lib - make -C programs zstd-small zstd-decompress zstd-compress - make -C tests test-fuzzer - fi - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then - make -C tests test-zstd - make -C tests test-fullbench - make -C tests test-zstream - make -C tests test-legacy - make -C tests test-symbols - make -C tests test-longmatch - make -C tests test-invalidDictionaries - make -C tests dll - fi + if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then make cmaketest && make clean; fi + if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-invalidDictionaries && make clean; fi + - | + if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then g++ -v; make gpptest && make clean; fi + if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-legacy && make clean; fi + - | + if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc -v; make gnu90test && make clean; fi + if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-symbols && make clean; fi + - | + if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc -v; make c99test && make clean; fi + if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-longmatch && make clean; fi + - | + if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc -v; make gnu99test && make clean; fi + if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests dll && make clean; fi + - | + if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then clang -v; make clangtest && make clean; fi + if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C programs zstd-small zstd-decompress zstd-compress && make clean lib && make clean; fi + - | + if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then travis-install && make clean; fi + if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-fullbench && make clean; fi + - | + if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc-5 -v; make gcc5test && gcc-6 -v && make gcc6test && make clean; fi + if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-zstream && make clean; fi + - | + if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then make -C tests test-zstd && make clean; fi + if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-fuzzer && make clean; fi test: override: From 6f508421ebd867f81ee21bd0a2b65df11619d6b2 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 16 Feb 2017 18:45:17 +0100 Subject: [PATCH 20/23] faster start of containers --- circle.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/circle.yml b/circle.yml index 5af1bd24e..de983f24f 100644 --- a/circle.yml +++ b/circle.yml @@ -1,9 +1,9 @@ dependencies: override: - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; sudo apt-get -y -qq update - - sudo apt-get -y install qemu-system-ppc qemu-user-static gcc-powerpc-linux-gnu - - sudo apt-get -y install qemu-system-arm gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross - - sudo apt-get -y install libc6-dev-i386 clang gcc-5 gcc-6 valgrind + #- sudo apt-get -y install qemu-system-ppc qemu-user-static gcc-powerpc-linux-gnu valgrind + #- sudo apt-get -y install qemu-system-arm gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross + - sudo apt-get -y install libc6-dev-i386 clang gcc-5 gcc-6 # use default "parallel: true" for commands in the machine, checkout, dependencies and database build phase post: @@ -24,7 +24,7 @@ dependencies: if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests dll && make clean; fi - | if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then clang -v; make clangtest && make clean; fi - if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C programs zstd-small zstd-decompress zstd-compress && make clean lib && make clean; fi + if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C programs zstd-small zstd-decompress zstd-compress zstd32 MOREFLAGS="-I/usr/include/x86_64-linux-gnu" && make clean lib && make clean; fi - | if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then travis-install && make clean; fi if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-fullbench && make clean; fi From 7a8811f3f56c84bb274615e7fc5568f571c47e23 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 16 Feb 2017 19:04:22 +0100 Subject: [PATCH 21/23] circle.yml: make travis-install --- circle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index de983f24f..d8b033597 100644 --- a/circle.yml +++ b/circle.yml @@ -26,7 +26,7 @@ dependencies: if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then clang -v; make clangtest && make clean; fi if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C programs zstd-small zstd-decompress zstd-compress zstd32 MOREFLAGS="-I/usr/include/x86_64-linux-gnu" && make clean lib && make clean; fi - | - if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then travis-install && make clean; fi + if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then make travis-install && make clean; fi if [[ "$CIRCLE_NODE_TOTAL" < "2" ]] || [[ "$CIRCLE_NODE_INDEX" == "1" ]]; then make -C tests test-fullbench && make clean; fi - | if [[ "$CIRCLE_NODE_INDEX" == "0" ]]; then gcc-5 -v; make gcc5test && gcc-6 -v && make gcc6test && make clean; fi From 6b010dec80124576e50635de96cc8266d7bd1cde Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Thu, 16 Feb 2017 12:05:40 -0800 Subject: [PATCH 22/23] execSequence copies up to 2*WILDCOPY_OVERLENGTH extra --- lib/decompress/zstd_decompress.c | 2 +- lib/legacy/zstd_v06.c | 2 +- lib/legacy/zstd_v07.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 52949be99..404d0b83d 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -2260,7 +2260,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB /* Adapt buffer sizes to frame header instructions */ { size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX); - size_t const neededOutSize = zds->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH; + size_t const neededOutSize = zds->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH * 2; zds->blockSize = blockSize; if (zds->inBuffSize < blockSize) { ZSTD_free(zds->inBuff, zds->customMem); diff --git a/lib/legacy/zstd_v06.c b/lib/legacy/zstd_v06.c index 1d65e8f7d..f586db226 100644 --- a/lib/legacy/zstd_v06.c +++ b/lib/legacy/zstd_v06.c @@ -4108,7 +4108,7 @@ size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* zbd, zbd->inBuff = (char*)malloc(blockSize); if (zbd->inBuff == NULL) return ERROR(memory_allocation); } - { size_t const neededOutSize = ((size_t)1 << zbd->fParams.windowLog) + blockSize + WILDCOPY_OVERLENGTH; + { size_t const neededOutSize = ((size_t)1 << zbd->fParams.windowLog) + blockSize + WILDCOPY_OVERLENGTH * 2; if (zbd->outBuffSize < neededOutSize) { free(zbd->outBuff); zbd->outBuffSize = neededOutSize; diff --git a/lib/legacy/zstd_v07.c b/lib/legacy/zstd_v07.c index c93a217f4..07099d5ab 100644 --- a/lib/legacy/zstd_v07.c +++ b/lib/legacy/zstd_v07.c @@ -4483,7 +4483,7 @@ size_t ZBUFFv07_decompressContinue(ZBUFFv07_DCtx* zbd, zbd->inBuff = (char*)zbd->customMem.customAlloc(zbd->customMem.opaque, blockSize); if (zbd->inBuff == NULL) return ERROR(memory_allocation); } - { size_t const neededOutSize = zbd->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH; + { size_t const neededOutSize = zbd->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH * 2; if (zbd->outBuffSize < neededOutSize) { zbd->customMem.customFree(zbd->customMem.opaque, zbd->outBuff); zbd->outBuffSize = neededOutSize; From 0ed3901b05ff099e485107caed272576732ce424 Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Thu, 16 Feb 2017 13:29:47 -0800 Subject: [PATCH 23/23] Update overlength match test case --- tests/zstreamtest.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index 323a087ce..9a9fed98d 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -469,15 +469,23 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo /* Overlen overwriting window data bug */ DISPLAYLEVEL(3, "test%3i : wildcopy doesn't overwrite potential match data : ", testNb++); - { const char* testCase = - "\x28\xB5\x2F\xFD\x04\x00\x4C\x00\x00\x10\x61\x61\x01\x00\xFC\x2A" - "\xC0\x02\x44\x00\x00\x08\x62\x01\x00\xFC\x2A\x10\x02\x00\x00\x00" - "\x4D\x00\x00\x00\x02\x40\x00\x01\x64\xE0\xE6\x19\xC1\xFB\x54\x9E"; + { /* This test has a window size of 1024 bytes and consists of 3 blocks: + 1. 'a' repeated 517 times + 2. 'b' repeated 516 times + 3. a compressed block with no literals and 3 sequence commands: + litlength = 0, offset = 24, match length = 24 + litlength = 0, offset = 24, match length = 3 (this one creates an overlength write of length 2*WILDCOPY_OVERLENGTH - 3) + litlength = 0, offset = 1021, match length = 3 (this one will try to read from overwritten data if the buffer is too small) */ + + const char* testCase = + "\x28\xB5\x2F\xFD\x04\x00\x4C\x00\x00\x10\x61\x61\x01\x00\x00\x2A" + "\x80\x05\x44\x00\x00\x08\x62\x01\x00\x00\x2A\x20\x04\x5D\x00\x00" + "\x00\x03\x40\x00\x00\x64\x60\x27\xB0\xE0\x0C\x67\x62\xCE\xE0"; ZSTD_DStream* zds = ZSTD_createDStream(); ZSTD_initDStream(zds); inBuff.src = testCase; - inBuff.size = 48; + inBuff.size = 47; inBuff.pos = 0; outBuff.dst = decodedBuffer; outBuff.size = CNBufferSize;