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.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/Rakefile +43 -3
  4. data/contrib/lz4/CODING_STYLE +57 -0
  5. data/contrib/lz4/LICENSE +3 -2
  6. data/contrib/lz4/Makefile.inc +56 -30
  7. data/contrib/lz4/NEWS +46 -0
  8. data/contrib/lz4/README.md +17 -6
  9. data/contrib/lz4/SECURITY.md +17 -0
  10. data/contrib/lz4/build/README.md +4 -15
  11. data/contrib/lz4/build/VS2022/_build.bat +39 -0
  12. data/contrib/lz4/build/VS2022/_setup.bat +35 -0
  13. data/contrib/lz4/build/VS2022/_test.bat +38 -0
  14. data/contrib/lz4/build/VS2022/build-and-test-win32-debug.bat +26 -0
  15. data/contrib/lz4/build/VS2022/build-and-test-win32-release.bat +26 -0
  16. data/contrib/lz4/build/VS2022/build-and-test-x64-debug.bat +26 -0
  17. data/contrib/lz4/build/VS2022/build-and-test-x64-release.bat +26 -0
  18. data/contrib/lz4/build/{VS2017 → VS2022}/datagen/datagen.vcxproj +11 -7
  19. data/contrib/lz4/build/{VS2017 → VS2022}/frametest/frametest.vcxproj +4 -4
  20. data/contrib/lz4/build/{VS2017 → VS2022}/fullbench/fullbench.vcxproj +4 -4
  21. data/contrib/lz4/build/{VS2017 → VS2022}/fullbench-dll/fullbench-dll.vcxproj +4 -4
  22. data/contrib/lz4/build/{VS2017 → VS2022}/fuzzer/fuzzer.vcxproj +4 -4
  23. data/contrib/lz4/build/{VS2017 → VS2022}/liblz4/liblz4.vcxproj +4 -4
  24. data/contrib/lz4/build/{VS2010 → VS2022}/liblz4-dll/liblz4-dll.rc +1 -1
  25. data/contrib/lz4/build/{VS2017 → VS2022}/liblz4-dll/liblz4-dll.vcxproj +4 -4
  26. data/contrib/lz4/build/{VS2010 → VS2022}/lz4/lz4.rc +1 -1
  27. data/contrib/lz4/build/{VS2017 → VS2022}/lz4/lz4.vcxproj +33 -8
  28. data/contrib/lz4/build/{VS2017 → VS2022}/lz4.sln +5 -2
  29. data/contrib/lz4/build/cmake/CMakeLists.txt +133 -100
  30. data/contrib/lz4/build/cmake/lz4Config.cmake.in +2 -0
  31. data/contrib/lz4/build/meson/GetLz4LibraryVersion.py +39 -0
  32. data/contrib/lz4/build/meson/README.md +34 -0
  33. data/contrib/lz4/build/meson/meson/contrib/gen_manual/meson.build +42 -0
  34. data/contrib/lz4/build/meson/meson/contrib/meson.build +11 -0
  35. data/contrib/lz4/build/meson/meson/examples/meson.build +32 -0
  36. data/contrib/lz4/build/meson/meson/lib/meson.build +87 -0
  37. data/contrib/lz4/build/meson/meson/meson.build +135 -0
  38. data/contrib/lz4/build/meson/meson/ossfuzz/meson.build +35 -0
  39. data/contrib/lz4/build/meson/meson/programs/meson.build +91 -0
  40. data/contrib/lz4/build/meson/meson/tests/meson.build +162 -0
  41. data/contrib/lz4/build/meson/meson.build +31 -0
  42. data/contrib/lz4/build/meson/meson_options.txt +44 -0
  43. data/contrib/lz4/build/visual/README.md +5 -0
  44. data/contrib/lz4/build/visual/generate_solution.cmd +55 -0
  45. data/contrib/lz4/build/visual/generate_vs2015.cmd +3 -0
  46. data/contrib/lz4/build/visual/generate_vs2017.cmd +3 -0
  47. data/contrib/lz4/build/visual/generate_vs2019.cmd +3 -0
  48. data/contrib/lz4/build/visual/generate_vs2022.cmd +3 -0
  49. data/contrib/lz4/lib/LICENSE +1 -1
  50. data/contrib/lz4/lib/README.md +69 -13
  51. data/contrib/lz4/lib/liblz4-dll.rc.in +1 -1
  52. data/contrib/lz4/lib/liblz4.pc.in +3 -3
  53. data/contrib/lz4/lib/lz4.c +608 -274
  54. data/contrib/lz4/lib/lz4.h +212 -102
  55. data/contrib/lz4/lib/lz4file.c +341 -0
  56. data/contrib/lz4/lib/lz4file.h +93 -0
  57. data/contrib/lz4/lib/lz4frame.c +545 -308
  58. data/contrib/lz4/lib/lz4frame.h +252 -124
  59. data/contrib/lz4/lib/lz4frame_static.h +1 -1
  60. data/contrib/lz4/lib/lz4hc.c +1038 -461
  61. data/contrib/lz4/lib/lz4hc.h +57 -56
  62. data/contrib/lz4/lib/xxhash.c +21 -21
  63. data/contrib/lz4/ossfuzz/Makefile +1 -0
  64. data/contrib/lz4/ossfuzz/decompress_fuzzer.c +18 -2
  65. data/contrib/lz4/ossfuzz/fuzz_helpers.h +4 -3
  66. data/contrib/lz4/ossfuzz/round_trip_frame_uncompressed_fuzzer.c +134 -0
  67. data/contrib/lz4/ossfuzz/round_trip_fuzzer.c +66 -6
  68. data/ext/blockapi.c +19 -19
  69. data/ext/extlz4.h +12 -0
  70. data/ext/frameapi.c +26 -26
  71. data/ext/hashargs.c +7 -1
  72. metadata +47 -30
  73. data/contrib/lz4/build/VS2010/datagen/datagen.vcxproj +0 -169
  74. data/contrib/lz4/build/VS2010/frametest/frametest.vcxproj +0 -176
  75. data/contrib/lz4/build/VS2010/fullbench/fullbench.vcxproj +0 -176
  76. data/contrib/lz4/build/VS2010/fullbench-dll/fullbench-dll.vcxproj +0 -180
  77. data/contrib/lz4/build/VS2010/fuzzer/fuzzer.vcxproj +0 -173
  78. data/contrib/lz4/build/VS2010/liblz4/liblz4.vcxproj +0 -175
  79. data/contrib/lz4/build/VS2010/liblz4-dll/liblz4-dll.vcxproj +0 -179
  80. data/contrib/lz4/build/VS2010/lz4/lz4.vcxproj +0 -189
  81. data/contrib/lz4/build/VS2010/lz4.sln +0 -98
  82. data/contrib/lz4/build/VS2017/liblz4-dll/liblz4-dll.rc +0 -51
  83. data/contrib/lz4/build/VS2017/lz4/lz4.rc +0 -51
  84. data/contrib/lz4/tmp +0 -0
  85. data/contrib/lz4/tmpsparse +0 -0
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  LZ4 HC - High Compression Mode of LZ4
3
3
  Header File
