extlz4 0.2.5 → 0.3.4

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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY.ja.md +16 -1
  3. data/README.md +49 -51
  4. data/Rakefile +22 -0
  5. data/bin/extlz4 +1 -1
  6. data/contrib/lz4/LICENSE +2 -1
  7. data/contrib/lz4/Makefile.inc +111 -0
  8. data/contrib/lz4/NEWS +97 -0
  9. data/contrib/lz4/README.md +41 -36
  10. data/contrib/lz4/build/README.md +55 -0
  11. data/contrib/lz4/build/VS2010/datagen/datagen.vcxproj +169 -0
  12. data/contrib/lz4/build/VS2010/frametest/frametest.vcxproj +176 -0
  13. data/contrib/lz4/build/VS2010/fullbench/fullbench.vcxproj +176 -0
  14. data/contrib/lz4/build/VS2010/fullbench-dll/fullbench-dll.vcxproj +180 -0
  15. data/contrib/lz4/build/VS2010/fuzzer/fuzzer.vcxproj +173 -0
  16. data/contrib/lz4/build/VS2010/liblz4/liblz4.vcxproj +175 -0
  17. data/contrib/lz4/build/VS2010/liblz4-dll/liblz4-dll.rc +51 -0
  18. data/contrib/lz4/build/VS2010/liblz4-dll/liblz4-dll.vcxproj +179 -0
  19. data/contrib/lz4/build/VS2010/lz4/lz4.rc +51 -0
  20. data/contrib/lz4/build/VS2010/lz4/lz4.vcxproj +189 -0
  21. data/contrib/lz4/build/VS2010/lz4.sln +98 -0
  22. data/contrib/lz4/build/VS2017/datagen/datagen.vcxproj +173 -0
  23. data/contrib/lz4/build/VS2017/frametest/frametest.vcxproj +180 -0
  24. data/contrib/lz4/build/VS2017/fullbench/fullbench.vcxproj +180 -0
  25. data/contrib/lz4/build/VS2017/fullbench-dll/fullbench-dll.vcxproj +184 -0
  26. data/contrib/lz4/build/VS2017/fuzzer/fuzzer.vcxproj +177 -0
  27. data/contrib/lz4/build/VS2017/liblz4/liblz4.vcxproj +179 -0
  28. data/contrib/lz4/build/VS2017/liblz4-dll/liblz4-dll.rc +51 -0
  29. data/contrib/lz4/build/VS2017/liblz4-dll/liblz4-dll.vcxproj +183 -0
  30. data/contrib/lz4/build/VS2017/lz4/lz4.rc +51 -0
  31. data/contrib/lz4/build/VS2017/lz4/lz4.vcxproj +175 -0
  32. data/contrib/lz4/build/VS2017/lz4.sln +103 -0
  33. data/contrib/lz4/build/VS2022/datagen/datagen.vcxproj +173 -0
  34. data/contrib/lz4/build/VS2022/frametest/frametest.vcxproj +180 -0
  35. data/contrib/lz4/build/VS2022/fullbench/fullbench.vcxproj +180 -0
  36. data/contrib/lz4/build/VS2022/fullbench-dll/fullbench-dll.vcxproj +184 -0
  37. data/contrib/lz4/build/VS2022/fuzzer/fuzzer.vcxproj +177 -0
  38. data/contrib/lz4/build/VS2022/liblz4/liblz4.vcxproj +179 -0
  39. data/contrib/lz4/build/VS2022/liblz4-dll/liblz4-dll.rc +51 -0
  40. data/contrib/lz4/build/VS2022/liblz4-dll/liblz4-dll.vcxproj +183 -0
  41. data/contrib/lz4/build/VS2022/lz4.sln +103 -0
  42. data/contrib/lz4/build/cmake/CMakeLists.txt +273 -0
  43. data/contrib/lz4/build/cmake/lz4Config.cmake.in +2 -0
  44. data/contrib/lz4/lib/LICENSE +1 -1
  45. data/contrib/lz4/lib/README.md +111 -15
  46. data/contrib/lz4/lib/liblz4-dll.rc.in +35 -0
  47. data/contrib/lz4/lib/liblz4.pc.in +3 -3
  48. data/contrib/lz4/lib/lz4.c +1891 -733
  49. data/contrib/lz4/lib/lz4.h +597 -234
  50. data/contrib/lz4/lib/lz4file.c +311 -0
  51. data/contrib/lz4/lib/lz4file.h +93 -0
  52. data/contrib/lz4/lib/lz4frame.c +896 -493
  53. data/contrib/lz4/lib/lz4frame.h +408 -107
  54. data/contrib/lz4/lib/lz4frame_static.h +5 -112
  55. data/contrib/lz4/lib/lz4hc.c +1039 -301
  56. data/contrib/lz4/lib/lz4hc.h +264 -123
  57. data/contrib/lz4/lib/xxhash.c +376 -240
  58. data/contrib/lz4/lib/xxhash.h +128 -93
  59. data/contrib/lz4/ossfuzz/Makefile +79 -0
  60. data/contrib/lz4/ossfuzz/compress_frame_fuzzer.c +48 -0
  61. data/contrib/lz4/ossfuzz/compress_fuzzer.c +58 -0
  62. data/contrib/lz4/ossfuzz/compress_hc_fuzzer.c +64 -0
  63. data/contrib/lz4/ossfuzz/decompress_frame_fuzzer.c +75 -0
  64. data/contrib/lz4/ossfuzz/decompress_fuzzer.c +78 -0
  65. data/contrib/lz4/ossfuzz/fuzz.h +48 -0
  66. data/contrib/lz4/ossfuzz/fuzz_data_producer.c +77 -0
  67. data/contrib/lz4/ossfuzz/fuzz_data_producer.h +36 -0
  68. data/contrib/lz4/ossfuzz/fuzz_helpers.h +95 -0
  69. data/contrib/lz4/ossfuzz/lz4_helpers.c +51 -0
  70. data/contrib/lz4/ossfuzz/lz4_helpers.h +13 -0
  71. data/contrib/lz4/ossfuzz/ossfuzz.sh +23 -0
  72. data/contrib/lz4/ossfuzz/round_trip_frame_fuzzer.c +43 -0
  73. data/contrib/lz4/ossfuzz/round_trip_frame_uncompressed_fuzzer.c +134 -0
  74. data/contrib/lz4/ossfuzz/round_trip_fuzzer.c +117 -0
  75. data/contrib/lz4/ossfuzz/round_trip_hc_fuzzer.c +44 -0
  76. data/contrib/lz4/ossfuzz/round_trip_stream_fuzzer.c +302 -0
  77. data/contrib/lz4/ossfuzz/standaloneengine.c +74 -0
  78. data/contrib/lz4/ossfuzz/travisoss.sh +26 -0
  79. data/ext/blockapi.c +13 -48
  80. data/ext/extlz4.c +2 -0
  81. data/ext/extlz4.h +17 -0
  82. data/ext/frameapi.c +3 -14
  83. data/ext/hashargs.c +9 -3
  84. data/ext/hashargs.h +1 -1
  85. data/ext/lz4_amalgam.c +0 -23
  86. data/gemstub.rb +5 -16
  87. data/lib/extlz4/oldstream.rb +1 -1
  88. data/lib/extlz4.rb +51 -3
  89. data/test/common.rb +2 -2
  90. metadata +84 -16
  91. data/contrib/lz4/circle.yml +0 -38
  92. data/contrib/lz4/lib/lz4opt.h +0 -356
  93. data/lib/extlz4/version.rb +0 -3
