extlz4 0.3.3 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/Rakefile +43 -3
- data/contrib/lz4/CODING_STYLE +57 -0
- data/contrib/lz4/LICENSE +3 -2
- data/contrib/lz4/Makefile.inc +56 -30
- data/contrib/lz4/NEWS +46 -0
- data/contrib/lz4/README.md +17 -6
- data/contrib/lz4/SECURITY.md +17 -0
- data/contrib/lz4/build/README.md +4 -15
- data/contrib/lz4/build/VS2022/_build.bat +39 -0
- data/contrib/lz4/build/VS2022/_setup.bat +35 -0
- data/contrib/lz4/build/VS2022/_test.bat +38 -0
- data/contrib/lz4/build/VS2022/build-and-test-win32-debug.bat +26 -0
- data/contrib/lz4/build/VS2022/build-and-test-win32-release.bat +26 -0
- data/contrib/lz4/build/VS2022/build-and-test-x64-debug.bat +26 -0
- data/contrib/lz4/build/VS2022/build-and-test-x64-release.bat +26 -0
- data/contrib/lz4/build/{VS2017 → VS2022}/datagen/datagen.vcxproj +11 -7
- data/contrib/lz4/build/{VS2017 → VS2022}/frametest/frametest.vcxproj +4 -4
- data/contrib/lz4/build/{VS2017 → VS2022}/fullbench/fullbench.vcxproj +4 -4
- data/contrib/lz4/build/{VS2017 → VS2022}/fullbench-dll/fullbench-dll.vcxproj +4 -4
- data/contrib/lz4/build/{VS2017 → VS2022}/fuzzer/fuzzer.vcxproj +4 -4
- data/contrib/lz4/build/{VS2017 → VS2022}/liblz4/liblz4.vcxproj +4 -4
- data/contrib/lz4/build/{VS2010 → VS2022}/liblz4-dll/liblz4-dll.rc +1 -1
- data/contrib/lz4/build/{VS2017 → VS2022}/liblz4-dll/liblz4-dll.vcxproj +4 -4
- data/contrib/lz4/build/{VS2010 → VS2022}/lz4/lz4.rc +1 -1
- data/contrib/lz4/build/{VS2017 → VS2022}/lz4/lz4.vcxproj +33 -8
- data/contrib/lz4/build/{VS2017 → VS2022}/lz4.sln +5 -2
- data/contrib/lz4/build/cmake/CMakeLists.txt +133 -100
- data/contrib/lz4/build/cmake/lz4Config.cmake.in +2 -0
- data/contrib/lz4/build/meson/GetLz4LibraryVersion.py +39 -0
- data/contrib/lz4/build/meson/README.md +34 -0
- data/contrib/lz4/build/meson/meson/contrib/gen_manual/meson.build +42 -0
- data/contrib/lz4/build/meson/meson/contrib/meson.build +11 -0
- data/contrib/lz4/build/meson/meson/examples/meson.build +32 -0
- data/contrib/lz4/build/meson/meson/lib/meson.build +87 -0
- data/contrib/lz4/build/meson/meson/meson.build +135 -0
- data/contrib/lz4/build/meson/meson/ossfuzz/meson.build +35 -0
- data/contrib/lz4/build/meson/meson/programs/meson.build +91 -0
- data/contrib/lz4/build/meson/meson/tests/meson.build +162 -0
- data/contrib/lz4/build/meson/meson.build +31 -0
- data/contrib/lz4/build/meson/meson_options.txt +44 -0
- data/contrib/lz4/build/visual/README.md +5 -0
- data/contrib/lz4/build/visual/generate_solution.cmd +55 -0
- data/contrib/lz4/build/visual/generate_vs2015.cmd +3 -0
- data/contrib/lz4/build/visual/generate_vs2017.cmd +3 -0
- data/contrib/lz4/build/visual/generate_vs2019.cmd +3 -0
- data/contrib/lz4/build/visual/generate_vs2022.cmd +3 -0
- data/contrib/lz4/lib/LICENSE +1 -1
- data/contrib/lz4/lib/README.md +69 -13
- data/contrib/lz4/lib/liblz4-dll.rc.in +1 -1
- data/contrib/lz4/lib/liblz4.pc.in +3 -3
- data/contrib/lz4/lib/lz4.c +608 -274
- data/contrib/lz4/lib/lz4.h +212 -102
- data/contrib/lz4/lib/lz4file.c +341 -0
- data/contrib/lz4/lib/lz4file.h +93 -0
- data/contrib/lz4/lib/lz4frame.c +545 -308
- data/contrib/lz4/lib/lz4frame.h +252 -124
- data/contrib/lz4/lib/lz4frame_static.h +1 -1
- data/contrib/lz4/lib/lz4hc.c +1038 -461
- data/contrib/lz4/lib/lz4hc.h +57 -56
- data/contrib/lz4/lib/xxhash.c +21 -21
- data/contrib/lz4/ossfuzz/Makefile +1 -0
- data/contrib/lz4/ossfuzz/decompress_fuzzer.c +18 -2
- data/contrib/lz4/ossfuzz/fuzz_helpers.h +4 -3
- data/contrib/lz4/ossfuzz/round_trip_frame_uncompressed_fuzzer.c +134 -0
- data/contrib/lz4/ossfuzz/round_trip_fuzzer.c +66 -6
- data/ext/blockapi.c +19 -19
- data/ext/extlz4.h +12 -0
- data/ext/frameapi.c +26 -26
- data/ext/hashargs.c +7 -1
- metadata +47 -30
- data/contrib/lz4/build/VS2010/datagen/datagen.vcxproj +0 -169
- data/contrib/lz4/build/VS2010/frametest/frametest.vcxproj +0 -176
- data/contrib/lz4/build/VS2010/fullbench/fullbench.vcxproj +0 -176
- data/contrib/lz4/build/VS2010/fullbench-dll/fullbench-dll.vcxproj +0 -180
- data/contrib/lz4/build/VS2010/fuzzer/fuzzer.vcxproj +0 -173
- data/contrib/lz4/build/VS2010/liblz4/liblz4.vcxproj +0 -175
- data/contrib/lz4/build/VS2010/liblz4-dll/liblz4-dll.vcxproj +0 -179
- data/contrib/lz4/build/VS2010/lz4/lz4.vcxproj +0 -189
- data/contrib/lz4/build/VS2010/lz4.sln +0 -98
- data/contrib/lz4/build/VS2017/liblz4-dll/liblz4-dll.rc +0 -51
- data/contrib/lz4/build/VS2017/lz4/lz4.rc +0 -51
- data/contrib/lz4/tmp +0 -0
- data/contrib/lz4/tmpsparse +0 -0
data/contrib/lz4/lib/lz4hc.h
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
LZ4 HC - High Compression Mode of LZ4
|
3
3
|
Header File
|
4
|
-
Copyright (C) 2011-
|
4
|
+
Copyright (C) 2011-2020, Yann Collet.
|
5
5
|
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
6
6
|
|
7
7
|
Redistribution and use in source and binary forms, with or without
|
@@ -44,7 +44,7 @@ extern "C" {
|
|
44
44
|
|
45
45
|
|
46
46
|
/* --- Useful constants --- */
|
47
|
-
#define LZ4HC_CLEVEL_MIN
|
47
|
+
#define LZ4HC_CLEVEL_MIN 2
|
48
48
|
#define LZ4HC_CLEVEL_DEFAULT 9
|
49
49
|
#define LZ4HC_CLEVEL_OPT_MIN 10
|
50
50
|
#define LZ4HC_CLEVEL_MAX 12
|
@@ -126,6 +126,8 @@ LZ4LIB_API int LZ4_freeStreamHC (LZ4_streamHC_t* streamHCPtr);
|
|
126
126
|
|
127
127
|
After reset, a first "fictional block" can be designated as initial dictionary,
|
128
128
|
using LZ4_loadDictHC() (Optional).
|
129
|
+
Note: In order for LZ4_loadDictHC() to create the correct data structure,
|
130
|
+
it is essential to set the compression level _before_ loading the dictionary.
|
129
131
|
|
130
132
|
Invoke LZ4_compress_HC_continue() to compress each successive block.
|
131
133
|
The number of blocks is unlimited.
|
@@ -135,12 +137,12 @@ LZ4LIB_API int LZ4_freeStreamHC (LZ4_streamHC_t* streamHCPtr);
|
|
135
137
|
It's allowed to update compression level anytime between blocks,
|
136
138
|
using LZ4_setCompressionLevel() (experimental).
|
137
139
|
|
138
|
-
|
140
|
+
@dst buffer should be sized to handle worst case scenarios
|
139
141
|
(see LZ4_compressBound(), it ensures compression success).
|
140
142
|
In case of failure, the API does not guarantee recovery,
|
141
143
|
so the state _must_ be reset.
|
142
144
|
To ensure compression success
|
143
|
-
whenever
|
145
|
+
whenever @dst buffer size cannot be made >= LZ4_compressBound(),
|
144
146
|
consider using LZ4_compress_HC_continue_destSize().
|
145
147
|
|
146
148
|
Whenever previous input blocks can't be preserved unmodified in-place during compression of next blocks,
|
@@ -176,6 +178,34 @@ LZ4LIB_API int LZ4_compress_HC_continue_destSize(LZ4_streamHC_t* LZ4_streamHCPtr
|
|
176
178
|
LZ4LIB_API int LZ4_saveDictHC (LZ4_streamHC_t* streamHCPtr, char* safeBuffer, int maxDictSize);
|
177
179
|
|
178
180
|
|
181
|
+
/*! LZ4_attach_HC_dictionary() : stable since v1.10.0
|
182
|
+
* This API allows for the efficient re-use of a static dictionary many times.
|
183
|
+
*
|
184
|
+
* Rather than re-loading the dictionary buffer into a working context before
|
185
|
+
* each compression, or copying a pre-loaded dictionary's LZ4_streamHC_t into a
|
186
|
+
* working LZ4_streamHC_t, this function introduces a no-copy setup mechanism,
|
187
|
+
* in which the working stream references the dictionary stream in-place.
|
188
|
+
*
|
189
|
+
* Several assumptions are made about the state of the dictionary stream.
|
190
|
+
* Currently, only streams which have been prepared by LZ4_loadDictHC() should
|
191
|
+
* be expected to work.
|
192
|
+
*
|
193
|
+
* Alternatively, the provided dictionary stream pointer may be NULL, in which
|
194
|
+
* case any existing dictionary stream is unset.
|
195
|
+
*
|
196
|
+
* A dictionary should only be attached to a stream without any history (i.e.,
|
197
|
+
* a stream that has just been reset).
|
198
|
+
*
|
199
|
+
* The dictionary will remain attached to the working stream only for the
|
200
|
+
* current stream session. Calls to LZ4_resetStreamHC(_fast) will remove the
|
201
|
+
* dictionary context association from the working stream. The dictionary
|
202
|
+
* stream (and source buffer) must remain in-place / accessible / unchanged
|
203
|
+
* through the lifetime of the stream session.
|
204
|
+
*/
|
205
|
+
LZ4LIB_API void
|
206
|
+
LZ4_attach_HC_dictionary(LZ4_streamHC_t* working_stream,
|
207
|
+
const LZ4_streamHC_t* dictionary_stream);
|
208
|
+
|
179
209
|
|
180
210
|
/*^**********************************************
|
181
211
|
* !!!!!! STATIC LINKING ONLY !!!!!!
|
@@ -198,38 +228,36 @@ LZ4LIB_API int LZ4_saveDictHC (LZ4_streamHC_t* streamHCPtr, char* safeBuffer, in
|
|
198
228
|
#define LZ4HC_HASH_MASK (LZ4HC_HASHTABLESIZE - 1)
|
199
229
|
|
200
230
|
|
231
|
+
/* Never ever use these definitions directly !
|
232
|
+
* Declare or allocate an LZ4_streamHC_t instead.
|
233
|
+
**/
|
201
234
|
typedef struct LZ4HC_CCtx_internal LZ4HC_CCtx_internal;
|
202
235
|
struct LZ4HC_CCtx_internal
|
203
236
|
{
|
204
|
-
LZ4_u32
|
205
|
-
LZ4_u16
|
206
|
-
const LZ4_byte* end;
|
207
|
-
const LZ4_byte*
|
208
|
-
const LZ4_byte*
|
209
|
-
LZ4_u32
|
210
|
-
LZ4_u32
|
211
|
-
LZ4_u32
|
212
|
-
short
|
213
|
-
LZ4_i8
|
214
|
-
|
215
|
-
LZ4_i8
|
237
|
+
LZ4_u32 hashTable[LZ4HC_HASHTABLESIZE];
|
238
|
+
LZ4_u16 chainTable[LZ4HC_MAXD];
|
239
|
+
const LZ4_byte* end; /* next block here to continue on current prefix */
|
240
|
+
const LZ4_byte* prefixStart; /* Indexes relative to this position */
|
241
|
+
const LZ4_byte* dictStart; /* alternate reference for extDict */
|
242
|
+
LZ4_u32 dictLimit; /* below that point, need extDict */
|
243
|
+
LZ4_u32 lowLimit; /* below that point, no more history */
|
244
|
+
LZ4_u32 nextToUpdate; /* index from which to continue dictionary update */
|
245
|
+
short compressionLevel;
|
246
|
+
LZ4_i8 favorDecSpeed; /* favor decompression speed if this flag set,
|
247
|
+
otherwise, favor compression ratio */
|
248
|
+
LZ4_i8 dirty; /* stream has to be fully reset if this flag is set */
|
216
249
|
const LZ4HC_CCtx_internal* dictCtx;
|
217
250
|
};
|
218
251
|
|
219
|
-
|
220
|
-
/* Do not use these definitions directly !
|
221
|
-
* Declare or allocate an LZ4_streamHC_t instead.
|
222
|
-
*/
|
223
|
-
#define LZ4_STREAMHCSIZE 262200 /* static size, for inter-version compatibility */
|
224
|
-
#define LZ4_STREAMHCSIZE_VOIDP (LZ4_STREAMHCSIZE / sizeof(void*))
|
252
|
+
#define LZ4_STREAMHC_MINSIZE 262200 /* static size, for inter-version compatibility */
|
225
253
|
union LZ4_streamHC_u {
|
226
|
-
|
254
|
+
char minStateSize[LZ4_STREAMHC_MINSIZE];
|
227
255
|
LZ4HC_CCtx_internal internal_donotuse;
|
228
256
|
}; /* previously typedef'd to LZ4_streamHC_t */
|
229
257
|
|
230
258
|
/* LZ4_streamHC_t :
|
231
259
|
* This structure allows static allocation of LZ4 HC streaming state.
|
232
|
-
* This can be used to allocate statically
|
260
|
+
* This can be used to allocate statically on stack, or as part of a larger structure.
|
233
261
|
*
|
234
262
|
* Such state **must** be initialized using LZ4_initStreamHC() before first use.
|
235
263
|
*
|
@@ -244,7 +272,7 @@ union LZ4_streamHC_u {
|
|
244
272
|
* Required before first use of a statically allocated LZ4_streamHC_t.
|
245
273
|
* Before v1.9.0 : use LZ4_resetStreamHC() instead
|
246
274
|
*/
|
247
|
-
LZ4LIB_API LZ4_streamHC_t* LZ4_initStreamHC
|
275
|
+
LZ4LIB_API LZ4_streamHC_t* LZ4_initStreamHC(void* buffer, size_t size);
|
248
276
|
|
249
277
|
|
250
278
|
/*-************************************
|
@@ -272,9 +300,11 @@ LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_comp
|
|
272
300
|
* LZ4_slideInputBufferHC() will truncate the history of the stream, rather
|
273
301
|
* than preserve a window-sized chunk of history.
|
274
302
|
*/
|
303
|
+
#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION)
|
275
304
|
LZ4_DEPRECATED("use LZ4_createStreamHC() instead") LZ4LIB_API void* LZ4_createHC (const char* inputBuffer);
|
276
|
-
LZ4_DEPRECATED("use LZ4_saveDictHC() instead") LZ4LIB_API char* LZ4_slideInputBufferHC (void* LZ4HC_Data);
|
277
305
|
LZ4_DEPRECATED("use LZ4_freeStreamHC() instead") LZ4LIB_API int LZ4_freeHC (void* LZ4HC_Data);
|
306
|
+
#endif
|
307
|
+
LZ4_DEPRECATED("use LZ4_saveDictHC() instead") LZ4LIB_API char* LZ4_slideInputBufferHC (void* LZ4HC_Data);
|
278
308
|
LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel);
|
279
309
|
LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
|
280
310
|
LZ4_DEPRECATED("use LZ4_createStreamHC() instead") LZ4LIB_API int LZ4_sizeofStreamStateHC(void);
|
@@ -305,7 +335,7 @@ LZ4LIB_API void LZ4_resetStreamHC (LZ4_streamHC_t* streamHCPtr, int compressionL
|
|
305
335
|
* They should not be linked from DLL,
|
306
336
|
* as there is no guarantee of API stability yet.
|
307
337
|
* Prototypes will be promoted to "stable" status
|
308
|
-
* after
|
338
|
+
* after successful usage in real-life scenarios.
|
309
339
|
***************************************************/
|
310
340
|
#ifdef LZ4_HC_STATIC_LINKING_ONLY /* protection macro */
|
311
341
|
#ifndef LZ4_HC_SLO_098092834
|
@@ -376,35 +406,6 @@ LZ4LIB_STATIC_API int LZ4_compress_HC_extStateHC_fastReset (
|
|
376
406
|
int srcSize, int dstCapacity,
|
377
407
|
int compressionLevel);
|
378
408
|
|
379
|
-
/*! LZ4_attach_HC_dictionary() :
|
380
|
-
* This is an experimental API that allows for the efficient use of a
|
381
|
-
* static dictionary many times.
|
382
|
-
*
|
383
|
-
* Rather than re-loading the dictionary buffer into a working context before
|
384
|
-
* each compression, or copying a pre-loaded dictionary's LZ4_streamHC_t into a
|
385
|
-
* working LZ4_streamHC_t, this function introduces a no-copy setup mechanism,
|
386
|
-
* in which the working stream references the dictionary stream in-place.
|
387
|
-
*
|
388
|
-
* Several assumptions are made about the state of the dictionary stream.
|
389
|
-
* Currently, only streams which have been prepared by LZ4_loadDictHC() should
|
390
|
-
* be expected to work.
|
391
|
-
*
|
392
|
-
* Alternatively, the provided dictionary stream pointer may be NULL, in which
|
393
|
-
* case any existing dictionary stream is unset.
|
394
|
-
*
|
395
|
-
* A dictionary should only be attached to a stream without any history (i.e.,
|
396
|
-
* a stream that has just been reset).
|
397
|
-
*
|
398
|
-
* The dictionary will remain attached to the working stream only for the
|
399
|
-
* current stream session. Calls to LZ4_resetStreamHC(_fast) will remove the
|
400
|
-
* dictionary context association from the working stream. The dictionary
|
401
|
-
* stream (and source buffer) must remain in-place / accessible / unchanged
|
402
|
-
* through the lifetime of the stream session.
|
403
|
-
*/
|
404
|
-
LZ4LIB_STATIC_API void LZ4_attach_HC_dictionary(
|
405
|
-
LZ4_streamHC_t *working_stream,
|
406
|
-
const LZ4_streamHC_t *dictionary_stream);
|
407
|
-
|
408
409
|
#if defined (__cplusplus)
|
409
410
|
}
|
410
411
|
#endif
|
data/contrib/lz4/lib/xxhash.c
CHANGED
@@ -120,12 +120,12 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcp
|
|
120
120
|
/* *************************************
|
121
121
|
* Compiler Specific Options
|
122
122
|
***************************************/
|
123
|
-
#
|
123
|
+
#if defined (_MSC_VER) && !defined (__clang__) /* MSVC */
|
124
124
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
125
125
|
# define FORCE_INLINE static __forceinline
|
126
126
|
#else
|
127
127
|
# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
|
128
|
-
#
|
128
|
+
# if defined (__GNUC__) || defined (__clang__)
|
129
129
|
# define FORCE_INLINE static inline __attribute__((always_inline))
|
130
130
|
# else
|
131
131
|
# define FORCE_INLINE static inline
|
@@ -213,7 +213,7 @@ static U32 XXH_swap32 (U32 x)
|
|
213
213
|
/* *************************************
|
214
214
|
* Architecture Macros
|
215
215
|
***************************************/
|
216
|
-
typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 }
|
216
|
+
typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianness;
|
217
217
|
|
218
218
|
/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */
|
219
219
|
#ifndef XXH_CPU_LITTLE_ENDIAN
|
@@ -231,7 +231,7 @@ static int XXH_isLittleEndian(void)
|
|
231
231
|
*****************************/
|
232
232
|
typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
|
233
233
|
|
234
|
-
FORCE_INLINE U32 XXH_readLE32_align(const void* ptr,
|
234
|
+
FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianness endian, XXH_alignment align)
|
235
235
|
{
|
236
236
|
if (align==XXH_unaligned)
|
237
237
|
return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr));
|
@@ -239,7 +239,7 @@ FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_a
|
|
239
239
|
return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr);
|
240
240
|
}
|
241
241
|
|
242
|
-
FORCE_INLINE U32 XXH_readLE32(const void* ptr,
|
242
|
+
FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianness endian)
|
243
243
|
{
|
244
244
|
return XXH_readLE32_align(ptr, endian, XXH_unaligned);
|
245
245
|
}
|
@@ -289,7 +289,7 @@ static U32 XXH32_avalanche(U32 h32)
|
|
289
289
|
|
290
290
|
static U32
|
291
291
|
XXH32_finalize(U32 h32, const void* ptr, size_t len,
|
292
|
-
|
292
|
+
XXH_endianness endian, XXH_alignment align)
|
293
293
|
|
294
294
|
{
|
295
295
|
const BYTE* p = (const BYTE*)ptr;
|
@@ -350,7 +350,7 @@ XXH32_finalize(U32 h32, const void* ptr, size_t len,
|
|
350
350
|
|
351
351
|
FORCE_INLINE U32
|
352
352
|
XXH32_endian_align(const void* input, size_t len, U32 seed,
|
353
|
-
|
353
|
+
XXH_endianness endian, XXH_alignment align)
|
354
354
|
{
|
355
355
|
const BYTE* p = (const BYTE*)input;
|
356
356
|
const BYTE* bEnd = p + len;
|
@@ -398,7 +398,7 @@ XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int s
|
|
398
398
|
XXH32_update(&state, input, len);
|
399
399
|
return XXH32_digest(&state);
|
400
400
|
#else
|
401
|
-
|
401
|
+
XXH_endianness endian_detected = (XXH_endianness)XXH_CPU_LITTLE_ENDIAN;
|
402
402
|
|
403
403
|
if (XXH_FORCE_ALIGN_CHECK) {
|
404
404
|
if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */
|
@@ -449,7 +449,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int s
|
|
449
449
|
|
450
450
|
|
451
451
|
FORCE_INLINE XXH_errorcode
|
452
|
-
XXH32_update_endian(XXH32_state_t* state, const void* input, size_t len,
|
452
|
+
XXH32_update_endian(XXH32_state_t* state, const void* input, size_t len, XXH_endianness endian)
|
453
453
|
{
|
454
454
|
if (input==NULL)
|
455
455
|
#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)
|
@@ -514,7 +514,7 @@ XXH32_update_endian(XXH32_state_t* state, const void* input, size_t len, XXH_end
|
|
514
514
|
|
515
515
|
XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len)
|
516
516
|
{
|
517
|
-
|
517
|
+
XXH_endianness endian_detected = (XXH_endianness)XXH_CPU_LITTLE_ENDIAN;
|
518
518
|
|
519
519
|
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
520
520
|
return XXH32_update_endian(state_in, input, len, XXH_littleEndian);
|
@@ -524,7 +524,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void*
|
|
524
524
|
|
525
525
|
|
526
526
|
FORCE_INLINE U32
|
527
|
-
XXH32_digest_endian (const XXH32_state_t* state,
|
527
|
+
XXH32_digest_endian (const XXH32_state_t* state, XXH_endianness endian)
|
528
528
|
{
|
529
529
|
U32 h32;
|
530
530
|
|
@@ -545,7 +545,7 @@ XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian)
|
|
545
545
|
|
546
546
|
XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in)
|
547
547
|
{
|
548
|
-
|
548
|
+
XXH_endianness endian_detected = (XXH_endianness)XXH_CPU_LITTLE_ENDIAN;
|
549
549
|
|
550
550
|
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
551
551
|
return XXH32_digest_endian(state_in, XXH_littleEndian);
|
@@ -642,7 +642,7 @@ static U64 XXH_swap64 (U64 x)
|
|
642
642
|
}
|
643
643
|
#endif
|
644
644
|
|
645
|
-
FORCE_INLINE U64 XXH_readLE64_align(const void* ptr,
|
645
|
+
FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianness endian, XXH_alignment align)
|
646
646
|
{
|
647
647
|
if (align==XXH_unaligned)
|
648
648
|
return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr));
|
@@ -650,7 +650,7 @@ FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_a
|
|
650
650
|
return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr);
|
651
651
|
}
|
652
652
|
|
653
|
-
FORCE_INLINE U64 XXH_readLE64(const void* ptr,
|
653
|
+
FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianness endian)
|
654
654
|
{
|
655
655
|
return XXH_readLE64_align(ptr, endian, XXH_unaligned);
|
656
656
|
}
|
@@ -700,7 +700,7 @@ static U64 XXH64_avalanche(U64 h64)
|
|
700
700
|
|
701
701
|
static U64
|
702
702
|
XXH64_finalize(U64 h64, const void* ptr, size_t len,
|
703
|
-
|
703
|
+
XXH_endianness endian, XXH_alignment align)
|
704
704
|
{
|
705
705
|
const BYTE* p = (const BYTE*)ptr;
|
706
706
|
|
@@ -809,7 +809,7 @@ XXH64_finalize(U64 h64, const void* ptr, size_t len,
|
|
809
809
|
|
810
810
|
FORCE_INLINE U64
|
811
811
|
XXH64_endian_align(const void* input, size_t len, U64 seed,
|
812
|
-
|
812
|
+
XXH_endianness endian, XXH_alignment align)
|
813
813
|
{
|
814
814
|
const BYTE* p = (const BYTE*)input;
|
815
815
|
const BYTE* bEnd = p + len;
|
@@ -861,7 +861,7 @@ XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned
|
|
861
861
|
XXH64_update(&state, input, len);
|
862
862
|
return XXH64_digest(&state);
|
863
863
|
#else
|
864
|
-
|
864
|
+
XXH_endianness endian_detected = (XXH_endianness)XXH_CPU_LITTLE_ENDIAN;
|
865
865
|
|
866
866
|
if (XXH_FORCE_ALIGN_CHECK) {
|
867
867
|
if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */
|
@@ -909,7 +909,7 @@ XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long
|
|
909
909
|
}
|
910
910
|
|
911
911
|
FORCE_INLINE XXH_errorcode
|
912
|
-
XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len,
|
912
|
+
XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianness endian)
|
913
913
|
{
|
914
914
|
if (input==NULL)
|
915
915
|
#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)
|
@@ -970,7 +970,7 @@ XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_en
|
|
970
970
|
|
971
971
|
XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len)
|
972
972
|
{
|
973
|
-
|
973
|
+
XXH_endianness endian_detected = (XXH_endianness)XXH_CPU_LITTLE_ENDIAN;
|
974
974
|
|
975
975
|
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
976
976
|
return XXH64_update_endian(state_in, input, len, XXH_littleEndian);
|
@@ -978,7 +978,7 @@ XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void*
|
|
978
978
|
return XXH64_update_endian(state_in, input, len, XXH_bigEndian);
|
979
979
|
}
|
980
980
|
|
981
|
-
FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state,
|
981
|
+
FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianness endian)
|
982
982
|
{
|
983
983
|
U64 h64;
|
984
984
|
|
@@ -1004,7 +1004,7 @@ FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess
|
|
1004
1004
|
|
1005
1005
|
XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* state_in)
|
1006
1006
|
{
|
1007
|
-
|
1007
|
+
XXH_endianness endian_detected = (XXH_endianness)XXH_CPU_LITTLE_ENDIAN;
|
1008
1008
|
|
1009
1009
|
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
1010
1010
|
return XXH64_digest_endian(state_in, XXH_littleEndian);
|
@@ -39,7 +39,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
|
39
39
|
/* No dictionary. */
|
40
40
|
LZ4_decompress_safe_usingDict((char const*)data, dst, size,
|
41
41
|
dstCapacity, NULL, 0);
|
42
|
-
/* Small external
|
42
|
+
/* Small external dictionary. */
|
43
43
|
LZ4_decompress_safe_usingDict((char const*)data, dst, size,
|
44
44
|
dstCapacity, smallDict, smallDictSize);
|
45
45
|
/* Large external dictionary. */
|
@@ -49,11 +49,27 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
|
49
49
|
LZ4_decompress_safe_usingDict((char const*)dataAfterDict, dst, size,
|
50
50
|
dstCapacity, smallDict, smallDictSize);
|
51
51
|
/* Large prefix. */
|
52
|
-
LZ4_decompress_safe_usingDict((char const*)
|
52
|
+
LZ4_decompress_safe_usingDict((char const*)dataAfterDict, dst, size,
|
53
53
|
dstCapacity, largeDict, largeDictSize);
|
54
54
|
/* Partial decompression. */
|
55
55
|
LZ4_decompress_safe_partial((char const*)data, dst, size,
|
56
56
|
dstCapacity, dstCapacity);
|
57
|
+
/* Partial decompression using each possible dictionary configuration. */
|
58
|
+
/* Partial decompression with no dictionary. */
|
59
|
+
LZ4_decompress_safe_partial_usingDict((char const*)data, dst, size,
|
60
|
+
dstCapacity, dstCapacity, NULL, 0);
|
61
|
+
/* Partial decompression with small external dictionary. */
|
62
|
+
LZ4_decompress_safe_partial_usingDict((char const*)data, dst, size,
|
63
|
+
dstCapacity, dstCapacity, smallDict, smallDictSize);
|
64
|
+
/* Partial decompression with large external dictionary. */
|
65
|
+
LZ4_decompress_safe_partial_usingDict((char const*)data, dst, size,
|
66
|
+
dstCapacity, dstCapacity, largeDict, largeDictSize);
|
67
|
+
/* Partial decompression with small prefix. */
|
68
|
+
LZ4_decompress_safe_partial_usingDict((char const*)dataAfterDict, dst, size,
|
69
|
+
dstCapacity, dstCapacity, smallDict, smallDictSize);
|
70
|
+
/* Partial decompression with large prefix. */
|
71
|
+
LZ4_decompress_safe_partial_usingDict((char const*)dataAfterDict, dst, size,
|
72
|
+
dstCapacity, dstCapacity, largeDict, largeDictSize);
|
57
73
|
free(dst);
|
58
74
|
free(dict);
|
59
75
|
FUZZ_dataProducer_free(producer);
|
@@ -4,7 +4,8 @@
|
|
4
4
|
*
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
6
6
|
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
7
|
-
* in the COPYING file in the root directory of this source tree)
|
7
|
+
* in the COPYING file in the root directory of this source tree),
|
8
|
+
* meaning you may select, at your option, one of the above-listed licenses.
|
8
9
|
*/
|
9
10
|
|
10
11
|
/**
|
@@ -43,7 +44,7 @@ extern "C" {
|
|
43
44
|
: (fprintf(stderr, "%s: %u: Assertion: `%s' failed. %s\n", __FILE__, \
|
44
45
|
__LINE__, FUZZ_QUOTE(cond), (msg)), \
|
45
46
|
abort()))
|
46
|
-
#define FUZZ_ASSERT(cond) FUZZ_ASSERT_MSG((cond), "")
|
47
|
+
#define FUZZ_ASSERT(cond) FUZZ_ASSERT_MSG((cond), "")
|
47
48
|
|
48
49
|
#if defined(__GNUC__)
|
49
50
|
#define FUZZ_STATIC static __inline __attribute__((unused))
|
@@ -81,7 +82,7 @@ FUZZ_STATIC uint32_t FUZZ_rand(uint32_t *state) {
|
|
81
82
|
return rand32 >> 5;
|
82
83
|
}
|
83
84
|
|
84
|
-
/* Returns a random
|
85
|
+
/* Returns a random number in the range [min, max]. */
|
85
86
|
FUZZ_STATIC uint32_t FUZZ_rand32(uint32_t *state, uint32_t min, uint32_t max) {
|
86
87
|
uint32_t random = FUZZ_rand(state);
|
87
88
|
return min + (random % (max - min + 1));
|
@@ -0,0 +1,134 @@
|
|
1
|
+
/**
|
2
|
+
* This fuzz target performs a lz4 round-trip test (compress & decompress),
|
3
|
+
* compares the result with the original, and calls abort() on corruption.
|
4
|
+
*/
|
5
|
+
|
6
|
+
#include <stddef.h>
|
7
|
+
#include <stdint.h>
|
8
|
+
#include <stdlib.h>
|
9
|
+
#include <string.h>
|
10
|
+
|
11
|
+
#include "fuzz_data_producer.h"
|
12
|
+
#include "fuzz_helpers.h"
|
13
|
+
#include "lz4.h"
|
14
|
+
#include "lz4_helpers.h"
|
15
|
+
#include "lz4frame.h"
|
16
|
+
#include "lz4frame_static.h"
|
17
|
+
|
18
|
+
static void decompress(LZ4F_dctx *dctx, void *src, void *dst,
|
19
|
+
size_t dstCapacity, size_t readSize) {
|
20
|
+
size_t ret = 1;
|
21
|
+
const void *srcPtr = (const char *) src;
|
22
|
+
void *dstPtr = (char *) dst;
|
23
|
+
const void *const srcEnd = (const char *) srcPtr + readSize;
|
24
|
+
|
25
|
+
while (ret != 0) {
|
26
|
+
while (srcPtr < srcEnd && ret != 0) {
|
27
|
+
/* Any data within dst has been flushed at this stage */
|
28
|
+
size_t dstSize = dstCapacity;
|
29
|
+
size_t srcSize = (const char *) srcEnd - (const char *) srcPtr;
|
30
|
+
ret = LZ4F_decompress(dctx, dstPtr, &dstSize, srcPtr, &srcSize,
|
31
|
+
/* LZ4F_decompressOptions_t */ NULL);
|
32
|
+
FUZZ_ASSERT(!LZ4F_isError(ret));
|
33
|
+
|
34
|
+
/* Update input */
|
35
|
+
srcPtr = (const char *) srcPtr + srcSize;
|
36
|
+
dstPtr = (char *) dstPtr + dstSize;
|
37
|
+
}
|
38
|
+
|
39
|
+
FUZZ_ASSERT(srcPtr <= srcEnd);
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
static void compress_round_trip(const uint8_t *data, size_t size,
|
44
|
+
FUZZ_dataProducer_t *producer, LZ4F_preferences_t const prefs) {
|
45
|
+
|
46
|
+
// Choose random uncompressed offset start and end by producing seeds from random data, calculate the remaining
|
47
|
+
// data size that will be used for compression later and use the seeds to actually calculate the offsets
|
48
|
+
size_t const uncompressedOffsetSeed = FUZZ_dataProducer_retrieve32(producer);
|
49
|
+
size_t const uncompressedEndOffsetSeed = FUZZ_dataProducer_retrieve32(producer);
|
50
|
+
size = FUZZ_dataProducer_remainingBytes(producer);
|
51
|
+
|
52
|
+
size_t const uncompressedOffset = FUZZ_getRange_from_uint32(uncompressedOffsetSeed, 0, size);
|
53
|
+
size_t const uncompressedEndOffset = FUZZ_getRange_from_uint32(uncompressedEndOffsetSeed, uncompressedOffset, size);
|
54
|
+
size_t const uncompressedSize = uncompressedEndOffset - uncompressedOffset;
|
55
|
+
FUZZ_ASSERT(uncompressedOffset <= uncompressedEndOffset);
|
56
|
+
FUZZ_ASSERT(uncompressedEndOffset <= size);
|
57
|
+
|
58
|
+
const uint8_t *const uncompressedData = data + uncompressedOffset;
|
59
|
+
|
60
|
+
size_t const dstCapacity =
|
61
|
+
LZ4F_compressFrameBound(LZ4_compressBound(size), &prefs) +
|
62
|
+
uncompressedSize;
|
63
|
+
char *const dst = (char *) malloc(dstCapacity);
|
64
|
+
size_t rtCapacity = dstCapacity;
|
65
|
+
char *const rt = (char *) malloc(rtCapacity);
|
66
|
+
|
67
|
+
FUZZ_ASSERT(dst);
|
68
|
+
FUZZ_ASSERT(rt);
|
69
|
+
|
70
|
+
/* Compression must succeed and round trip correctly. */
|
71
|
+
LZ4F_compressionContext_t ctx;
|
72
|
+
size_t const ctxCreation = LZ4F_createCompressionContext(&ctx, LZ4F_VERSION);
|
73
|
+
FUZZ_ASSERT(!LZ4F_isError(ctxCreation));
|
74
|
+
|
75
|
+
size_t const headerSize = LZ4F_compressBegin(ctx, dst, dstCapacity, &prefs);
|
76
|
+
FUZZ_ASSERT(!LZ4F_isError(headerSize));
|
77
|
+
size_t compressedSize = headerSize;
|
78
|
+
|
79
|
+
/* Compress data before uncompressed offset */
|
80
|
+
size_t lz4Return = LZ4F_compressUpdate(ctx, dst + compressedSize, dstCapacity,
|
81
|
+
data, uncompressedOffset, NULL);
|
82
|
+
FUZZ_ASSERT(!LZ4F_isError(lz4Return));
|
83
|
+
compressedSize += lz4Return;
|
84
|
+
|
85
|
+
/* Add uncompressed data */
|
86
|
+
lz4Return = LZ4F_uncompressedUpdate(ctx, dst + compressedSize, dstCapacity,
|
87
|
+
uncompressedData, uncompressedSize, NULL);
|
88
|
+
FUZZ_ASSERT(!LZ4F_isError(lz4Return));
|
89
|
+
compressedSize += lz4Return;
|
90
|
+
|
91
|
+
/* Compress data after uncompressed offset */
|
92
|
+
lz4Return = LZ4F_compressUpdate(ctx, dst + compressedSize, dstCapacity,
|
93
|
+
data + uncompressedEndOffset,
|
94
|
+
size - uncompressedEndOffset, NULL);
|
95
|
+
FUZZ_ASSERT(!LZ4F_isError(lz4Return));
|
96
|
+
compressedSize += lz4Return;
|
97
|
+
|
98
|
+
/* Finish compression */
|
99
|
+
lz4Return = LZ4F_compressEnd(ctx, dst + compressedSize, dstCapacity, NULL);
|
100
|
+
FUZZ_ASSERT(!LZ4F_isError(lz4Return));
|
101
|
+
compressedSize += lz4Return;
|
102
|
+
|
103
|
+
LZ4F_decompressOptions_t opts;
|
104
|
+
memset(&opts, 0, sizeof(opts));
|
105
|
+
opts.stableDst = 1;
|
106
|
+
LZ4F_dctx *dctx;
|
107
|
+
LZ4F_createDecompressionContext(&dctx, LZ4F_VERSION);
|
108
|
+
FUZZ_ASSERT(dctx);
|
109
|
+
|
110
|
+
decompress(dctx, dst, rt, rtCapacity, compressedSize);
|
111
|
+
|
112
|
+
LZ4F_freeDecompressionContext(dctx);
|
113
|
+
|
114
|
+
FUZZ_ASSERT_MSG(!memcmp(data, rt, size), "Corruption!");
|
115
|
+
|
116
|
+
free(dst);
|
117
|
+
free(rt);
|
118
|
+
|
119
|
+
FUZZ_dataProducer_free(producer);
|
120
|
+
LZ4F_freeCompressionContext(ctx);
|
121
|
+
}
|
122
|
+
|
123
|
+
static void compress_independent_block_mode(const uint8_t *data, size_t size) {
|
124
|
+
FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(data, size);
|
125
|
+
LZ4F_preferences_t prefs = FUZZ_dataProducer_preferences(producer);
|
126
|
+
prefs.frameInfo.blockMode = LZ4F_blockIndependent;
|
127
|
+
compress_round_trip(data, size, producer, prefs);
|
128
|
+
}
|
129
|
+
|
130
|
+
|
131
|
+
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
132
|
+
compress_independent_block_mode(data, size);
|
133
|
+
return 0;
|
134
|
+
}
|