From d2908b9215f7c991206edfe6047f3e413763ed18 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 7 Dec 2016 16:41:33 -0800 Subject: [PATCH 01/17] updated NEWS --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index 36aa45e91..b4a200ad6 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ cli : new : preserve file attributes cli : new : added zstdless and zstdgrep tools cli : fixed : status displays total amount decoded, even for file consisting of multiple frames (like pzstd) cli : fixed : zstdcat +library : changed : only public ZSTD_ symbols are now exposed API : changed : zbuff prototypes now generate deprecation warnings API : changed : streaming decompression implicit reset on starting new frame API : added experimental : dictID retrieval functions From 16a57525884b3d1445d48ac56918530fe0efa562 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 8 Dec 2016 17:28:26 -0800 Subject: [PATCH 02/17] streaming example uses stable API --- examples/streaming_compression.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/examples/streaming_compression.c b/examples/streaming_compression.c index 108a63c83..4c2c1a1d8 100644 --- a/examples/streaming_compression.c +++ b/examples/streaming_compression.c @@ -7,11 +7,9 @@ */ -#include // malloc, exit -#include // fprintf, perror, feof -#include // strerror -#include // errno -#define ZSTD_STATIC_LINKING_ONLY // streaming API defined as "experimental" for the time being +#include // malloc, free, exit +#include // fprintf, perror, feof, fopen, etc. +#include // strlen, memset, strcat #include // presumes zstd library is installed @@ -82,7 +80,7 @@ static void compressFile_orDie(const char* fname, const char* outName, int cLeve ZSTD_outBuffer output = { buffOut, buffOutSize, 0 }; toRead = ZSTD_compressStream(cstream, &output , &input); /* toRead is guaranteed to be <= ZSTD_CStreamInSize() */ if (ZSTD_isError(toRead)) { fprintf(stderr, "ZSTD_compressStream() error : %s \n", ZSTD_getErrorName(toRead)); exit(12); } - if (toRead > buffInSize) toRead = buffInSize; /* Safely handle when `buffInSize` is manually changed to a smaller value */ + if (toRead > buffInSize) toRead = buffInSize; /* Safely handle case when `buffInSize` is manually changed to a value < ZSTD_CStreamInSize()*/ fwrite_orDie(buffOut, output.pos, fout); } } From 6e754fe76addd34ad238c0c131b4aede73b442f0 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 8 Dec 2016 18:25:36 -0800 Subject: [PATCH 03/17] fixed lib soname. example : simple_compression : size overflow check --- NEWS | 3 ++- examples/simple_compression.c | 21 +++++++++++++-------- lib/Makefile | 4 ++-- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/NEWS b/NEWS index b4a200ad6..f6f1ad90b 100644 --- a/NEWS +++ b/NEWS @@ -5,7 +5,8 @@ cli : new : preserve file attributes cli : new : added zstdless and zstdgrep tools cli : fixed : status displays total amount decoded, even for file consisting of multiple frames (like pzstd) cli : fixed : zstdcat -library : changed : only public ZSTD_ symbols are now exposed +lib : changed : only public ZSTD_ symbols are now exposed +lib : fixed : soname API : changed : zbuff prototypes now generate deprecation warnings API : changed : streaming decompression implicit reset on starting new frame API : added experimental : dictID retrieval functions diff --git a/examples/simple_compression.c b/examples/simple_compression.c index 332ce721b..deb0bbfc4 100644 --- a/examples/simple_compression.c +++ b/examples/simple_compression.c @@ -8,9 +8,9 @@ -#include // malloc, exit -#include // fprintf, perror -#include // strerror +#include // malloc, free, exit +#include // fprintf, perror, fopen, etc. +#include // strlen, strcat, memset, strerror #include // errno #include // stat #include // presumes zstd library is installed @@ -45,13 +45,18 @@ static void* malloc_orDie(size_t size) static void* loadFile_orDie(const char* fileName, size_t* size) { - off_t const buffSize = fsize_orDie(fileName); + off_t const fileSize = fsize_orDie(fileName); + size_t const buffSize = (size_t)fileSize; + if ((off_t)buffSize < fileSize) { /* narrowcast overflow */ + fprintf(stderr, "%s : filesize too large \n", fileName); + exit(4); + } 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) { fprintf(stderr, "fread: %s : %s \n", fileName, strerror(errno)); - exit(4); + exit(5); } fclose(inFile); /* can't fail, read only */ *size = buffSize; @@ -65,11 +70,11 @@ static void saveFile_orDie(const char* fileName, const void* buff, size_t buffSi size_t const wSize = fwrite(buff, 1, buffSize, oFile); if (wSize != (size_t)buffSize) { fprintf(stderr, "fwrite: %s : %s \n", fileName, strerror(errno)); - exit(5); + exit(6); } if (fclose(oFile)) { perror(fileName); - exit(6); + exit(7); } } @@ -84,7 +89,7 @@ static void compress_orDie(const char* fname, const char* oname) size_t const cSize = ZSTD_compress(cBuff, cBuffSize, fBuff, fSize, 1); if (ZSTD_isError(cSize)) { fprintf(stderr, "error compressing %s : %s \n", fname, ZSTD_getErrorName(cSize)); - exit(7); + exit(8); } saveFile_orDie(oname, cBuff, cSize); diff --git a/lib/Makefile b/lib/Makefile index 44c64b8ed..21a805d05 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -47,9 +47,9 @@ ifeq ($(shell uname), Darwin) SHARED_EXT = dylib SHARED_EXT_MAJOR = $(LIBVER_MAJOR).$(SHARED_EXT) SHARED_EXT_VER = $(LIBVER).$(SHARED_EXT) - SONAME_FLAGS = -install_name $(PREFIX)/lib/$@.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER) + SONAME_FLAGS = -install_name $(PREFIX)/lib/libzstd.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER) else - SONAME_FLAGS = -Wl,-soname=$@.$(SHARED_EXT).$(LIBVER_MAJOR) + SONAME_FLAGS = -Wl,-soname=libzstd.$(SHARED_EXT).$(LIBVER_MAJOR) SHARED_EXT = so SHARED_EXT_MAJOR = $(SHARED_EXT).$(LIBVER_MAJOR) SHARED_EXT_VER = $(SHARED_EXT).$(LIBVER) From 383b8088a33530500131a17b50b687fade2b199b Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 8 Dec 2016 18:42:27 -0800 Subject: [PATCH 04/17] minor lib build refactoring --- NEWS | 1 - lib/Makefile | 14 +++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index f6f1ad90b..7f30f2d52 100644 --- a/NEWS +++ b/NEWS @@ -6,7 +6,6 @@ cli : new : added zstdless and zstdgrep tools cli : fixed : status displays total amount decoded, even for file consisting of multiple frames (like pzstd) cli : fixed : zstdcat lib : changed : only public ZSTD_ symbols are now exposed -lib : fixed : soname API : changed : zbuff prototypes now generate deprecation warnings API : changed : streaming decompression implicit reset on starting new frame API : added experimental : dictID retrieval functions diff --git a/lib/Makefile b/lib/Makefile index 21a805d05..fcc0d099d 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -47,7 +47,7 @@ ifeq ($(shell uname), Darwin) SHARED_EXT = dylib SHARED_EXT_MAJOR = $(LIBVER_MAJOR).$(SHARED_EXT) SHARED_EXT_VER = $(LIBVER).$(SHARED_EXT) - SONAME_FLAGS = -install_name $(PREFIX)/lib/libzstd.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER) + SONAME_FLAGS = -install_name $(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER) else SONAME_FLAGS = -Wl,-soname=libzstd.$(SHARED_EXT).$(LIBVER_MAJOR) SHARED_EXT = so @@ -107,15 +107,15 @@ libzstd.pc: libzstd.pc.in install: libzstd.a libzstd libzstd.pc @install -d -m 755 $(DESTDIR)$(LIBDIR)/pkgconfig/ $(DESTDIR)$(INCLUDEDIR)/ - @install -m 755 libzstd.$(SHARED_EXT_VER) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT_VER) + @install -m 755 libzstd.$(SHARED_EXT_VER) $(DESTDIR)$(LIBDIR) @cp -a libzstd.$(SHARED_EXT_MAJOR) $(DESTDIR)$(LIBDIR) @cp -a libzstd.$(SHARED_EXT) $(DESTDIR)$(LIBDIR) @cp -a libzstd.pc $(DESTDIR)$(LIBDIR)/pkgconfig/ - @install -m 644 libzstd.a $(DESTDIR)$(LIBDIR)/libzstd.a - @install -m 644 zstd.h $(DESTDIR)$(INCLUDEDIR)/zstd.h - @install -m 644 common/zstd_errors.h $(DESTDIR)$(INCLUDEDIR)/zstd_errors.h - @install -m 644 deprecated/zbuff.h $(DESTDIR)$(INCLUDEDIR)/zbuff.h # prototypes generate deprecation warnings - @install -m 644 dictBuilder/zdict.h $(DESTDIR)$(INCLUDEDIR)/zdict.h + @install -m 644 libzstd.a $(DESTDIR)$(LIBDIR) + @install -m 644 zstd.h $(DESTDIR)$(INCLUDEDIR) + @install -m 644 common/zstd_errors.h $(DESTDIR)$(INCLUDEDIR) + @install -m 644 deprecated/zbuff.h $(DESTDIR)$(INCLUDEDIR) # prototypes generate deprecation warnings + @install -m 644 dictBuilder/zdict.h $(DESTDIR)$(INCLUDEDIR) @echo zstd static and shared library installed uninstall: From 0012332ce0acf589da4831e9f9b2e79ce12eed9d Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 9 Dec 2016 17:15:33 -0800 Subject: [PATCH 05/17] Fix compression segfault When the overflow protection kicks in, it makes sure that ip - ctx->base isn't too large. However, it didn't ensure that saved offsets are still valid. This change ensures that any valid offsets (<= windowLog) are still representable after the update. The bug would shop up on line 1056, when `offset_1 > current + 1`, which causes an underflow. This in turn, would cause a segfault on line 1063. The input must necessarily be longer than 1 GB for this issue to occur. Even then, it only occurs if one of the last 3 matches is larger than the chain size and block size. --- 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 665d09c0f..a575534c3 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2277,7 +2277,7 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, if (cctx->lowLimit > (1<<30)) { U32 const btplus = (cctx->params.cParams.strategy == ZSTD_btlazy2) | (cctx->params.cParams.strategy == ZSTD_btopt) | (cctx->params.cParams.strategy == ZSTD_btopt2); U32 const chainMask = (1 << (cctx->params.cParams.chainLog - btplus)) - 1; - U32 const supLog = MAX(cctx->params.cParams.chainLog, 17 /* blockSize */); + U32 const supLog = MAX(MAX(cctx->params.cParams.chainLog, 17 /* blockSize */), cctx->params.cParams.windowLog); U32 const newLowLimit = (cctx->lowLimit & chainMask) + (1 << supLog); /* preserve position % chainSize, ensure current-repcode doesn't underflow */ U32 const correction = cctx->lowLimit - newLowLimit; ZSTD_reduceIndex(cctx, correction); From 3826207a70779477703fcfe11f652d5cea9cff8c Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Sat, 10 Dec 2016 18:46:55 -0800 Subject: [PATCH 06/17] Simplify segfault fix Take advantage of the fact that `chainLog <= windowLog`. --- 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 a575534c3..aef769fc0 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2277,7 +2277,7 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, if (cctx->lowLimit > (1<<30)) { U32 const btplus = (cctx->params.cParams.strategy == ZSTD_btlazy2) | (cctx->params.cParams.strategy == ZSTD_btopt) | (cctx->params.cParams.strategy == ZSTD_btopt2); U32 const chainMask = (1 << (cctx->params.cParams.chainLog - btplus)) - 1; - U32 const supLog = MAX(MAX(cctx->params.cParams.chainLog, 17 /* blockSize */), cctx->params.cParams.windowLog); + U32 const supLog = MAX(cctx->params.cParams.windowLog, 17 /* blockSize */); U32 const newLowLimit = (cctx->lowLimit & chainMask) + (1 << supLog); /* preserve position % chainSize, ensure current-repcode doesn't underflow */ U32 const correction = cctx->lowLimit - newLowLimit; ZSTD_reduceIndex(cctx, correction); From 0acae734f17e43ccceb8bd6bd3f1eee0d179ca9f Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Sat, 10 Dec 2016 19:12:13 -0800 Subject: [PATCH 07/17] Add exposing test case --- tests/.gitignore | 1 + tests/Makefile | 10 +++++-- tests/longmatch.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 tests/longmatch.c diff --git a/tests/.gitignore b/tests/.gitignore index c8f9ae79e..b558ac258 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -11,6 +11,7 @@ datagen paramgrill paramgrill32 roundTripCrash +longmatch # Tmp test directory zstdtest diff --git a/tests/Makefile b/tests/Makefile index fbee21448..6110465f6 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -124,6 +124,9 @@ datagen : $(PRGDIR)/datagen.c datagencli.c roundTripCrash : $(ZSTD_FILES) roundTripCrash.c $(CC) $(FLAGS) $^ -o $@$(EXT) +longmatch : $(ZSTD_FILES) longmatch.c + $(CC) $(FLAGS) $^ -o $@$(EXT) + namespaceTest: if $(CC) namespaceTest.c ../lib/common/xxhash.c -o $@ ; then echo compilation should fail; exit 1 ; fi $(RM) $@ @@ -140,7 +143,7 @@ clean: fullbench-lib$(EXT) fullbench-dll$(EXT) \ fuzzer$(EXT) fuzzer32$(EXT) zbufftest$(EXT) zbufftest32$(EXT) \ zstreamtest$(EXT) zstreamtest32$(EXT) \ - datagen$(EXT) paramgrill$(EXT) roundTripCrash$(EXT) + datagen$(EXT) paramgrill$(EXT) roundTripCrash$(EXT) longmatch$(EXT) @echo Cleaning completed @@ -180,7 +183,7 @@ zstd-playTests: datagen file $(ZSTD) ZSTD="$(QEMU_SYS) $(ZSTD)" ./playTests.sh $(ZSTDRTTEST) -test: test-zstd test-fullbench test-fuzzer test-zstream +test: test-zstd test-fullbench test-fuzzer test-zstream test-longmatch test32: test-zstd32 test-fullbench32 test-fuzzer32 test-zstream32 @@ -237,4 +240,7 @@ test-zstream: zstreamtest test-zstream32: zstreamtest32 $(QEMU_SYS) ./zstreamtest32 $(ZSTREAM_TESTTIME) +test-longmatch: longmatch + $(QEMU_SYS) ./longmatch + endif diff --git a/tests/longmatch.c b/tests/longmatch.c new file mode 100644 index 000000000..b99dccc6f --- /dev/null +++ b/tests/longmatch.c @@ -0,0 +1,72 @@ +#define ZSTD_STATIC_LINKING_ONLY +#include +#include +#include +#include + +void compress(ZSTD_CStream *ctx, ZSTD_outBuffer out, const void *data, size_t size) { + ZSTD_inBuffer in = { data, size, 0 }; + while (in.pos < in.size) { + ZSTD_outBuffer tmp = out; + const size_t rc = ZSTD_compressStream(ctx, &tmp, &in); + if (ZSTD_isError(rc)) { + exit(5); + } + } + ZSTD_outBuffer tmp = out; + const size_t rc = ZSTD_flushStream(ctx, &tmp); + if (rc != 0) { exit(6); } +} + +int main() { + ZSTD_CStream *ctx; + ZSTD_parameters params = {}; + size_t rc; + unsigned windowLog; + /* Create stream */ + ctx = ZSTD_createCStream(); + if (!ctx) { return 1; } + /* Set parameters */ + params.cParams.windowLog = 18; + params.cParams.chainLog = 13; + params.cParams.hashLog = 14; + params.cParams.searchLog = 1; + params.cParams.searchLength = 7; + params.cParams.targetLength = 16; + params.cParams.strategy = ZSTD_fast; + windowLog = params.cParams.windowLog; + /* Initialize stream */ + rc = ZSTD_initCStream_advanced(ctx, NULL, 0, params, 0); + if (ZSTD_isError(rc)) { return 2; } + { + uint64_t compressed = 0; + const uint64_t toCompress = ((uint64_t)1) << 33; + const size_t size = 1 << windowLog; + size_t pos = 0; + char *srcBuffer = (char*) malloc(1 << windowLog); + char *dstBuffer = (char*) malloc(ZSTD_compressBound(1 << windowLog)); + ZSTD_outBuffer out = { dstBuffer, ZSTD_compressBound(1 << windowLog), 0 }; + const char match[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const size_t randomData = (1 << windowLog) - 2*sizeof(match); + for (size_t i = 0; i < sizeof(match); ++i) { + srcBuffer[i] = match[i]; + } + for (size_t i = 0; i < randomData; ++i) { + srcBuffer[sizeof(match) + i] = (char)(rand() & 0xFF); + } + for (size_t i = 0; i < sizeof(match); ++i) { + srcBuffer[sizeof(match) + randomData + i] = match[i]; + } + compress(ctx, out, srcBuffer, size); + compressed += size; + while (compressed < toCompress) { + const size_t block = rand() % (size - pos + 1); + if (pos == size) { pos = 0; } + compress(ctx, out, srcBuffer + pos, block); + pos += block; + compressed += block; + } + free(srcBuffer); + free(dstBuffer); + } +} From 5cc85cf18398cde78cef206a4f0ef381c0d91846 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Sat, 10 Dec 2016 19:31:55 -0800 Subject: [PATCH 08/17] Switch uint64_t to U64 --- tests/longmatch.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/longmatch.c b/tests/longmatch.c index b99dccc6f..46dcbc77a 100644 --- a/tests/longmatch.c +++ b/tests/longmatch.c @@ -1,8 +1,10 @@ #define ZSTD_STATIC_LINKING_ONLY -#include +#include "zstd.h" +#include "mem.h" #include #include #include +#include void compress(ZSTD_CStream *ctx, ZSTD_outBuffer out, const void *data, size_t size) { ZSTD_inBuffer in = { data, size, 0 }; @@ -39,8 +41,8 @@ int main() { rc = ZSTD_initCStream_advanced(ctx, NULL, 0, params, 0); if (ZSTD_isError(rc)) { return 2; } { - uint64_t compressed = 0; - const uint64_t toCompress = ((uint64_t)1) << 33; + U64 compressed = 0; + const U64 toCompress = ((U64)1) << 33; const size_t size = 1 << windowLog; size_t pos = 0; char *srcBuffer = (char*) malloc(1 << windowLog); From b547d212a191c6cd7c2b0b4b942833ac8c360c33 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Sat, 10 Dec 2016 23:17:36 -0800 Subject: [PATCH 09/17] Fix longmatch test build errors. --- tests/longmatch.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/tests/longmatch.c b/tests/longmatch.c index 46dcbc77a..c75c0d18e 100644 --- a/tests/longmatch.c +++ b/tests/longmatch.c @@ -6,29 +6,35 @@ #include #include -void compress(ZSTD_CStream *ctx, ZSTD_outBuffer out, const void *data, size_t size) { +int compress(ZSTD_CStream *ctx, ZSTD_outBuffer out, const void *data, size_t size) { ZSTD_inBuffer in = { data, size, 0 }; while (in.pos < in.size) { ZSTD_outBuffer tmp = out; const size_t rc = ZSTD_compressStream(ctx, &tmp, &in); if (ZSTD_isError(rc)) { - exit(5); + return 1; } } - ZSTD_outBuffer tmp = out; - const size_t rc = ZSTD_flushStream(ctx, &tmp); - if (rc != 0) { exit(6); } + { + ZSTD_outBuffer tmp = out; + const size_t rc = ZSTD_flushStream(ctx, &tmp); + if (rc != 0) { return 1; } + } + return 0; } -int main() { +int main(int argc, const char** argv) { ZSTD_CStream *ctx; - ZSTD_parameters params = {}; + ZSTD_parameters params; size_t rc; unsigned windowLog; + (void)argc; + (void)argv; /* Create stream */ ctx = ZSTD_createCStream(); if (!ctx) { return 1; } /* Set parameters */ + memset(¶ms, 0, sizeof(params)); params.cParams.windowLog = 18; params.cParams.chainLog = 13; params.cParams.hashLog = 14; @@ -50,25 +56,31 @@ int main() { ZSTD_outBuffer out = { dstBuffer, ZSTD_compressBound(1 << windowLog), 0 }; const char match[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; const size_t randomData = (1 << windowLog) - 2*sizeof(match); - for (size_t i = 0; i < sizeof(match); ++i) { + size_t i; + for (i = 0; i < sizeof(match); ++i) { srcBuffer[i] = match[i]; } - for (size_t i = 0; i < randomData; ++i) { + for (i = 0; i < randomData; ++i) { srcBuffer[sizeof(match) + i] = (char)(rand() & 0xFF); } - for (size_t i = 0; i < sizeof(match); ++i) { + for (i = 0; i < sizeof(match); ++i) { srcBuffer[sizeof(match) + randomData + i] = match[i]; } - compress(ctx, out, srcBuffer, size); + if (compress(ctx, out, srcBuffer, size)) { + return 1; + } compressed += size; while (compressed < toCompress) { const size_t block = rand() % (size - pos + 1); if (pos == size) { pos = 0; } - compress(ctx, out, srcBuffer + pos, block); + if (compress(ctx, out, srcBuffer + pos, block)) { + return 1; + } pos += block; compressed += block; } free(srcBuffer); free(dstBuffer); } + return 0; } From c261f71f6a85dfcf66f612357782bd29acbb44c1 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 12 Dec 2016 00:25:07 +0100 Subject: [PATCH 10/17] minor variation of rescale fix --- NEWS | 9 +++++---- lib/compress/zstd_compress.c | 12 +++++++----- tests/longmatch.c | 10 +++++++--- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/NEWS b/NEWS index 7f30f2d52..dc6c93234 100644 --- a/NEWS +++ b/NEWS @@ -1,14 +1,15 @@ v1.1.2 -Improved : faster decompression speed at ultra compression settings and in 32-bits mode +Improved : faster decompression speed at ultra compression settings and 32-bits mode cli : new : gzstd, experimental version able to decode .gz files, by Przemyslaw Skibinski cli : new : preserve file attributes cli : new : added zstdless and zstdgrep tools cli : fixed : status displays total amount decoded, even for file consisting of multiple frames (like pzstd) cli : fixed : zstdcat +lib : fixed : bug in streaming compression, by Nick Terrell lib : changed : only public ZSTD_ symbols are now exposed -API : changed : zbuff prototypes now generate deprecation warnings -API : changed : streaming decompression implicit reset on starting new frame -API : added experimental : dictID retrieval functions +API : zbuff : changed : prototypes now generate deprecation warnings +API : streaming : decompression : changed : implicit reset on starting new frames without init +API : experimental : added : dictID retrieval functions zlib_wrapper : added support for gz* functions, by Przemyslaw Skibinski Changed : zbuff source files moved to lib/deprecated Changed : reduced stack memory use diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index aef769fc0..35201a3a2 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -33,6 +33,7 @@ typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZS /*-************************************* * Helper functions ***************************************/ +#define ZSTD_STATIC_ASSERT(c) { enum { ZSTD_static_assert = 1/(int)(!!(c)) }; } size_t ZSTD_compressBound(size_t srcSize) { return FSE_compressBound(srcSize) + 12; } @@ -2274,16 +2275,17 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, if (remaining < blockSize) blockSize = remaining; /* preemptive overflow correction */ - if (cctx->lowLimit > (1<<30)) { + if (cctx->lowLimit > (2U<<30)) { U32 const btplus = (cctx->params.cParams.strategy == ZSTD_btlazy2) | (cctx->params.cParams.strategy == ZSTD_btopt) | (cctx->params.cParams.strategy == ZSTD_btopt2); U32 const chainMask = (1 << (cctx->params.cParams.chainLog - btplus)) - 1; - U32 const supLog = MAX(cctx->params.cParams.windowLog, 17 /* blockSize */); - U32 const newLowLimit = (cctx->lowLimit & chainMask) + (1 << supLog); /* preserve position % chainSize, ensure current-repcode doesn't underflow */ - U32 const correction = cctx->lowLimit - newLowLimit; + U32 const current = (U32)(ip - cctx->base); + U32 const newCurrent = (current & chainMask) + (1 << cctx->params.cParams.windowLog); + U32 const correction = current - newCurrent; + ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_64 <= 30); ZSTD_reduceIndex(cctx, correction); cctx->base += correction; cctx->dictBase += correction; - cctx->lowLimit = newLowLimit; + cctx->lowLimit -= correction; cctx->dictLimit -= correction; if (cctx->nextToUpdate < correction) cctx->nextToUpdate = 0; else cctx->nextToUpdate -= correction; diff --git a/tests/longmatch.c b/tests/longmatch.c index c75c0d18e..61b81b359 100644 --- a/tests/longmatch.c +++ b/tests/longmatch.c @@ -1,10 +1,10 @@ -#define ZSTD_STATIC_LINKING_ONLY -#include "zstd.h" -#include "mem.h" #include #include #include #include +#include "mem.h" +#define ZSTD_STATIC_LINKING_ONLY +#include "zstd.h" int compress(ZSTD_CStream *ctx, ZSTD_outBuffer out, const void *data, size_t size) { ZSTD_inBuffer in = { data, size, 0 }; @@ -57,6 +57,8 @@ int main(int argc, const char** argv) { const char match[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; const size_t randomData = (1 << windowLog) - 2*sizeof(match); size_t i; + printf("\n === Long Match Test === \n"); + printf("Creating random data to produce long matches \n"); for (i = 0; i < sizeof(match); ++i) { srcBuffer[i] = match[i]; } @@ -66,6 +68,7 @@ int main(int argc, const char** argv) { for (i = 0; i < sizeof(match); ++i) { srcBuffer[sizeof(match) + randomData + i] = match[i]; } + printf("Compressing, trying to generate a segfault \n"); if (compress(ctx, out, srcBuffer, size)) { return 1; } @@ -79,6 +82,7 @@ int main(int argc, const char** argv) { pos += block; compressed += block; } + printf("Compression completed successfully (no error triggered)\n"); free(srcBuffer); free(dstBuffer); } From c3a5c4bef8e3ed2dac9407f08a381c3dfb431cd2 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 12 Dec 2016 00:47:30 +0100 Subject: [PATCH 11/17] introduced cycleLog --- lib/compress/zstd_compress.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 35201a3a2..6e52ec8ec 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -149,6 +149,14 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams) } +/** ZSTD_cycleLog() : + * condition for correct operation : hashLog > 1 */ +static U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat) +{ + U32 const btScale = ((U32)strat >= (U32)ZSTD_btlazy2); + return hashLog - btScale; +} + /** ZSTD_adjustCParams() : optimize `cPar` for a given input (`srcSize` and `dictSize`). mostly downsizing to reduce memory consumption and initialization. @@ -167,9 +175,9 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u if (cPar.windowLog > srcLog) cPar.windowLog = srcLog; } } if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog; - { U32 const btPlus = (cPar.strategy == ZSTD_btlazy2) | (cPar.strategy == ZSTD_btopt) | (cPar.strategy == ZSTD_btopt2); - U32 const maxChainLog = cPar.windowLog+btPlus; - if (cPar.chainLog > maxChainLog) cPar.chainLog = maxChainLog; } /* <= ZSTD_CHAINLOG_MAX */ + { U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy); + if (cycleLog > cPar.windowLog) cPar.chainLog -= (cycleLog - cPar.windowLog); + } if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* required for frame header */ @@ -2276,10 +2284,9 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, /* preemptive overflow correction */ if (cctx->lowLimit > (2U<<30)) { - U32 const btplus = (cctx->params.cParams.strategy == ZSTD_btlazy2) | (cctx->params.cParams.strategy == ZSTD_btopt) | (cctx->params.cParams.strategy == ZSTD_btopt2); - U32 const chainMask = (1 << (cctx->params.cParams.chainLog - btplus)) - 1; + U32 const cycleMask = (1 << ZSTD_cycleLog(cctx->params.cParams.hashLog, cctx->params.cParams.strategy)) - 1; U32 const current = (U32)(ip - cctx->base); - U32 const newCurrent = (current & chainMask) + (1 << cctx->params.cParams.windowLog); + U32 const newCurrent = (current & cycleMask) + (1 << cctx->params.cParams.windowLog); U32 const correction = current - newCurrent; ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_64 <= 30); ZSTD_reduceIndex(cctx, correction); From fda539f50b5f8e9c63df546ef952a75eba4505b6 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 12 Dec 2016 01:03:23 +0100 Subject: [PATCH 12/17] minor coding style changes --- programs/util.h | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/programs/util.h b/programs/util.h index fd07c348a..012c20c49 100644 --- a/programs/util.h +++ b/programs/util.h @@ -25,7 +25,7 @@ extern "C" { # define _CRT_SECURE_NO_DEPRECATE /* VS2005 */ # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ #if _MSC_VER <= 1800 /* (1800 = Visual Studio 2013) */ - #define snprintf sprintf_s /* snprintf unsupported by Visual <= 2013 */ +# define snprintf sprintf_s /* snprintf unsupported by Visual <= 2013 */ #endif #endif @@ -49,11 +49,11 @@ extern "C" { #include /* stat, utime */ #include /* stat */ #if defined(_MSC_VER) - #include /* utime */ - #include /* _chmod */ +# include /* utime */ +# include /* _chmod */ #else - #include /* chown, stat */ - #include /* utime */ +# include /* chown, stat */ +# include /* utime */ #endif #include /* time */ #include @@ -406,16 +406,15 @@ UTIL_STATIC const char** UTIL_createFileList(const char **inputNames, unsigned i { size_t pos; unsigned i, nbFiles; - char *bufend, *buf; + char* buf = (char*)malloc(LIST_SIZE_INCREASE); + char* bufend = buf + LIST_SIZE_INCREASE; const char** fileTable; - buf = (char*)malloc(LIST_SIZE_INCREASE); if (!buf) return NULL; - bufend = buf + LIST_SIZE_INCREASE; for (i=0, pos=0, nbFiles=0; i= bufend) { ptrdiff_t newListSize = (bufend - buf) + LIST_SIZE_INCREASE; buf = (char*)UTIL_realloc(buf, newListSize); @@ -437,8 +436,7 @@ UTIL_STATIC const char** UTIL_createFileList(const char **inputNames, unsigned i fileTable = (const char**)malloc((nbFiles+1) * sizeof(const char*)); if (!fileTable) { free(buf); return NULL; } - for (i=0, pos=0; i Date: Mon, 12 Dec 2016 19:22:47 +0100 Subject: [PATCH 13/17] Fix running test suite on FreeBSD * Remove last bashism from tests/playTests.sh * Use gmd5sum from the sysutils/coreutils port --- tests/playTests.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/playTests.sh b/tests/playTests.sh index 6179265e7..abde72c80 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -31,8 +31,10 @@ case "$OS" in ;; esac -case "$OSTYPE" in - darwin*) MD5SUM="md5 -r" ;; +UNAME=$(uname) +case "$UNAME" in + Darwin) MD5SUM="md5 -r" ;; + FreeBSD) MD5SUM="gmd5sum" ;; *) MD5SUM="md5sum" ;; esac @@ -228,8 +230,8 @@ cp ../programs/*.h dirTestDict $MD5SUM dirTestDict/* > tmph1 $ZSTD -f --rm dirTestDict/* -D tmpDictC $ZSTD -d --rm dirTestDict/*.zst -D tmpDictC # note : use internal checksum by default -case "$OSTYPE" in - darwin*) $ECHO "md5sum -c not supported on OS-X : test skipped" ;; # not compatible with OS-X's md5 +case "$UNAME" in + Darwin) $ECHO "md5sum -c not supported on OS-X : test skipped" ;; # not compatible with OS-X's md5 *) $MD5SUM -c tmph1 ;; esac rm -rf dirTestDict From 83cc2fb083c1f757a23d75173cdf1f104759f77c Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Mon, 12 Dec 2016 19:24:51 +0100 Subject: [PATCH 14/17] Enable using isatty() and nanosleep() on *BSD --- contrib/pzstd/Options.cpp | 10 ++-------- programs/util.h | 2 +- programs/zstdcli.c | 3 ++- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/contrib/pzstd/Options.cpp b/contrib/pzstd/Options.cpp index 18c069eae..0b1403354 100644 --- a/contrib/pzstd/Options.cpp +++ b/contrib/pzstd/Options.cpp @@ -22,19 +22,13 @@ defined(__CYGWIN__) #include /* _isatty */ #define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream)) -#else -#if defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \ - defined(_POSIX_SOURCE) || \ - (defined(__APPLE__) && \ - defined( \ - __MACH__)) /* https://sourceforge.net/p/predef/wiki/OperatingSystems/ \ - */ +#elif defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || (defined(__APPLE__) && defined(__MACH__)) || \ + defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) /* https://sourceforge.net/p/predef/wiki/OperatingSystems/ */ #include /* isatty */ #define IS_CONSOLE(stdStream) isatty(fileno(stdStream)) #else #define IS_CONSOLE(stdStream) 0 #endif -#endif namespace pzstd { diff --git a/programs/util.h b/programs/util.h index 3d5c44642..0fa70577a 100644 --- a/programs/util.h +++ b/programs/util.h @@ -98,7 +98,7 @@ extern "C" { # define SET_HIGH_PRIORITY /* disabled */ # endif # define UTIL_sleep(s) sleep(s) -# if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L) +# if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L)) # define UTIL_sleepMilli(milli) { struct timespec t; t.tv_sec=0; t.tv_nsec=milli*1000000ULL; nanosleep(&t, NULL); } # else # define UTIL_sleepMilli(milli) /* disabled */ diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 7ffb0bb62..561730a5f 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -43,7 +43,8 @@ #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) # include /* _isatty */ # define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream)) -#elif defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || (defined(__APPLE__) && defined(__MACH__)) /* https://sourceforge.net/p/predef/wiki/OperatingSystems/ */ +#elif defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || (defined(__APPLE__) && defined(__MACH__)) || \ + defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) /* https://sourceforge.net/p/predef/wiki/OperatingSystems/ */ # include /* isatty */ # define IS_CONSOLE(stdStream) isatty(fileno(stdStream)) #else From e474aa55b4d6b52d5e7d97db163835f208415a12 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 12 Dec 2016 18:05:30 -0800 Subject: [PATCH 15/17] Fix decompression buffer overrun Allows an adversary to write up to 3 bytes beyond the end of the buffer. Occurs if the match overlaps the `extDict` and `currentPrefix`, and the match length in the `currentPrefix` is less than `MINMATCH`, and `op-(16-MINMATCH) >= oMatchEnd > op-16`. --- lib/decompress/zstd_decompress.c | 8 ++++---- lib/legacy/zstd_v01.c | 2 +- lib/legacy/zstd_v02.c | 2 +- lib/legacy/zstd_v03.c | 2 +- lib/legacy/zstd_v04.c | 4 ++-- lib/legacy/zstd_v05.c | 4 ++-- lib/legacy/zstd_v06.c | 2 +- lib/legacy/zstd_v07.c | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 70dd4ccaa..1422d2b3b 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -963,13 +963,13 @@ size_t ZSTD_execSequence(BYTE* op, op = oLitEnd + length1; sequence.matchLength -= length1; match = base; - if (op > oend_w) { + if (op > oend_w || sequence.matchLength < MINMATCH) { U32 i; for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; return sequenceLength; } } } - /* Requirement: op <= oend_w */ + /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */ /* match within prefix */ if (sequence.offset < 8) { @@ -1183,13 +1183,13 @@ size_t ZSTD_execSequenceLong(BYTE* op, op = oLitEnd + length1; sequence.matchLength -= length1; match = base; - if (op > oend_w) { + if (op > oend_w || sequence.matchLength < MINMATCH) { U32 i; for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; return sequenceLength; } } } - /* Requirement: op <= oend_w */ + /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */ #endif /* match within prefix */ diff --git a/lib/legacy/zstd_v01.c b/lib/legacy/zstd_v01.c index 5c36c2108..7c8b0f1e6 100644 --- a/lib/legacy/zstd_v01.c +++ b/lib/legacy/zstd_v01.c @@ -1803,7 +1803,7 @@ static size_t ZSTD_execSequence(BYTE* op, } else { ZSTD_copy8(op, match); } op += 8; match += 8; - if (endMatch > oend-12) + if (endMatch > oend-(16-MINMATCH)) { if (op < oend-8) { diff --git a/lib/legacy/zstd_v02.c b/lib/legacy/zstd_v02.c index ed082aad7..135b5bc90 100644 --- a/lib/legacy/zstd_v02.c +++ b/lib/legacy/zstd_v02.c @@ -3206,7 +3206,7 @@ static size_t ZSTD_execSequence(BYTE* op, } op += 8; match += 8; - if (oMatchEnd > oend-12) + if (oMatchEnd > oend-(16-MINMATCH)) { if (op < oend_8) { diff --git a/lib/legacy/zstd_v03.c b/lib/legacy/zstd_v03.c index 321450670..8cb5928fb 100644 --- a/lib/legacy/zstd_v03.c +++ b/lib/legacy/zstd_v03.c @@ -2847,7 +2847,7 @@ static size_t ZSTD_execSequence(BYTE* op, } op += 8; match += 8; - if (oMatchEnd > oend-12) + if (oMatchEnd > oend-(16-MINMATCH)) { if (op < oend_8) { diff --git a/lib/legacy/zstd_v04.c b/lib/legacy/zstd_v04.c index 11b5481a1..60cde97c5 100644 --- a/lib/legacy/zstd_v04.c +++ b/lib/legacy/zstd_v04.c @@ -3107,7 +3107,7 @@ static size_t ZSTD_execSequence(BYTE* op, op = oLitEnd + length1; sequence.matchLength -= length1; match = base; - if (op > oend_8) { + if (op > oend_8 || sequence.matchLength < MINMATCH) { while (op < oMatchEnd) *op++ = *match++; return sequenceLength; } @@ -3134,7 +3134,7 @@ static size_t ZSTD_execSequence(BYTE* op, } op += 8; match += 8; - if (oMatchEnd > oend-12) + if (oMatchEnd > oend-(16-MINMATCH)) { if (op < oend_8) { diff --git a/lib/legacy/zstd_v05.c b/lib/legacy/zstd_v05.c index bf1235a35..3dcf70399 100644 --- a/lib/legacy/zstd_v05.c +++ b/lib/legacy/zstd_v05.c @@ -3325,7 +3325,7 @@ static size_t ZSTDv05_execSequence(BYTE* op, op = oLitEnd + length1; sequence.matchLength -= length1; match = base; - if (op > oend_8) { + if (op > oend_8 || sequence.matchLength < MINMATCH) { while (op < oMatchEnd) *op++ = *match++; return sequenceLength; } @@ -3348,7 +3348,7 @@ static size_t ZSTDv05_execSequence(BYTE* op, } op += 8; match += 8; - if (oMatchEnd > oend-12) { + if (oMatchEnd > oend-(16-MINMATCH)) { if (op < oend_8) { ZSTDv05_wildcopy(op, match, oend_8 - op); match += oend_8 - op; diff --git a/lib/legacy/zstd_v06.c b/lib/legacy/zstd_v06.c index 6584d4858..8aa6dc999 100644 --- a/lib/legacy/zstd_v06.c +++ b/lib/legacy/zstd_v06.c @@ -3470,7 +3470,7 @@ size_t ZSTDv06_execSequence(BYTE* op, op = oLitEnd + length1; sequence.matchLength -= length1; match = base; - if (op > oend_8) { + if (op > oend_8 || sequence.matchLength < MINMATCH) { while (op < oMatchEnd) *op++ = *match++; return sequenceLength; } diff --git a/lib/legacy/zstd_v07.c b/lib/legacy/zstd_v07.c index 2ae6c5ad2..7719ba089 100644 --- a/lib/legacy/zstd_v07.c +++ b/lib/legacy/zstd_v07.c @@ -3693,7 +3693,7 @@ size_t ZSTDv07_execSequence(BYTE* op, op = oLitEnd + length1; sequence.matchLength -= length1; match = base; - if (op > oend_w) { + if (op > oend_w || sequence.matchLength < MINMATCH) { while (op < oMatchEnd) *op++ = *match++; return sequenceLength; } From 064a143520ded4d8410c63220fa9b3630a40c503 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 12 Dec 2016 19:01:23 -0800 Subject: [PATCH 16/17] Fix execSequence wildcopy undefined behavior execSequence relied on pointer overflow to handle cases where `sequence.matchLength < 8`. Instead of passing an `size_t` to wildcopy, pass a `ptrdiff_t`. --- lib/common/zstd_internal.h | 2 +- lib/decompress/zstd_decompress.c | 4 ++-- lib/legacy/zstd_v01.c | 4 ++-- lib/legacy/zstd_v02.c | 4 ++-- lib/legacy/zstd_v03.c | 4 ++-- lib/legacy/zstd_v04.c | 4 ++-- lib/legacy/zstd_v05.c | 4 ++-- lib/legacy/zstd_v06.c | 4 ++-- lib/legacy/zstd_v07.c | 4 ++-- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index a5002fb11..96e057758 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -147,7 +147,7 @@ static void ZSTD_copy8(void* dst, const void* src) { memcpy(dst, src, 8); } /*! ZSTD_wildcopy() : * custom version of memcpy(), can copy up to 7 bytes too many (8 bytes if length==0) */ #define WILDCOPY_OVERLENGTH 8 -MEM_STATIC void ZSTD_wildcopy(void* dst, const void* src, size_t length) +MEM_STATIC void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length) { const BYTE* ip = (const BYTE*)src; BYTE* op = (BYTE*)dst; diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 70dd4ccaa..ce91c0aff 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -997,7 +997,7 @@ size_t ZSTD_execSequence(BYTE* op, } while (op < oMatchEnd) *op++ = *match++; } else { - ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */ + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */ } return sequenceLength; } @@ -1218,7 +1218,7 @@ size_t ZSTD_execSequenceLong(BYTE* op, } while (op < oMatchEnd) *op++ = *match++; } else { - ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */ + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */ } return sequenceLength; } diff --git a/lib/legacy/zstd_v01.c b/lib/legacy/zstd_v01.c index 5c36c2108..376aefe2d 100644 --- a/lib/legacy/zstd_v01.c +++ b/lib/legacy/zstd_v01.c @@ -1354,7 +1354,7 @@ static void ZSTD_copy8(void* dst, const void* src) { memcpy(dst, src, 8); } #define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; } -static void ZSTD_wildcopy(void* dst, const void* src, size_t length) +static void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length) { const BYTE* ip = (const BYTE*)src; BYTE* op = (BYTE*)dst; @@ -1814,7 +1814,7 @@ static size_t ZSTD_execSequence(BYTE* op, while (op Date: Tue, 13 Dec 2016 11:45:19 +0100 Subject: [PATCH 17/17] updated NEWS --- NEWS | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index dc6c93234..35e0e5820 100644 --- a/NEWS +++ b/NEWS @@ -1,18 +1,19 @@ v1.1.2 -Improved : faster decompression speed at ultra compression settings and 32-bits mode +API : streaming : decompression : changed : implicit reset on starting new frames without init +API : experimental : added : dictID retrieval functions +API : zbuff : changed : prototypes now generate deprecation warnings +lib : improved : faster decompression speed at ultra compression settings and 32-bits mode +lib : changed : only public ZSTD_ symbols are now exposed +lib : changed : reduced usage of stack memory +lib : fixed : several corner case bugs, by Nick Terrell cli : new : gzstd, experimental version able to decode .gz files, by Przemyslaw Skibinski cli : new : preserve file attributes cli : new : added zstdless and zstdgrep tools cli : fixed : status displays total amount decoded, even for file consisting of multiple frames (like pzstd) cli : fixed : zstdcat -lib : fixed : bug in streaming compression, by Nick Terrell -lib : changed : only public ZSTD_ symbols are now exposed -API : zbuff : changed : prototypes now generate deprecation warnings -API : streaming : decompression : changed : implicit reset on starting new frames without init -API : experimental : added : dictID retrieval functions zlib_wrapper : added support for gz* functions, by Przemyslaw Skibinski -Changed : zbuff source files moved to lib/deprecated -Changed : reduced stack memory use +install : better compatibility with FreeBSD, by Dimitry Andric +source tree : changed : zbuff source files moved to lib/deprecated v1.1.1 New : command -M#, --memory=, --memlimit=, --memlimit-decompress= to limit allowed memory consumption