extlz4 0.2.4.2 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +5 -5
  2. data/HISTORY.ja.md +25 -0
  3. data/README.md +49 -41
  4. data/bin/extlz4 +1 -1
  5. data/contrib/lz4/INSTALL +1 -0
  6. data/contrib/lz4/Makefile.inc +87 -0
  7. data/contrib/lz4/NEWS +89 -0
  8. data/contrib/lz4/README.md +42 -36
  9. data/contrib/lz4/build/README.md +55 -0
  10. data/contrib/lz4/build/VS2010/datagen/datagen.vcxproj +169 -0
  11. data/contrib/lz4/build/VS2010/frametest/frametest.vcxproj +176 -0
  12. data/contrib/lz4/build/VS2010/fullbench-dll/fullbench-dll.vcxproj +180 -0
  13. data/contrib/lz4/build/VS2010/fullbench/fullbench.vcxproj +176 -0
  14. data/contrib/lz4/build/VS2010/fuzzer/fuzzer.vcxproj +173 -0
  15. data/contrib/lz4/build/VS2010/liblz4-dll/liblz4-dll.rc +51 -0
  16. data/contrib/lz4/build/VS2010/liblz4-dll/liblz4-dll.vcxproj +179 -0
  17. data/contrib/lz4/build/VS2010/liblz4/liblz4.vcxproj +175 -0
  18. data/contrib/lz4/build/VS2010/lz4.sln +98 -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/VS2017/datagen/datagen.vcxproj +173 -0
  22. data/contrib/lz4/build/VS2017/frametest/frametest.vcxproj +180 -0
  23. data/contrib/lz4/build/VS2017/fullbench-dll/fullbench-dll.vcxproj +184 -0
  24. data/contrib/lz4/build/VS2017/fullbench/fullbench.vcxproj +180 -0
  25. data/contrib/lz4/build/VS2017/fuzzer/fuzzer.vcxproj +177 -0
  26. data/contrib/lz4/build/VS2017/liblz4-dll/liblz4-dll.rc +51 -0
  27. data/contrib/lz4/build/VS2017/liblz4-dll/liblz4-dll.vcxproj +183 -0
  28. data/contrib/lz4/build/VS2017/liblz4/liblz4.vcxproj +179 -0
  29. data/contrib/lz4/build/VS2017/lz4.sln +103 -0
  30. data/contrib/lz4/build/VS2017/lz4/lz4.rc +51 -0
  31. data/contrib/lz4/build/VS2017/lz4/lz4.vcxproj +164 -0
  32. data/contrib/lz4/build/cmake/CMakeLists.txt +235 -0
  33. data/contrib/lz4/lib/README.md +98 -34
  34. data/contrib/lz4/lib/liblz4-dll.rc.in +35 -0
  35. data/contrib/lz4/lib/lz4.c +1698 -681
  36. data/contrib/lz4/lib/lz4.h +546 -235
  37. data/contrib/lz4/lib/lz4frame.c +608 -378
  38. data/contrib/lz4/lib/lz4frame.h +315 -83
  39. data/contrib/lz4/lib/lz4frame_static.h +4 -100
  40. data/contrib/lz4/lib/lz4hc.c +1090 -282
  41. data/contrib/lz4/lib/lz4hc.h +276 -141
  42. data/contrib/lz4/lib/xxhash.c +371 -235
  43. data/contrib/lz4/lib/xxhash.h +128 -93
  44. data/contrib/lz4/ossfuzz/Makefile +78 -0
  45. data/contrib/lz4/ossfuzz/compress_frame_fuzzer.c +48 -0
  46. data/contrib/lz4/ossfuzz/compress_fuzzer.c +58 -0
  47. data/contrib/lz4/ossfuzz/compress_hc_fuzzer.c +64 -0
  48. data/contrib/lz4/ossfuzz/decompress_frame_fuzzer.c +75 -0
  49. data/contrib/lz4/ossfuzz/decompress_fuzzer.c +62 -0
  50. data/contrib/lz4/ossfuzz/fuzz.h +48 -0
  51. data/contrib/lz4/ossfuzz/fuzz_data_producer.c +77 -0
  52. data/contrib/lz4/ossfuzz/fuzz_data_producer.h +36 -0
  53. data/contrib/lz4/ossfuzz/fuzz_helpers.h +94 -0
  54. data/contrib/lz4/ossfuzz/lz4_helpers.c +51 -0
  55. data/contrib/lz4/ossfuzz/lz4_helpers.h +13 -0
  56. data/contrib/lz4/ossfuzz/ossfuzz.sh +23 -0
  57. data/contrib/lz4/ossfuzz/round_trip_frame_fuzzer.c +43 -0
  58. data/contrib/lz4/ossfuzz/round_trip_fuzzer.c +57 -0
  59. data/contrib/lz4/ossfuzz/round_trip_hc_fuzzer.c +44 -0
  60. data/contrib/lz4/ossfuzz/round_trip_stream_fuzzer.c +302 -0
  61. data/contrib/lz4/ossfuzz/standaloneengine.c +74 -0
  62. data/contrib/lz4/ossfuzz/travisoss.sh +26 -0
  63. data/contrib/lz4/tmp +0 -0
  64. data/contrib/lz4/tmpsparse +0 -0
  65. data/ext/blockapi.c +5 -5
  66. data/ext/extlz4.c +2 -0
  67. data/ext/extlz4.h +5 -0
  68. data/ext/frameapi.c +1 -1
  69. data/ext/hashargs.c +2 -2
  70. data/ext/hashargs.h +1 -1
  71. data/ext/lz4_amalgam.c +0 -23
  72. data/gemstub.rb +5 -16
  73. data/lib/extlz4.rb +51 -3
  74. data/lib/extlz4/oldstream.rb +1 -1
  75. data/test/common.rb +2 -2
  76. metadata +73 -16
  77. data/contrib/lz4/circle.yml +0 -39
  78. data/contrib/lz4/lib/lz4opt.h +0 -366
  79. data/lib/extlz4/version.rb +0 -3
