extlz4 0.3 → 0.3.1

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY.ja.md +7 -0
  3. data/README.md +3 -3
  4. data/contrib/lz4/Makefile.inc +87 -0
  5. data/contrib/lz4/NEWS +7 -0
  6. data/contrib/lz4/README.md +1 -1
  7. data/contrib/lz4/lib/README.md +3 -5
  8. data/contrib/lz4/lib/liblz4-dll.rc.in +35 -0
  9. data/contrib/lz4/lib/lz4.c +296 -182
  10. data/contrib/lz4/lib/lz4.h +125 -40
  11. data/contrib/lz4/lib/lz4frame.c +30 -6
  12. data/contrib/lz4/lib/lz4frame.h +11 -2
  13. data/contrib/lz4/lib/lz4hc.c +93 -30
  14. data/contrib/lz4/lib/lz4hc.h +3 -0
  15. data/contrib/lz4/ossfuzz/Makefile +74 -0
  16. data/contrib/lz4/ossfuzz/compress_frame_fuzzer.c +42 -0
  17. data/contrib/lz4/ossfuzz/compress_fuzzer.c +51 -0
  18. data/contrib/lz4/ossfuzz/compress_hc_fuzzer.c +57 -0
  19. data/contrib/lz4/ossfuzz/decompress_frame_fuzzer.c +67 -0
  20. data/contrib/lz4/ossfuzz/decompress_fuzzer.c +58 -0
  21. data/contrib/lz4/ossfuzz/fuzz.h +48 -0
  22. data/contrib/lz4/ossfuzz/fuzz_helpers.h +94 -0
  23. data/contrib/lz4/ossfuzz/lz4_helpers.c +51 -0
  24. data/contrib/lz4/ossfuzz/lz4_helpers.h +13 -0
  25. data/contrib/lz4/ossfuzz/ossfuzz.sh +23 -0
  26. data/contrib/lz4/ossfuzz/round_trip_frame_fuzzer.c +39 -0
  27. data/contrib/lz4/ossfuzz/round_trip_fuzzer.c +50 -0
  28. data/contrib/lz4/ossfuzz/round_trip_hc_fuzzer.c +39 -0
  29. data/contrib/lz4/ossfuzz/round_trip_stream_fuzzer.c +302 -0
  30. data/contrib/lz4/ossfuzz/standaloneengine.c +74 -0
  31. data/contrib/lz4/ossfuzz/travisoss.sh +21 -0
  32. data/ext/blockapi.c +3 -3
  33. data/ext/hashargs.c +1 -1
  34. data/lib/extlz4.rb +5 -1
  35. data/lib/extlz4/version.rb +1 -1
  36. data/test/common.rb +2 -2
  37. metadata +22 -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,39 @@
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
+
16
+ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
17
+ {
18
+ uint32_t seed = FUZZ_seed(&data, &size);
19
+ LZ4F_preferences_t const prefs = FUZZ_randomPreferences(&seed);
20
+ size_t const dstCapacity = LZ4F_compressFrameBound(size, &prefs);
21
+ char* const dst = (char*)malloc(dstCapacity);
22
+ char* const rt = (char*)malloc(size);
23
+
24
+ FUZZ_ASSERT(dst);
25
+ FUZZ_ASSERT(rt);
26
+
27
+ /* Compression must succeed and round trip correctly. */
28
+ size_t const dstSize =
29
+ LZ4F_compressFrame(dst, dstCapacity, data, size, &prefs);
30
+ FUZZ_ASSERT(!LZ4F_isError(dstSize));
31
+ size_t const rtSize = FUZZ_decompressFrame(rt, size, dst, dstSize);
32
+ FUZZ_ASSERT_MSG(rtSize == size, "Incorrect regenerated size");
33
+ FUZZ_ASSERT_MSG(!memcmp(data, rt, size), "Corruption!");
34
+
35
+ free(dst);
36
+ free(rt);
37
+
38
+ return 0;
39
+ }
@@ -0,0 +1,50 @@
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
+
14
+ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
15
+ {
16
+ uint32_t seed = FUZZ_seed(&data, &size);
17
+ size_t const dstCapacity = LZ4_compressBound(size);
18
+ char* const dst = (char*)malloc(dstCapacity);
19
+ char* const rt = (char*)malloc(size);
20
+
21
+ FUZZ_ASSERT(dst);
22
+ FUZZ_ASSERT(rt);
23
+
24
+ /* Compression must succeed and round trip correctly. */
25
+ int const dstSize = LZ4_compress_default((const char*)data, dst,
26
+ size, dstCapacity);
27
+ FUZZ_ASSERT(dstSize > 0);
28
+
29
+ int const rtSize = LZ4_decompress_safe(dst, rt, dstSize, size);
30
+ FUZZ_ASSERT_MSG(rtSize == size, "Incorrect size");
31
+ FUZZ_ASSERT_MSG(!memcmp(data, rt, size), "Corruption!");
32
+
33
+ /* Partial decompression must succeed. */
34
+ {
35
+ size_t const partialCapacity = FUZZ_rand32(&seed, 0, size);
36
+ char* const partial = (char*)malloc(partialCapacity);
37
+ FUZZ_ASSERT(partial);
38
+ int const partialSize = LZ4_decompress_safe_partial(
39
+ dst, partial, dstSize, partialCapacity, partialCapacity);
40
+ FUZZ_ASSERT(partialSize >= 0);
41
+ FUZZ_ASSERT_MSG(partialSize == partialCapacity, "Incorrect size");
42
+ FUZZ_ASSERT_MSG(!memcmp(data, partial, partialSize), "Corruption!");
43
+ free(partial);
44
+ }
45
+
46
+ free(dst);
47
+ free(rt);
48
+
49
+ return 0;
50
+ }
@@ -0,0 +1,39 @@
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 "lz4hc.h"
14
+
15
+ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
16
+ {
17
+ uint32_t seed = FUZZ_seed(&data, &size);
18
+ size_t const dstCapacity = LZ4_compressBound(size);
19
+ char* const dst = (char*)malloc(dstCapacity);
20
+ char* const rt = (char*)malloc(size);
21
+ int const level = FUZZ_rand32(&seed, LZ4HC_CLEVEL_MIN, LZ4HC_CLEVEL_MAX);
22
+
23
+ FUZZ_ASSERT(dst);
24
+ FUZZ_ASSERT(rt);
25
+
26
+ /* Compression must succeed and round trip correctly. */
27
+ int const dstSize = LZ4_compress_HC((const char*)data, dst, size,
28
+ dstCapacity, level);
29
+ FUZZ_ASSERT(dstSize > 0);
30
+
31
+ int const rtSize = LZ4_decompress_safe(dst, rt, dstSize, size);
32
+ FUZZ_ASSERT_MSG(rtSize == size, "Incorrect size");
33
+ FUZZ_ASSERT_MSG(!memcmp(data, rt, size), "Corruption!");
34
+
35
+ free(dst);
36
+ free(rt);
37
+
38
+ return 0;
39
+ }
@@ -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
+ }