@@ -0,0 +1,78 @@
1
+ /**
2
+ * This fuzz target attempts to decompress the fuzzed data with the simple
3
+ * decompression function to ensure the decompressor never crashes.
4
+ */
5
+
6
+ #include <stddef.h>
7
+ #include <stdint.h>
8
+ #include <stdlib.h>
9
+ #include <string.h>
10
+
11
+ #include "fuzz_helpers.h"
12
+ #include "fuzz_data_producer.h"
13
+ #include "lz4.h"
14
+
15
+ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
16
+ {
17
+ FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(data, size);
18
+ size_t const dstCapacitySeed = FUZZ_dataProducer_retrieve32(producer);
19
+ size = FUZZ_dataProducer_remainingBytes(producer);
20
+
21
+ size_t const dstCapacity = FUZZ_getRange_from_uint32(dstCapacitySeed, 0, 4 * size);
22
+ size_t const smallDictSize = size + 1;
23
+ size_t const largeDictSize = 64 * 1024 - 1;
24
+ size_t const dictSize = MAX(smallDictSize, largeDictSize);
25
+ char* const dst = (char*)malloc(dstCapacity);
26
+ char* const dict = (char*)malloc(dictSize + size);
27
+ char* const largeDict = dict;
28
+ char* const dataAfterDict = dict + dictSize;
29
+ char* const smallDict = dataAfterDict - smallDictSize;
30
+
31
+ FUZZ_ASSERT(dst);
32
+ FUZZ_ASSERT(dict);
33
+
34
+ /* Prepare the dictionary. The data doesn't matter for decompression. */
35
+ memset(dict, 0, dictSize);
36
+ memcpy(dataAfterDict, data, size);
37
+
38
+ /* Decompress using each possible dictionary configuration. */
39
+ /* No dictionary. */
40
+ LZ4_decompress_safe_usingDict((char const*)data, dst, size,
41
+ dstCapacity, NULL, 0);
42
+ /* Small external dictionary. */
43
+ LZ4_decompress_safe_usingDict((char const*)data, dst, size,
44
+ dstCapacity, smallDict, smallDictSize);
45
+ /* Large external dictionary. */
46
+ LZ4_decompress_safe_usingDict((char const*)data, dst, size,
47
+ dstCapacity, largeDict, largeDictSize);
48
+ /* Small prefix. */
49
+ LZ4_decompress_safe_usingDict((char const*)dataAfterDict, dst, size,
50
+ dstCapacity, smallDict, smallDictSize);
51
+ /* Large prefix. */
52
+ LZ4_decompress_safe_usingDict((char const*)dataAfterDict, dst, size,
53
+ dstCapacity, largeDict, largeDictSize);
54
+ /* Partial decompression. */
55
+ LZ4_decompress_safe_partial((char const*)data, dst, size,
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 wtih large prefix. */
71
+ LZ4_decompress_safe_partial_usingDict((char const*)dataAfterDict, dst, size,
72
+ dstCapacity, dstCapacity, largeDict, largeDictSize);
73
+ free(dst);
74
+ free(dict);
75
+ FUZZ_dataProducer_free(producer);
76
+
77
+ return 0;
78
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Fuzz target interface.
3
+ * Fuzz targets have some common parameters passed as macros during compilation.
4
+ * Check the documentation for each individual fuzzer for more parameters.
5
+ *
6
+ * @param FUZZ_RNG_SEED_SIZE:
7
+ * The number of bytes of the source to look at when constructing a seed
8
+ * for the deterministic RNG. These bytes are discarded before passing
9
+ * the data to lz4 functions. Every fuzzer initializes the RNG exactly
10
+ * once before doing anything else, even if it is unused.
11
+ * Default: 4.
12
+ * @param LZ4_DEBUG:
13
+ * This is a parameter for the lz4 library. Defining `LZ4_DEBUG=1`
14
+ * enables assert() statements in the lz4 library. Higher levels enable
15
+ * logging, so aren't recommended. Defining `LZ4_DEBUG=1` is
16
+ * recommended.
17
+ * @param LZ4_FORCE_MEMORY_ACCESS:
18
+ * This flag controls how the zstd library accesses unaligned memory.
19
+ * It can be undefined, or 0 through 2. If it is undefined, it selects
20
+ * the method to use based on the compiler. If testing with UBSAN set
21
+ * MEM_FORCE_MEMORY_ACCESS=0 to use the standard compliant method.
22
+ * @param FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
23
+ * This is the canonical flag to enable deterministic builds for fuzzing.
24
+ * Changes to zstd for fuzzing are gated behind this define.
25
+ * It is recommended to define this when building zstd for fuzzing.
26
+ */
27
+
28
+ #ifndef FUZZ_H
29
+ #define FUZZ_H
30
+
31
+ #ifndef FUZZ_RNG_SEED_SIZE
32
+ # define FUZZ_RNG_SEED_SIZE 4
33
+ #endif
34
+
35
+ #include <stddef.h>
36
+ #include <stdint.h>
37
+
38
+ #ifdef __cplusplus
39
+ extern "C" {
40
+ #endif
41
+
42
+ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size);
43
+
44
+ #ifdef __cplusplus
45
+ }
46
+ #endif
47
+
48
+ #endif
@@ -0,0 +1,77 @@
1
+ #include "fuzz_data_producer.h"
2
+
3
+ struct FUZZ_dataProducer_s{
4
+ const uint8_t *data;
5
+ size_t size;
6
+ };
7
+
8
+ FUZZ_dataProducer_t* FUZZ_dataProducer_create(const uint8_t* data, size_t size) {
9
+ FUZZ_dataProducer_t* const producer = malloc(sizeof(FUZZ_dataProducer_t));
10
+
11
+ FUZZ_ASSERT(producer != NULL);
12
+
13
+ producer->data = data;
14
+ producer->size = size;
15
+ return producer;
16
+ }
17
+
18
+ void FUZZ_dataProducer_free(FUZZ_dataProducer_t *producer) { free(producer); }
19
+
20
+ uint32_t FUZZ_dataProducer_retrieve32(FUZZ_dataProducer_t *producer) {
21
+ const uint8_t* data = producer->data;
22
+ const size_t size = producer->size;
23
+ if (size == 0) {
24
+ return 0;
25
+ } else if (size < 4) {
26
+ producer->size -= 1;
27
+ return (uint32_t)data[size - 1];
28
+ } else {
29
+ producer->size -= 4;
30
+ return *(data + size - 4);
31
+ }
32
+ }
33
+
34
+ uint32_t FUZZ_getRange_from_uint32(uint32_t seed, uint32_t min, uint32_t max)
35
+ {
36
+ uint32_t range = max - min;
37
+ if (range == 0xffffffff) {
38
+ return seed;
39
+ }
40
+ return min + seed % (range + 1);
41
+ }
42
+
43
+ uint32_t FUZZ_dataProducer_range32(FUZZ_dataProducer_t* producer,
44
+ uint32_t min, uint32_t max)
45
+ {
46
+ size_t const seed = FUZZ_dataProducer_retrieve32(producer);
47
+ return FUZZ_getRange_from_uint32(seed, min, max);
48
+ }
49
+
50
+ LZ4F_frameInfo_t FUZZ_dataProducer_frameInfo(FUZZ_dataProducer_t* producer)
51
+ {
52
+ LZ4F_frameInfo_t info = LZ4F_INIT_FRAMEINFO;
53
+ info.blockSizeID = FUZZ_dataProducer_range32(producer, LZ4F_max64KB - 1, LZ4F_max4MB);
54
+ if (info.blockSizeID < LZ4F_max64KB) {
55
+ info.blockSizeID = LZ4F_default;
56
+ }
57
+ info.blockMode = FUZZ_dataProducer_range32(producer, LZ4F_blockLinked, LZ4F_blockIndependent);
58
+ info.contentChecksumFlag = FUZZ_dataProducer_range32(producer, LZ4F_noContentChecksum,
59
+ LZ4F_contentChecksumEnabled);
60
+ info.blockChecksumFlag = FUZZ_dataProducer_range32(producer, LZ4F_noBlockChecksum,
61
+ LZ4F_blockChecksumEnabled);
62
+ return info;
63
+ }
64
+
65
+ LZ4F_preferences_t FUZZ_dataProducer_preferences(FUZZ_dataProducer_t* producer)
66
+ {
67
+ LZ4F_preferences_t prefs = LZ4F_INIT_PREFERENCES;
68
+ prefs.frameInfo = FUZZ_dataProducer_frameInfo(producer);
69
+ prefs.compressionLevel = FUZZ_dataProducer_range32(producer, 0, LZ4HC_CLEVEL_MAX + 3) - 3;
70
+ prefs.autoFlush = FUZZ_dataProducer_range32(producer, 0, 1);
71
+ prefs.favorDecSpeed = FUZZ_dataProducer_range32(producer, 0, 1);
72
+ return prefs;
73
+ }
74
+
75
+ size_t FUZZ_dataProducer_remainingBytes(FUZZ_dataProducer_t *producer){
76
+ return producer->size;
77
+ }
@@ -0,0 +1,36 @@
1
+ #include <stddef.h>
2
+ #include <stdint.h>
3
+ #include <stdio.h>
4
+ #include <stdlib.h>
5
+
6
+ #include "fuzz_helpers.h"
7
+ #include "lz4frame.h"
8
+ #include "lz4hc.h"
9
+
10
+ /* Struct used for maintaining the state of the data */
11
+ typedef struct FUZZ_dataProducer_s FUZZ_dataProducer_t;
12
+
13
+ /* Returns a data producer state struct. Use for producer initialization. */
14
+ FUZZ_dataProducer_t *FUZZ_dataProducer_create(const uint8_t *data, size_t size);
15
+
16
+ /* Frees the data producer */
17
+ void FUZZ_dataProducer_free(FUZZ_dataProducer_t *producer);
18
+
19
+ /* Returns 32 bits from the end of data */
20
+ uint32_t FUZZ_dataProducer_retrieve32(FUZZ_dataProducer_t *producer);
21
+
22
+ /* Returns value between [min, max] */
23
+ uint32_t FUZZ_getRange_from_uint32(uint32_t seed, uint32_t min, uint32_t max);
24
+
25
+ /* Combination of above two functions for non adaptive use cases. ie where size is not involved */
26
+ uint32_t FUZZ_dataProducer_range32(FUZZ_dataProducer_t *producer, uint32_t min,
27
+ uint32_t max);
28
+
29
+ /* Returns lz4 preferences */
30
+ LZ4F_preferences_t FUZZ_dataProducer_preferences(FUZZ_dataProducer_t* producer);
31
+
32
+ /* Returns lz4 frame info */
33
+ LZ4F_frameInfo_t FUZZ_dataProducer_frameInfo(FUZZ_dataProducer_t* producer);
34
+
35
+ /* Returns the size of the remaining bytes of data in the producer */
36
+ size_t FUZZ_dataProducer_remainingBytes(FUZZ_dataProducer_t *producer);
@@ -0,0 +1,95 @@
1
+ /*
2
+ * Copyright (c) 2016-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under both the BSD-style license (found in the
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),
8
+ * meaning you may select, at your option, one of the above-listed licenses.
9
+ */
10
+
11
+ /**
12
+ * Helper functions for fuzzing.
13
+ */
14
+
15
+ #ifndef FUZZ_HELPERS_H
16
+ #define FUZZ_HELPERS_H
17
+
18
+ #include "fuzz.h"
19
+ #include "xxhash.h"
20
+ #include <stdint.h>
21
+ #include <stdio.h>
22
+ #include <stdlib.h>
23
+
24
+ #ifdef __cplusplus
25
+ extern "C" {
26
+ #endif
27
+
28
+ #define LZ4_COMMONDEFS_ONLY
29
+ #ifndef LZ4_SRC_INCLUDED
30
+ #include "lz4.c" /* LZ4_count, constants, mem */
31
+ #endif
32
+
33
+ #define MIN(a,b) ( (a) < (b) ? (a) : (b) )
34
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
35
+
36
+ #define FUZZ_QUOTE_IMPL(str) #str
37
+ #define FUZZ_QUOTE(str) FUZZ_QUOTE_IMPL(str)
38
+
39
+ /**
40
+ * Asserts for fuzzing that are always enabled.
41
+ */
42
+ #define FUZZ_ASSERT_MSG(cond, msg) \
43
+ ((cond) ? (void)0 \
44
+ : (fprintf(stderr, "%s: %u: Assertion: `%s' failed. %s\n", __FILE__, \
45
+ __LINE__, FUZZ_QUOTE(cond), (msg)), \
46
+ abort()))
47
+ #define FUZZ_ASSERT(cond) FUZZ_ASSERT_MSG((cond), "");
48
+
49
+ #if defined(__GNUC__)
50
+ #define FUZZ_STATIC static __inline __attribute__((unused))
51
+ #elif defined(__cplusplus) || \
52
+ (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
53
+ #define FUZZ_STATIC static inline
54
+ #elif defined(_MSC_VER)
55
+ #define FUZZ_STATIC static __inline
56
+ #else
57
+ #define FUZZ_STATIC static
58
+ #endif
59
+
60
+ /**
61
+ * Deterministically constructs a seed based on the fuzz input.
62
+ * Consumes up to the first FUZZ_RNG_SEED_SIZE bytes of the input.
63
+ */
64
+ FUZZ_STATIC uint32_t FUZZ_seed(uint8_t const **src, size_t* size) {
65
+ uint8_t const *data = *src;
66
+ size_t const toHash = MIN(FUZZ_RNG_SEED_SIZE, *size);
67
+ *size -= toHash;
68
+ *src += toHash;
69
+ return XXH32(data, toHash, 0);
70
+ }
71
+
72
+ #define FUZZ_rotl32(x, r) (((x) << (r)) | ((x) >> (32 - (r))))
73
+
74
+ FUZZ_STATIC uint32_t FUZZ_rand(uint32_t *state) {
75
+ static const uint32_t prime1 = 2654435761U;
76
+ static const uint32_t prime2 = 2246822519U;
77
+ uint32_t rand32 = *state;
78
+ rand32 *= prime1;
79
+ rand32 += prime2;
80
+ rand32 = FUZZ_rotl32(rand32, 13);
81
+ *state = rand32;
82
+ return rand32 >> 5;
83
+ }
84
+
85
+ /* Returns a random number in the range [min, max]. */
86
+ FUZZ_STATIC uint32_t FUZZ_rand32(uint32_t *state, uint32_t min, uint32_t max) {
87
+ uint32_t random = FUZZ_rand(state);
88
+ return min + (random % (max - min + 1));
89
+ }
90
+
91
+ #ifdef __cplusplus
92
+ }
93
+ #endif
94
+
95
+ #endif
@@ -0,0 +1,51 @@
1
+ #include "fuzz_helpers.h"
2
+ #include "lz4_helpers.h"
3
+ #include "lz4hc.h"
4
+
5
+ LZ4F_frameInfo_t FUZZ_randomFrameInfo(uint32_t* seed)
6
+ {
7
+ LZ4F_frameInfo_t info = LZ4F_INIT_FRAMEINFO;
8
+ info.blockSizeID = FUZZ_rand32(seed, LZ4F_max64KB - 1, LZ4F_max4MB);
9
+ if (info.blockSizeID < LZ4F_max64KB) {
10
+ info.blockSizeID = LZ4F_default;
11
+ }
12
+ info.blockMode = FUZZ_rand32(seed, LZ4F_blockLinked, LZ4F_blockIndependent);
13
+ info.contentChecksumFlag = FUZZ_rand32(seed, LZ4F_noContentChecksum,
14
+ LZ4F_contentChecksumEnabled);
15
+ info.blockChecksumFlag = FUZZ_rand32(seed, LZ4F_noBlockChecksum,
16
+ LZ4F_blockChecksumEnabled);
17
+ return info;
18
+ }
19
+
20
+ LZ4F_preferences_t FUZZ_randomPreferences(uint32_t* seed)
21
+ {
22
+ LZ4F_preferences_t prefs = LZ4F_INIT_PREFERENCES;
23
+ prefs.frameInfo = FUZZ_randomFrameInfo(seed);
24
+ prefs.compressionLevel = FUZZ_rand32(seed, 0, LZ4HC_CLEVEL_MAX + 3) - 3;
25
+ prefs.autoFlush = FUZZ_rand32(seed, 0, 1);
26
+ prefs.favorDecSpeed = FUZZ_rand32(seed, 0, 1);
27
+ return prefs;
28
+ }
29
+
30
+ size_t FUZZ_decompressFrame(void* dst, const size_t dstCapacity,
31
+ const void* src, const size_t srcSize)
32
+ {
33
+ LZ4F_decompressOptions_t opts;
34
+ memset(&opts, 0, sizeof(opts));
35
+ opts.stableDst = 1;
36
+ LZ4F_dctx* dctx;
37
+ LZ4F_createDecompressionContext(&dctx, LZ4F_VERSION);
38
+ FUZZ_ASSERT(dctx);
39
+
40
+ size_t dstSize = dstCapacity;
41
+ size_t srcConsumed = srcSize;
42
+ size_t const rc =
43
+ LZ4F_decompress(dctx, dst, &dstSize, src, &srcConsumed, &opts);
44
+ FUZZ_ASSERT(!LZ4F_isError(rc));
45
+ FUZZ_ASSERT(rc == 0);
46
+ FUZZ_ASSERT(srcConsumed == srcSize);
47
+
48
+ LZ4F_freeDecompressionContext(dctx);
49
+
50
+ return dstSize;
51
+ }
@@ -0,0 +1,13 @@
1
+ #ifndef LZ4_HELPERS
2
+ #define LZ4_HELPERS
3
+
4
+ #include "lz4frame.h"
5
+
6
+ LZ4F_frameInfo_t FUZZ_randomFrameInfo(uint32_t* seed);
7
+
8
+ LZ4F_preferences_t FUZZ_randomPreferences(uint32_t* seed);
9
+
10
+ size_t FUZZ_decompressFrame(void* dst, const size_t dstCapacity,
11
+ const void* src, const size_t srcSize);
12
+
13
+ #endif /* LZ4_HELPERS */
@@ -0,0 +1,23 @@
1
+ #!/bin/bash -eu
2
+
3
+ # This script is called by the oss-fuzz main project when compiling the fuzz
4
+ # targets. This script is regression tested by travisoss.sh.
5
+
6
+ # Save off the current folder as the build root.
7
+ export BUILD_ROOT=$PWD
8
+
9
+ echo "CC: $CC"
10
+ echo "CXX: $CXX"
11
+ echo "LIB_FUZZING_ENGINE: $LIB_FUZZING_ENGINE"
12
+ echo "CFLAGS: $CFLAGS"
13
+ echo "CXXFLAGS: $CXXFLAGS"
14
+ echo "OUT: $OUT"
15
+
16
+ export MAKEFLAGS+="-j$(nproc)"
17
+
18
+ pushd ossfuzz
19
+ make V=1 all
20
+ popd
21
+
22
+ # Copy the fuzzers to the target directory.
23
+ cp -v ossfuzz/*_fuzzer $OUT/
@@ -0,0 +1,43 @@
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_helpers.h"
12
+ #include "lz4.h"
13
+ #include "lz4frame.h"
14
+ #include "lz4_helpers.h"
15
+ #include "fuzz_data_producer.h"
16
+
17
+ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
18
+ {
19
+ FUZZ_dataProducer_t* producer = FUZZ_dataProducer_create(data, size);
20
+ LZ4F_preferences_t const prefs = FUZZ_dataProducer_preferences(producer);
21
+ size = FUZZ_dataProducer_remainingBytes(producer);
22
+
23
+ size_t const dstCapacity = LZ4F_compressFrameBound(LZ4_compressBound(size), &prefs);
24
+ char* const dst = (char*)malloc(dstCapacity);
25
+ char* const rt = (char*)malloc(FUZZ_dataProducer_remainingBytes(producer));
26
+
27
+ FUZZ_ASSERT(dst);
28
+ FUZZ_ASSERT(rt);
29
+
30
+ /* Compression must succeed and round trip correctly. */
31
+ size_t const dstSize =
32
+ LZ4F_compressFrame(dst, dstCapacity, data, size, &prefs);
33
+ FUZZ_ASSERT(!LZ4F_isError(dstSize));
34
+ size_t const rtSize = FUZZ_decompressFrame(rt, size, dst, dstSize);
35
+ FUZZ_ASSERT_MSG(rtSize == size, "Incorrect regenerated size");
36
+ FUZZ_ASSERT_MSG(!memcmp(data, rt, size), "Corruption!");
37
+
38
+ free(dst);
39
+ free(rt);
40
+ FUZZ_dataProducer_free(producer);
41
+
42
+ return 0;
43
+ }
@@ -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
+ }