@@ -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,57 @@
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 "fuzz_data_producer.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 partialCapacitySeed = FUZZ_dataProducer_retrieve32(producer);
19
+ size = FUZZ_dataProducer_remainingBytes(producer);
20
+
21
+ size_t const partialCapacity = FUZZ_getRange_from_uint32(partialCapacitySeed, 0, size);
22
+ size_t const dstCapacity = LZ4_compressBound(size);
23
+
24
+ char* const dst = (char*)malloc(dstCapacity);
25
+ char* const rt = (char*)malloc(size);
26
+
27
+ FUZZ_ASSERT(dst);
28
+ FUZZ_ASSERT(rt);
29
+
30
+ /* Compression must succeed and round trip correctly. */
31
+ int const dstSize = LZ4_compress_default((const char*)data, dst,
32
+ size, dstCapacity);
33
+ FUZZ_ASSERT(dstSize > 0);
34
+
35
+ int const rtSize = LZ4_decompress_safe(dst, rt, dstSize, size);
36
+ FUZZ_ASSERT_MSG(rtSize == size, "Incorrect size");
37
+ FUZZ_ASSERT_MSG(!memcmp(data, rt, size), "Corruption!");
38
+
39
+ /* Partial decompression must succeed. */
40
+ {
41
+ char* const partial = (char*)malloc(partialCapacity);
42
+ FUZZ_ASSERT(partial);
43
+ int const partialSize = LZ4_decompress_safe_partial(
44
+ dst, partial, dstSize, partialCapacity, partialCapacity);
45
+ FUZZ_ASSERT(partialSize >= 0);
46
+ FUZZ_ASSERT_MSG(partialSize == partialCapacity, "Incorrect size");
47
+ FUZZ_ASSERT_MSG(!memcmp(data, partial, partialSize), "Corruption!");
48
+ free(partial);
49
+ }
50
+
51
+
52
+ free(dst);
53
+ free(rt);
54
+ FUZZ_dataProducer_free(producer);
55
+
56
+ return 0;
57
+ }
@@ -0,0 +1,44 @@
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 "fuzz_data_producer.h"
13
+ #include "lz4.h"
14
+ #include "lz4hc.h"
15
+
16
+ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
17
+ {
18
+ FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(data, size);
19
+ int const level = FUZZ_dataProducer_range32(producer,
20
+ LZ4HC_CLEVEL_MIN, LZ4HC_CLEVEL_MAX);
21
+ size = FUZZ_dataProducer_remainingBytes(producer);
22
+
23
+ size_t const dstCapacity = LZ4_compressBound(size);
24
+ char* const dst = (char*)malloc(dstCapacity);
25
+ char* const rt = (char*)malloc(size);
26
+
27
+ FUZZ_ASSERT(dst);
28
+ FUZZ_ASSERT(rt);
29
+
30
+ /* Compression must succeed and round trip correctly. */
31
+ int const dstSize = LZ4_compress_HC((const char*)data, dst, size,
32
+ dstCapacity, level);
33
+ FUZZ_ASSERT(dstSize > 0);
34
+
35
+ int const rtSize = LZ4_decompress_safe(dst, rt, dstSize, size);
36
+ FUZZ_ASSERT_MSG(rtSize == size, "Incorrect size");
37
+ FUZZ_ASSERT_MSG(!memcmp(data, rt, size), "Corruption!");
38
+
39
+ free(dst);
40
+ free(rt);
41
+ FUZZ_dataProducer_free(producer);
42
+
43
+ return 0;
44
+ }
@@ -0,0 +1,302 @@
1
+ /**
2
+ * This fuzz target performs a lz4 streaming round-trip test
3
+ * (compress & decompress), compares the result with the original, and calls
4
+ * abort() on corruption.
5
+ */
6
+
7
+ #include <stddef.h>
8
+ #include <stdint.h>
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+
12
+ #include "fuzz_helpers.h"
13
+ #define LZ4_STATIC_LINKING_ONLY
14
+ #include "lz4.h"
15
+ #define LZ4_HC_STATIC_LINKING_ONLY
16
+ #include "lz4hc.h"
17
+
18
+ typedef struct {
19
+ char const* buf;
20
+ size_t size;
21
+ size_t pos;
22
+ } const_cursor_t;
23
+
24
+ typedef struct {
25
+ char* buf;
26
+ size_t size;
27
+ size_t pos;
28
+ } cursor_t;
29
+
30
+ typedef struct {
31
+ LZ4_stream_t* cstream;
32
+ LZ4_streamHC_t* cstreamHC;
33
+ LZ4_streamDecode_t* dstream;
34
+ const_cursor_t data;
35
+ cursor_t compressed;
36
+ cursor_t roundTrip;
37
+ uint32_t seed;
38
+ int level;
39
+ } state_t;
40
+
41
+ cursor_t cursor_create(size_t size)
42
+ {
43
+ cursor_t cursor;
44
+ cursor.buf = (char*)malloc(size);
45
+ cursor.size = size;
46
+ cursor.pos = 0;
47
+ FUZZ_ASSERT(cursor.buf);
48
+ return cursor;
49
+ }
50
+
51
+ typedef void (*round_trip_t)(state_t* state);
52
+
53
+ void cursor_free(cursor_t cursor)
54
+ {
55
+ free(cursor.buf);
56
+ }
57
+
58
+ state_t state_create(char const* data, size_t size, uint32_t seed)
59
+ {
60
+ state_t state;
61
+
62
+ state.seed = seed;
63
+
64
+ state.data.buf = (char const*)data;
65
+ state.data.size = size;
66
+ state.data.pos = 0;
67
+
68
+ /* Extra margin because we are streaming. */
69
+ state.compressed = cursor_create(1024 + 2 * LZ4_compressBound(size));
70
+ state.roundTrip = cursor_create(size);
71
+
72
+ state.cstream = LZ4_createStream();
73
+ FUZZ_ASSERT(state.cstream);
74
+ state.cstreamHC = LZ4_createStreamHC();
75
+ FUZZ_ASSERT(state.cstream);
76
+ state.dstream = LZ4_createStreamDecode();
77
+ FUZZ_ASSERT(state.dstream);
78
+
79
+ return state;
80
+ }
81
+
82
+ void state_free(state_t state)
83
+ {
84
+ cursor_free(state.compressed);
85
+ cursor_free(state.roundTrip);
86
+ LZ4_freeStream(state.cstream);
87
+ LZ4_freeStreamHC(state.cstreamHC);
88
+ LZ4_freeStreamDecode(state.dstream);
89
+ }
90
+
91
+ static void state_reset(state_t* state, uint32_t seed)
92
+ {
93
+ state->level = FUZZ_rand32(&seed, LZ4HC_CLEVEL_MIN, LZ4HC_CLEVEL_MAX);
94
+ LZ4_resetStream_fast(state->cstream);
95
+ LZ4_resetStreamHC_fast(state->cstreamHC, state->level);
96
+ LZ4_setStreamDecode(state->dstream, NULL, 0);
97
+ state->data.pos = 0;
98
+ state->compressed.pos = 0;
99
+ state->roundTrip.pos = 0;
100
+ state->seed = seed;
101
+ }
102
+
103
+ static void state_decompress(state_t* state, char const* src, int srcSize)
104
+ {
105
+ char* dst = state->roundTrip.buf + state->roundTrip.pos;
106
+ int const dstCapacity = state->roundTrip.size - state->roundTrip.pos;
107
+ int const dSize = LZ4_decompress_safe_continue(state->dstream, src, dst,
108
+ srcSize, dstCapacity);
109
+ FUZZ_ASSERT(dSize >= 0);
110
+ state->roundTrip.pos += dSize;
111
+ }
112
+
113
+ static void state_checkRoundTrip(state_t const* state)
114
+ {
115
+ char const* data = state->data.buf;
116
+ size_t const size = state->data.size;
117
+ FUZZ_ASSERT_MSG(size == state->roundTrip.pos, "Incorrect size!");
118
+ FUZZ_ASSERT_MSG(!memcmp(data, state->roundTrip.buf, size), "Corruption!");
119
+ }
120
+
121
+ /**
122
+ * Picks a dictionary size and trims the dictionary off of the data.
123
+ * We copy the dictionary to the roundTrip so our validation passes.
124
+ */
125
+ static size_t state_trimDict(state_t* state)
126
+ {
127
+ /* 64 KB is the max dict size, allow slightly beyond that to test trim. */
128
+ uint32_t maxDictSize = MIN(70 * 1024, state->data.size);
129
+ size_t const dictSize = FUZZ_rand32(&state->seed, 0, maxDictSize);
130
+ DEBUGLOG(2, "dictSize = %zu", dictSize);
131
+ FUZZ_ASSERT(state->data.pos == 0);
132
+ FUZZ_ASSERT(state->roundTrip.pos == 0);
133
+ memcpy(state->roundTrip.buf, state->data.buf, dictSize);
134
+ state->data.pos += dictSize;
135
+ state->roundTrip.pos += dictSize;
136
+ return dictSize;
137
+ }
138
+
139
+ static void state_prefixRoundTrip(state_t* state)
140
+ {
141
+ while (state->data.pos != state->data.size) {
142
+ char const* src = state->data.buf + state->data.pos;
143
+ char* dst = state->compressed.buf + state->compressed.pos;
144
+ int const srcRemaining = state->data.size - state->data.pos;
145
+ int const srcSize = FUZZ_rand32(&state->seed, 0, srcRemaining);
146
+ int const dstCapacity = state->compressed.size - state->compressed.pos;
147
+ int const cSize = LZ4_compress_fast_continue(state->cstream, src, dst,
148
+ srcSize, dstCapacity, 0);
149
+ FUZZ_ASSERT(cSize > 0);
150
+ state->data.pos += srcSize;
151
+ state->compressed.pos += cSize;
152
+ state_decompress(state, dst, cSize);
153
+ }
154
+ }
155
+
156
+ static void state_extDictRoundTrip(state_t* state)
157
+ {
158
+ int i = 0;
159
+ cursor_t data2 = cursor_create(state->data.size);
160
+ memcpy(data2.buf, state->data.buf, state->data.size);
161
+ while (state->data.pos != state->data.size) {
162
+ char const* data = (i++ & 1) ? state->data.buf : data2.buf;
163
+ char const* src = data + state->data.pos;
164
+ char* dst = state->compressed.buf + state->compressed.pos;
165
+ int const srcRemaining = state->data.size - state->data.pos;
166
+ int const srcSize = FUZZ_rand32(&state->seed, 0, srcRemaining);
167
+ int const dstCapacity = state->compressed.size - state->compressed.pos;
168
+ int const cSize = LZ4_compress_fast_continue(state->cstream, src, dst,
169
+ srcSize, dstCapacity, 0);
170
+ FUZZ_ASSERT(cSize > 0);
171
+ state->data.pos += srcSize;
172
+ state->compressed.pos += cSize;
173
+ state_decompress(state, dst, cSize);
174
+ }
175
+ cursor_free(data2);
176
+ }
177
+
178
+ static void state_randomRoundTrip(state_t* state, round_trip_t rt0,
179
+ round_trip_t rt1)
180
+ {
181
+ if (FUZZ_rand32(&state->seed, 0, 1)) {
182
+ rt0(state);
183
+ } else {
184
+ rt1(state);
185
+ }
186
+ }
187
+
188
+ static void state_loadDictRoundTrip(state_t* state)
189
+ {
190
+ char const* dict = state->data.buf;
191
+ size_t const dictSize = state_trimDict(state);
192
+ LZ4_loadDict(state->cstream, dict, dictSize);
193
+ LZ4_setStreamDecode(state->dstream, dict, dictSize);
194
+ state_randomRoundTrip(state, state_prefixRoundTrip, state_extDictRoundTrip);
195
+ }
196
+
197
+ static void state_attachDictRoundTrip(state_t* state)
198
+ {
199
+ char const* dict = state->data.buf;
200
+ size_t const dictSize = state_trimDict(state);
201
+ LZ4_stream_t* dictStream = LZ4_createStream();
202
+ LZ4_loadDict(dictStream, dict, dictSize);
203
+ LZ4_attach_dictionary(state->cstream, dictStream);
204
+ LZ4_setStreamDecode(state->dstream, dict, dictSize);
205
+ state_randomRoundTrip(state, state_prefixRoundTrip, state_extDictRoundTrip);
206
+ LZ4_freeStream(dictStream);
207
+ }
208
+
209
+ static void state_prefixHCRoundTrip(state_t* state)
210
+ {
211
+ while (state->data.pos != state->data.size) {
212
+ char const* src = state->data.buf + state->data.pos;
213
+ char* dst = state->compressed.buf + state->compressed.pos;
214
+ int const srcRemaining = state->data.size - state->data.pos;
215
+ int const srcSize = FUZZ_rand32(&state->seed, 0, srcRemaining);
216
+ int const dstCapacity = state->compressed.size - state->compressed.pos;
217
+ int const cSize = LZ4_compress_HC_continue(state->cstreamHC, src, dst,
218
+ srcSize, dstCapacity);
219
+ FUZZ_ASSERT(cSize > 0);
220
+ state->data.pos += srcSize;
221
+ state->compressed.pos += cSize;
222
+ state_decompress(state, dst, cSize);
223
+ }
224
+ }
225
+
226
+ static void state_extDictHCRoundTrip(state_t* state)
227
+ {
228
+ int i = 0;
229
+ cursor_t data2 = cursor_create(state->data.size);
230
+ DEBUGLOG(2, "extDictHC");
231
+ memcpy(data2.buf, state->data.buf, state->data.size);
232
+ while (state->data.pos != state->data.size) {
233
+ char const* data = (i++ & 1) ? state->data.buf : data2.buf;
234
+ char const* src = data + state->data.pos;
235
+ char* dst = state->compressed.buf + state->compressed.pos;
236
+ int const srcRemaining = state->data.size - state->data.pos;
237
+ int const srcSize = FUZZ_rand32(&state->seed, 0, srcRemaining);
238
+ int const dstCapacity = state->compressed.size - state->compressed.pos;
239
+ int const cSize = LZ4_compress_HC_continue(state->cstreamHC, src, dst,
240
+ srcSize, dstCapacity);
241
+ FUZZ_ASSERT(cSize > 0);
242
+ DEBUGLOG(2, "srcSize = %d", srcSize);
243
+ state->data.pos += srcSize;
244
+ state->compressed.pos += cSize;
245
+ state_decompress(state, dst, cSize);
246
+ }
247
+ cursor_free(data2);
248
+ }
249
+
250
+ static void state_loadDictHCRoundTrip(state_t* state)
251
+ {
252
+ char const* dict = state->data.buf;
253
+ size_t const dictSize = state_trimDict(state);
254
+ LZ4_loadDictHC(state->cstreamHC, dict, dictSize);
255
+ LZ4_setStreamDecode(state->dstream, dict, dictSize);
256
+ state_randomRoundTrip(state, state_prefixHCRoundTrip,
257
+ state_extDictHCRoundTrip);
258
+ }
259
+
260
+ static void state_attachDictHCRoundTrip(state_t* state)
261
+ {
262
+ char const* dict = state->data.buf;
263
+ size_t const dictSize = state_trimDict(state);
264
+ LZ4_streamHC_t* dictStream = LZ4_createStreamHC();
265
+ LZ4_setCompressionLevel(dictStream, state->level);
266
+ LZ4_loadDictHC(dictStream, dict, dictSize);
267
+ LZ4_attach_HC_dictionary(state->cstreamHC, dictStream);
268
+ LZ4_setStreamDecode(state->dstream, dict, dictSize);
269
+ state_randomRoundTrip(state, state_prefixHCRoundTrip,
270
+ state_extDictHCRoundTrip);
271
+ LZ4_freeStreamHC(dictStream);
272
+ }
273
+
274
+ round_trip_t roundTrips[] = {
275
+ &state_prefixRoundTrip,
276
+ &state_extDictRoundTrip,
277
+ &state_loadDictRoundTrip,
278
+ &state_attachDictRoundTrip,
279
+ &state_prefixHCRoundTrip,
280
+ &state_extDictHCRoundTrip,
281
+ &state_loadDictHCRoundTrip,
282
+ &state_attachDictHCRoundTrip,
283
+ };
284
+
285
+ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
286
+ {
287
+ uint32_t seed = FUZZ_seed(&data, &size);
288
+ state_t state = state_create((char const*)data, size, seed);
289
+ const int n = sizeof(roundTrips) / sizeof(round_trip_t);
290
+ int i;
291
+
292
+ for (i = 0; i < n; ++i) {
293
+ DEBUGLOG(2, "Round trip %d", i);
294
+ state_reset(&state, seed);
295
+ roundTrips[i](&state);
296
+ state_checkRoundTrip(&state);
297
+ }
298
+
299
+ state_free(state);
300
+
301
+ return 0;
302
+ }