summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYann Collet <Cyan4973@users.noreply.github.com>2018-04-28 00:22:06 (GMT)
committerGitHub <noreply@github.com>2018-04-28 00:22:06 (GMT)
commit9d4eae59f05270f12fc0c62851424e186ef4ef6e (patch)
tree3ffc05b86717e06cb23e2e30ec4beb86148c1a4d
parent1e6ca25af3a0906f4b2cd8fd8f9e732bc7ee0eac (diff)
parentd81a434c3dc032779dba6f22a58b127922ef332f (diff)
downloadlz4-9d4eae59f05270f12fc0c62851424e186ef4ef6e.zip
lz4-9d4eae59f05270f12fc0c62851424e186ef4ef6e.tar.gz
lz4-9d4eae59f05270f12fc0c62851424e186ef4ef6e.tar.bz2
Merge pull request #522 from svpv/refactorDec
Refactor dec
-rw-r--r--lib/lz4.c163
-rw-r--r--tests/fullbench.c2
-rw-r--r--tests/fuzzer.c121
3 files changed, 196 insertions, 90 deletions
diff --git a/lib/lz4.c b/lib/lz4.c
index 06ff611..1e0d8e9 100644
--- a/lib/lz4.c
+++ b/lib/lz4.c
@@ -92,6 +92,7 @@
* Dependency
**************************************/
#define LZ4_STATIC_LINKING_ONLY
+#define LZ4_DISABLE_DEPRECATE_WARNINGS /* due to LZ4_decompress_safe_withPrefix64k */
#include "lz4.h"
/* see also "memory routines" below */
@@ -1554,6 +1555,8 @@ _output_error:
}
+/*===== Instantiate the API decoding functions. =====*/
+
LZ4_FORCE_O2_GCC_PPC64LE
int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxDecompressedSize)
{
@@ -1575,9 +1578,76 @@ int LZ4_decompress_fast(const char* source, char* dest, int originalSize)
{
return LZ4_decompress_generic(source, dest, 0, originalSize,
endOnOutputSize, full, 0, withPrefix64k,
- (BYTE*)(dest - 64 KB), NULL, 64 KB);
+ (BYTE*)dest - 64 KB, NULL, 0);
+}
+
+/*===== Instantiate a few more decoding cases, used more than once. =====*/
+
+LZ4_FORCE_O2_GCC_PPC64LE /* Exported, an obsolete API function. */
+int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int compressedSize, int maxOutputSize)
+{
+ return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
+ endOnInputSize, full, 0, withPrefix64k,
+ (BYTE*)dest - 64 KB, NULL, 0);
+}
+
+/* Another obsolete API function, paired with the previous one. */
+int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int originalSize)
+{
+ /* LZ4_decompress_fast doesn't validate match offsets,
+ * and thus serves well with any prefixed dictionary. */
+ return LZ4_decompress_fast(source, dest, originalSize);
+}
+
+LZ4_FORCE_O2_GCC_PPC64LE
+static int LZ4_decompress_safe_withSmallPrefix(const char* source, char* dest, int compressedSize, int maxOutputSize,
+ size_t prefixSize)
+{
+ return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
+ endOnInputSize, full, 0, noDict,
+ (BYTE*)dest-prefixSize, NULL, 0);
}
+LZ4_FORCE_O2_GCC_PPC64LE /* Exported under another name, for tests/fullbench.c */
+#define LZ4_decompress_safe_extDict LZ4_decompress_safe_forceExtDict
+int LZ4_decompress_safe_extDict(const char* source, char* dest, int compressedSize, int maxOutputSize,
+ const void* dictStart, size_t dictSize)
+{
+ return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
+ endOnInputSize, full, 0, usingExtDict,
+ (BYTE*)dest, (const BYTE*)dictStart, dictSize);
+}
+
+LZ4_FORCE_O2_GCC_PPC64LE
+static int LZ4_decompress_fast_extDict(const char* source, char* dest, int originalSize,
+ const void* dictStart, size_t dictSize)
+{
+ return LZ4_decompress_generic(source, dest, 0, originalSize,
+ endOnOutputSize, full, 0, usingExtDict,
+ (BYTE*)dest, (const BYTE*)dictStart, dictSize);
+}
+
+/* The "double dictionary" mode, for use with e.g. ring buffers: the first part
+ * of the dictionary is passed as prefix, and the second via dictStart + dictSize.
+ * These routines are used only once, in LZ4_decompress_*_continue().
+ */
+LZ4_FORCE_INLINE
+int LZ4_decompress_safe_doubleDict(const char* source, char* dest, int compressedSize, int maxOutputSize,
+ size_t prefixSize, const void* dictStart, size_t dictSize)
+{
+ return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
+ endOnInputSize, full, 0, usingExtDict,
+ (BYTE*)dest-prefixSize, (const BYTE*)dictStart, dictSize);
+}
+
+LZ4_FORCE_INLINE
+int LZ4_decompress_fast_doubleDict(const char* source, char* dest, int originalSize,
+ size_t prefixSize, const void* dictStart, size_t dictSize)
+{
+ return LZ4_decompress_generic(source, dest, 0, originalSize,
+ endOnOutputSize, full, 0, usingExtDict,
+ (BYTE*)dest-prefixSize, (const BYTE*)dictStart, dictSize);
+}
/*===== streaming decompression functions =====*/
@@ -1624,19 +1694,32 @@ int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const ch
LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse;
int result;
- if (lz4sd->prefixEnd == (BYTE*)dest) {
- result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
- endOnInputSize, full, 0,
- usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize);
+ if (lz4sd->prefixSize == 0) {
+ /* The first call, no dictionary yet. */
+ assert(lz4sd->extDictSize == 0);
+ result = LZ4_decompress_safe(source, dest, compressedSize, maxOutputSize);
+ if (result <= 0) return result;
+ lz4sd->prefixSize = result;
+ lz4sd->prefixEnd = (BYTE*)dest + result;
+ } else if (lz4sd->prefixEnd == (BYTE*)dest) {
+ /* They're rolling the current segment. */
+ if (lz4sd->prefixSize >= 64 KB - 1)
+ result = LZ4_decompress_safe_withPrefix64k(source, dest, compressedSize, maxOutputSize);
+ else if (lz4sd->extDictSize == 0)
+ result = LZ4_decompress_safe_withSmallPrefix(source, dest, compressedSize, maxOutputSize,
+ lz4sd->prefixSize);
+ else
+ result = LZ4_decompress_safe_doubleDict(source, dest, compressedSize, maxOutputSize,
+ lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize);
if (result <= 0) return result;
lz4sd->prefixSize += result;
lz4sd->prefixEnd += result;
} else {
+ /* The buffer wraps around, or they're switching to another buffer. */
lz4sd->extDictSize = lz4sd->prefixSize;
lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize;
- result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
- endOnInputSize, full, 0,
- usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize);
+ result = LZ4_decompress_safe_extDict(source, dest, compressedSize, maxOutputSize,
+ lz4sd->externalDict, lz4sd->extDictSize);
if (result <= 0) return result;
lz4sd->prefixSize = result;
lz4sd->prefixEnd = (BYTE*)dest + result;
@@ -1651,19 +1734,26 @@ int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const ch
LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse;
int result;
- if (lz4sd->prefixEnd == (BYTE*)dest) {
- result = LZ4_decompress_generic(source, dest, 0, originalSize,
- endOnOutputSize, full, 0,
- usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize);
+ if (lz4sd->prefixSize == 0) {
+ assert(lz4sd->extDictSize == 0);
+ result = LZ4_decompress_fast(source, dest, originalSize);
+ if (result <= 0) return result;
+ lz4sd->prefixSize = originalSize;
+ lz4sd->prefixEnd = (BYTE*)dest + originalSize;
+ } else if (lz4sd->prefixEnd == (BYTE*)dest) {
+ if (lz4sd->prefixSize >= 64 KB - 1 || lz4sd->extDictSize == 0)
+ result = LZ4_decompress_fast(source, dest, originalSize);
+ else
+ result = LZ4_decompress_fast_doubleDict(source, dest, originalSize,
+ lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize);
if (result <= 0) return result;
lz4sd->prefixSize += originalSize;
lz4sd->prefixEnd += originalSize;
} else {
lz4sd->extDictSize = lz4sd->prefixSize;
lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize;
- result = LZ4_decompress_generic(source, dest, 0, originalSize,
- endOnOutputSize, full, 0,
- usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize);
+ result = LZ4_decompress_fast_extDict(source, dest, originalSize,
+ lz4sd->externalDict, lz4sd->extDictSize);
if (result <= 0) return result;
lz4sd->prefixSize = originalSize;
lz4sd->prefixEnd = (BYTE*)dest + originalSize;
@@ -1680,36 +1770,23 @@ Advanced decoding functions :
the dictionary must be explicitly provided within parameters
*/
-LZ4_FORCE_O2_GCC_PPC64LE
-LZ4_FORCE_INLINE int LZ4_decompress_usingDict_generic(const char* source, char* dest, int compressedSize, int maxOutputSize, int safe, const char* dictStart, int dictSize)
+int LZ4_decompress_safe_usingDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize)
{
if (dictSize==0)
- return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest, NULL, 0);
+ return LZ4_decompress_safe(source, dest, compressedSize, maxOutputSize);
if (dictStart+dictSize == dest) {
- if (dictSize >= (int)(64 KB - 1))
- return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, withPrefix64k, (BYTE*)dest-64 KB, NULL, 0);
- return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest-dictSize, NULL, 0);
+ if (dictSize >= 64 KB - 1)
+ return LZ4_decompress_safe_withPrefix64k(source, dest, compressedSize, maxOutputSize);
+ return LZ4_decompress_safe_withSmallPrefix(source, dest, compressedSize, maxOutputSize, dictSize);
}
- return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize);
-}
-
-LZ4_FORCE_O2_GCC_PPC64LE
-int LZ4_decompress_safe_usingDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize)
-{
- return LZ4_decompress_usingDict_generic(source, dest, compressedSize, maxOutputSize, 1, dictStart, dictSize);
+ return LZ4_decompress_safe_extDict(source, dest, compressedSize, maxOutputSize, dictStart, dictSize);
}
-LZ4_FORCE_O2_GCC_PPC64LE
int LZ4_decompress_fast_usingDict(const char* source, char* dest, int originalSize, const char* dictStart, int dictSize)
{
- return LZ4_decompress_usingDict_generic(source, dest, 0, originalSize, 0, dictStart, dictSize);
-}
-
-/* debug function */
-LZ4_FORCE_O2_GCC_PPC64LE
-int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize)
-{
- return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize);
+ if (dictSize==0 || dictStart+dictSize == dest)
+ return LZ4_decompress_fast(source, dest, originalSize);
+ return LZ4_decompress_fast_extDict(source, dest, originalSize, dictStart, dictSize);
}
@@ -1780,16 +1857,4 @@ char* LZ4_slideInputBuffer (void* state)
return (char *)(uptrval)((LZ4_stream_t*)state)->internal_donotuse.dictionary;
}
-/* Obsolete streaming decompression functions */
-
-int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int compressedSize, int maxOutputSize)
-{
- return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB);
-}
-
-int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int originalSize)
-{
- return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB);
-}
-
#endif /* LZ4_COMMONDEFS_ONLY */
diff --git a/tests/fullbench.c b/tests/fullbench.c
index 22199b7..ee2966f 100644
--- a/tests/fullbench.c
+++ b/tests/fullbench.c
@@ -282,7 +282,7 @@ static int local_LZ4_decompress_safe_usingDict(const char* in, char* out, int in
}
#ifndef LZ4_DLL_IMPORT
-extern int LZ4_decompress_safe_forceExtDict(const char* in, char* out, int inSize, int outSize, const char* dict, int dictSize);
+extern int LZ4_decompress_safe_forceExtDict(const char* in, char* out, int inSize, int outSize, const void* dict, size_t dictSize);
static int local_LZ4_decompress_safe_forceExtDict(const char* in, char* out, int inSize, int outSize)
{
diff --git a/tests/fuzzer.c b/tests/fuzzer.c
index 8cd4dec..1fbda8a 100644
--- a/tests/fuzzer.c
+++ b/tests/fuzzer.c
@@ -987,8 +987,8 @@ static void FUZ_unitTests(int compressionLevel)
/* ring buffer test */
{ XXH64_state_t xxhOrig;
- XXH64_state_t xxhNew;
- LZ4_streamDecode_t decodeState;
+ XXH64_state_t xxhNewSafe, xxhNewFast;
+ LZ4_streamDecode_t decodeStateSafe, decodeStateFast;
const U32 maxMessageSizeLog = 10;
const U32 maxMessageSizeMask = (1<<maxMessageSizeLog) - 1;
U32 messageSize = (FUZ_rand(&randState) & maxMessageSizeMask) + 1;
@@ -996,26 +996,36 @@ static void FUZ_unitTests(int compressionLevel)
U32 rNext = 0;
U32 dNext = 0;
const U32 dBufferSize = ringBufferSize + maxMessageSizeMask;
+ int compressedSize;
XXH64_reset(&xxhOrig, 0);
- XXH64_reset(&xxhNew, 0);
+ XXH64_reset(&xxhNewSafe, 0);
+ XXH64_reset(&xxhNewFast, 0);
LZ4_resetStream(&streamingState);
- LZ4_setStreamDecode(&decodeState, NULL, 0);
+ LZ4_setStreamDecode(&decodeStateSafe, NULL, 0);
+ LZ4_setStreamDecode(&decodeStateFast, NULL, 0);
while (iNext + messageSize < testCompressedSize) {
XXH64_update(&xxhOrig, testInput + iNext, messageSize);
crcOrig = XXH64_digest(&xxhOrig);
memcpy (ringBuffer + rNext, testInput + iNext, messageSize);
- result = LZ4_compress_fast_continue(&streamingState, ringBuffer + rNext, testCompressed, messageSize, testCompressedSize-ringBufferSize, 1);
- FUZ_CHECKTEST(result==0, "LZ4_compress_fast_continue() compression failed");
+ compressedSize = LZ4_compress_fast_continue(&streamingState, ringBuffer + rNext, testCompressed, messageSize, testCompressedSize-ringBufferSize, 1);
+ FUZ_CHECKTEST(compressedSize==0, "LZ4_compress_fast_continue() compression failed");
- result = LZ4_decompress_safe_continue(&decodeState, testCompressed, testVerify + dNext, result, messageSize);
- FUZ_CHECKTEST(result!=(int)messageSize, "ringBuffer : LZ4_decompress_safe() test failed");
+ result = LZ4_decompress_safe_continue(&decodeStateSafe, testCompressed, testVerify + dNext, compressedSize, messageSize);
+ FUZ_CHECKTEST(result!=(int)messageSize, "ringBuffer : LZ4_decompress_safe_continue() test failed");
- XXH64_update(&xxhNew, testVerify + dNext, messageSize);
- { U64 const crcNew = XXH64_digest(&xxhNew);
- FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe() decompression corruption"); }
+ XXH64_update(&xxhNewSafe, testVerify + dNext, messageSize);
+ { U64 const crcNew = XXH64_digest(&xxhNewSafe);
+ FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe_continue() decompression corruption"); }
+
+ result = LZ4_decompress_fast_continue(&decodeStateFast, testCompressed, testVerify + dNext, messageSize);
+ FUZ_CHECKTEST(result!=compressedSize, "ringBuffer : LZ4_decompress_fast_continue() test failed");
+
+ XXH64_update(&xxhNewFast, testVerify + dNext, messageSize);
+ { U64 const crcNew = XXH64_digest(&xxhNewFast);
+ FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_fast_continue() decompression corruption"); }
/* prepare next message */
iNext += messageSize;
@@ -1137,8 +1147,8 @@ static void FUZ_unitTests(int compressionLevel)
/* ring buffer test */
{ XXH64_state_t xxhOrig;
- XXH64_state_t xxhNew;
- LZ4_streamDecode_t decodeState;
+ XXH64_state_t xxhNewSafe, xxhNewFast;
+ LZ4_streamDecode_t decodeStateSafe, decodeStateFast;
const U32 maxMessageSizeLog = 10;
const U32 maxMessageSizeMask = (1<<maxMessageSizeLog) - 1;
U32 messageSize = (FUZ_rand(&randState) & maxMessageSizeMask) + 1;
@@ -1146,26 +1156,36 @@ static void FUZ_unitTests(int compressionLevel)
U32 rNext = 0;
U32 dNext = 0;
const U32 dBufferSize = ringBufferSize + maxMessageSizeMask;
+ int compressedSize;
XXH64_reset(&xxhOrig, 0);
- XXH64_reset(&xxhNew, 0);
+ XXH64_reset(&xxhNewSafe, 0);
+ XXH64_reset(&xxhNewFast, 0);
LZ4_resetStreamHC(&sHC, compressionLevel);
- LZ4_setStreamDecode(&decodeState, NULL, 0);
+ LZ4_setStreamDecode(&decodeStateSafe, NULL, 0);
+ LZ4_setStreamDecode(&decodeStateFast, NULL, 0);
while (iNext + messageSize < testCompressedSize) {
XXH64_update(&xxhOrig, testInput + iNext, messageSize);
crcOrig = XXH64_digest(&xxhOrig);
memcpy (ringBuffer + rNext, testInput + iNext, messageSize);
- result = LZ4_compress_HC_continue(&sHC, ringBuffer + rNext, testCompressed, messageSize, testCompressedSize-ringBufferSize);
- FUZ_CHECKTEST(result==0, "LZ4_compressHC_limitedOutput_continue() compression failed");
+ compressedSize = LZ4_compress_HC_continue(&sHC, ringBuffer + rNext, testCompressed, messageSize, testCompressedSize-ringBufferSize);
+ FUZ_CHECKTEST(compressedSize==0, "LZ4_compress_HC_continue() compression failed");
+
+ result = LZ4_decompress_safe_continue(&decodeStateSafe, testCompressed, testVerify + dNext, compressedSize, messageSize);
+ FUZ_CHECKTEST(result!=(int)messageSize, "ringBuffer : LZ4_decompress_safe_continue() test failed");
- result = LZ4_decompress_safe_continue(&decodeState, testCompressed, testVerify + dNext, result, messageSize);
- FUZ_CHECKTEST(result!=(int)messageSize, "ringBuffer : LZ4_decompress_safe() test failed");
+ XXH64_update(&xxhNewSafe, testVerify + dNext, messageSize);
+ { U64 const crcNew = XXH64_digest(&xxhNewSafe);
+ FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe_continue() decompression corruption"); }
- XXH64_update(&xxhNew, testVerify + dNext, messageSize);
- { U64 const crcNew = XXH64_digest(&xxhNew);
- FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe() decompression corruption"); }
+ result = LZ4_decompress_fast_continue(&decodeStateFast, testCompressed, testVerify + dNext, messageSize);
+ FUZ_CHECKTEST(result!=compressedSize, "ringBuffer : LZ4_decompress_fast_continue() test failed");
+
+ XXH64_update(&xxhNewFast, testVerify + dNext, messageSize);
+ { U64 const crcNew = XXH64_digest(&xxhNewFast);
+ FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_fast_continue() decompression corruption"); }
/* prepare next message */
iNext += messageSize;
@@ -1179,8 +1199,8 @@ static void FUZ_unitTests(int compressionLevel)
/* small decoder-side ring buffer test */
{ XXH64_state_t xxhOrig;
- XXH64_state_t xxhNew;
- LZ4_streamDecode_t decodeState;
+ XXH64_state_t xxhNewSafe, xxhNewFast;
+ LZ4_streamDecode_t decodeStateSafe, decodeStateFast;
const U32 maxMessageSizeLog = 12;
const U32 maxMessageSizeMask = (1<<maxMessageSizeLog) - 1;
U32 messageSize;
@@ -1188,11 +1208,14 @@ static void FUZ_unitTests(int compressionLevel)
U32 iNext = 0;
U32 dNext = 0;
const U32 dBufferSize = 64 KB;
+ int compressedSize;
XXH64_reset(&xxhOrig, 0);
- XXH64_reset(&xxhNew, 0);
+ XXH64_reset(&xxhNewSafe, 0);
+ XXH64_reset(&xxhNewFast, 0);
LZ4_resetStreamHC(&sHC, compressionLevel);
- LZ4_setStreamDecode(&decodeState, NULL, 0);
+ LZ4_setStreamDecode(&decodeStateSafe, NULL, 0);
+ LZ4_setStreamDecode(&decodeStateFast, NULL, 0);
#define BSIZE1 65537
#define BSIZE2 16435
@@ -1202,15 +1225,22 @@ static void FUZ_unitTests(int compressionLevel)
XXH64_update(&xxhOrig, testInput + iNext, messageSize);
crcOrig = XXH64_digest(&xxhOrig);
- result = LZ4_compress_HC_continue(&sHC, testInput + iNext, testCompressed, messageSize, testCompressedSize-ringBufferSize);
- FUZ_CHECKTEST(result==0, "LZ4_compressHC_limitedOutput_continue() compression failed");
+ compressedSize = LZ4_compress_HC_continue(&sHC, testInput + iNext, testCompressed, messageSize, testCompressedSize-ringBufferSize);
+ FUZ_CHECKTEST(compressedSize==0, "LZ4_compress_HC_continue() compression failed");
+
+ result = LZ4_decompress_safe_continue(&decodeStateSafe, testCompressed, testVerify + dNext, compressedSize, messageSize);
+ FUZ_CHECKTEST(result!=(int)messageSize, "64K D.ringBuffer : LZ4_decompress_safe_continue() test failed");
- result = LZ4_decompress_safe_continue(&decodeState, testCompressed, testVerify + dNext, result, messageSize);
- FUZ_CHECKTEST(result!=(int)messageSize, "64K D.ringBuffer : LZ4_decompress_safe() test failed");
+ XXH64_update(&xxhNewSafe, testVerify + dNext, messageSize);
+ { U64 const crcNew = XXH64_digest(&xxhNewSafe);
+ FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe_continue() decompression corruption"); }
- XXH64_update(&xxhNew, testVerify + dNext, messageSize);
- { U64 const crcNew = XXH64_digest(&xxhNew);
- FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe() decompression corruption"); }
+ result = LZ4_decompress_fast_continue(&decodeStateFast, testCompressed, testVerify + dNext, messageSize);
+ FUZ_CHECKTEST(result!=compressedSize, "64K D.ringBuffer : LZ4_decompress_fast_continue() test failed");
+
+ XXH64_update(&xxhNewFast, testVerify + dNext, messageSize);
+ { U64 const crcNew = XXH64_digest(&xxhNewFast);
+ FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_fast_continue() decompression corruption"); }
/* prepare next message */
dNext += messageSize;
@@ -1224,17 +1254,28 @@ static void FUZ_unitTests(int compressionLevel)
XXH64_update(&xxhOrig, testInput + iNext, messageSize);
crcOrig = XXH64_digest(&xxhOrig);
- result = LZ4_compress_HC_continue(&sHC, testInput + iNext, testCompressed, messageSize, testCompressedSize-ringBufferSize);
- FUZ_CHECKTEST(result==0, "LZ4_compressHC_limitedOutput_continue() compression failed");
+ compressedSize = LZ4_compress_HC_continue(&sHC, testInput + iNext, testCompressed, messageSize, testCompressedSize-ringBufferSize);
+ FUZ_CHECKTEST(compressedSize==0, "LZ4_compress_HC_continue() compression failed");
- result = LZ4_decompress_safe_continue(&decodeState, testCompressed, testVerify + dNext, result, messageSize);
- FUZ_CHECKTEST(result!=(int)messageSize, "64K D.ringBuffer : LZ4_decompress_safe() test failed");
+#if 1 /* Because the ring buffer is small, decompression overwrites part of the output which
+ * is first used as dictionary. Hence only one decompression function can be tested. */
+ result = LZ4_decompress_safe_continue(&decodeStateSafe, testCompressed, testVerify + dNext, compressedSize, messageSize);
+ FUZ_CHECKTEST(result!=(int)messageSize, "64K D.ringBuffer : LZ4_decompress_safe_continue() test failed");
+ XXH64_update(&xxhNewSafe, testVerify + dNext, messageSize);
+ { U64 const crcNew = XXH64_digest(&xxhNewSafe);
+ if (crcOrig != crcNew) FUZ_findDiff(testInput + iNext, testVerify + dNext);
+ FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe_continue() decompression corruption during small decoder-side ring buffer test");
+ }
+#else
+ result = LZ4_decompress_fast_continue(&decodeStateFast, testCompressed, testVerify + dNext, messageSize);
+ FUZ_CHECKTEST(result!=compressedSize, "64K D.ringBuffer : LZ4_decompress_fast_continue() test failed");
- XXH64_update(&xxhNew, testVerify + dNext, messageSize);
- { U64 const crcNew = XXH64_digest(&xxhNew);
+ XXH64_update(&xxhNewFast, testVerify + dNext, messageSize);
+ { U64 const crcNew = XXH64_digest(&xxhNewFast);
if (crcOrig != crcNew) FUZ_findDiff(testInput + iNext, testVerify + dNext);
- FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe() decompression corruption during small decoder-side ring buffer test");
+ FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_fast_continue() decompression corruption during small decoder-side ring buffer test");
}
+#endif
/* prepare next message */
dNext += messageSize;
totalMessageSize += messageSize;