4
- Copyright (C) 2011-2017, Yann Collet.
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 3
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
- 'dst' buffer should be sized to handle worst case scenarios
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 `dst` buffer size cannot be made >= LZ4_compressBound(),
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 hashTable[LZ4HC_HASHTABLESIZE];
205
- LZ4_u16 chainTable[LZ4HC_MAXD];
206
- const LZ4_byte* end; /* next block here to continue on current prefix */
207
- const LZ4_byte* base; /* All index relative to this position */
208
- const LZ4_byte* dictBase; /* alternate base for extDict */
209
- LZ4_u32 dictLimit; /* below that point, need extDict */
210
- LZ4_u32 lowLimit; /* below that point, no more dict */
211
- LZ4_u32 nextToUpdate; /* index from which to continue dictionary update */
212
- short compressionLevel;
213
- LZ4_i8 favorDecSpeed; /* favor decompression speed if this flag set,
214
- otherwise, favor compression ratio */
215
- LZ4_i8 dirty; /* stream has to be fully reset if this flag is set */
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
- void* table[LZ4_STREAMHCSIZE_VOIDP];
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, on state, or as part of a larger structure.
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 (void* buffer, size_t size);
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 successfull usage in real-life scenarios.
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
@@ -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
- #ifdef _MSC_VER /* Visual Studio */
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
- # ifdef __GNUC__
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 } XXH_endianess;
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, XXH_endianess endian, XXH_alignment align)
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, XXH_endianess endian)
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
- XXH_endianess endian, XXH_alignment align)
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
- XXH_endianess endian, XXH_alignment align)
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
- XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
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, XXH_endianess endian)
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
- XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
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, XXH_endianess endian)
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
- XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
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, XXH_endianess endian, XXH_alignment align)
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, XXH_endianess endian)
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
- XXH_endianess endian, XXH_alignment align)
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
- XXH_endianess endian, XXH_alignment align)
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
- XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
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, XXH_endianess endian)
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
- XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
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, XXH_endianess endian)
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
- XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
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);
@@ -45,6 +45,7 @@ FUZZERS := \
45
45
  round_trip_hc_fuzzer \
46
46
  compress_frame_fuzzer \
47
47
  round_trip_frame_fuzzer \
48
+ round_trip_frame_uncompressed_fuzzer \
48
49
  decompress_frame_fuzzer
49
50
 
50
51
  .PHONY: all
@@ -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 dictonary. */
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*)data, dst, size,
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 numer in the range [min, max]. */
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
+ }