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,117 @@
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
+ size_t const largeSize = 64 * 1024 - 1;
24
+ size_t const smallSize = 1024;
25
+ char* const dstPlusLargePrefix = (char*)malloc(dstCapacity + largeSize);
26
+ FUZZ_ASSERT(dstPlusLargePrefix);
27
+ char* const dstPlusSmallPrefix = dstPlusLargePrefix + largeSize - smallSize;
28
+ char* const largeDict = (char*)malloc(largeSize);
29
+ FUZZ_ASSERT(largeDict);
30
+ char* const smallDict = largeDict + largeSize - smallSize;
31
+ char* const dst = dstPlusLargePrefix + largeSize;
32
+ char* const rt = (char*)malloc(size);
33
+ FUZZ_ASSERT(rt);
34
+
35
+ /* Compression must succeed and round trip correctly. */
36
+ int const dstSize = LZ4_compress_default((const char*)data, dst,
37
+ size, dstCapacity);
38
+ FUZZ_ASSERT(dstSize > 0);
39
+
40
+ int const rtSize = LZ4_decompress_safe(dst, rt, dstSize, size);
41
+ FUZZ_ASSERT_MSG(rtSize == size, "Incorrect size");
42
+ FUZZ_ASSERT_MSG(!memcmp(data, rt, size), "Corruption!");
43
+
44
+ /* Partial decompression must succeed. */
45
+ {
46
+ char* const partial = (char*)malloc(partialCapacity);
47
+ FUZZ_ASSERT(partial);
48
+ int const partialSize = LZ4_decompress_safe_partial(
49
+ dst, partial, dstSize, partialCapacity, partialCapacity);
50
+ FUZZ_ASSERT(partialSize >= 0);
51
+ FUZZ_ASSERT_MSG(partialSize == partialCapacity, "Incorrect size");
52
+ FUZZ_ASSERT_MSG(!memcmp(data, partial, partialSize), "Corruption!");
53
+ free(partial);
54
+ }
55
+ /* Partial decompression using dict with no dict. */
56
+ {
57
+ char* const partial = (char*)malloc(partialCapacity);
58
+ FUZZ_ASSERT(partial);
59
+ int const partialSize = LZ4_decompress_safe_partial_usingDict(
60
+ dst, partial, dstSize, partialCapacity, partialCapacity, NULL, 0);
61
+ FUZZ_ASSERT(partialSize >= 0);
62
+ FUZZ_ASSERT_MSG(partialSize == partialCapacity, "Incorrect size");
63
+ FUZZ_ASSERT_MSG(!memcmp(data, partial, partialSize), "Corruption!");
64
+ free(partial);
65
+ }
66
+ /* Partial decompression using dict with small prefix as dict */
67
+ {
68
+ char* const partial = (char*)malloc(partialCapacity);
69
+ FUZZ_ASSERT(partial);
70
+ int const partialSize = LZ4_decompress_safe_partial_usingDict(
71
+ dst, partial, dstSize, partialCapacity, partialCapacity, dstPlusSmallPrefix, smallSize);
72
+ FUZZ_ASSERT(partialSize >= 0);
73
+ FUZZ_ASSERT_MSG(partialSize == partialCapacity, "Incorrect size");
74
+ FUZZ_ASSERT_MSG(!memcmp(data, partial, partialSize), "Corruption!");
75
+ free(partial);
76
+ }
77
+ /* Partial decompression using dict with large prefix as dict */
78
+ {
79
+ char* const partial = (char*)malloc(partialCapacity);
80
+ FUZZ_ASSERT(partial);
81
+ int const partialSize = LZ4_decompress_safe_partial_usingDict(
82
+ dst, partial, dstSize, partialCapacity, partialCapacity, dstPlusLargePrefix, largeSize);
83
+ FUZZ_ASSERT(partialSize >= 0);
84
+ FUZZ_ASSERT_MSG(partialSize == partialCapacity, "Incorrect size");
85
+ FUZZ_ASSERT_MSG(!memcmp(data, partial, partialSize), "Corruption!");
86
+ free(partial);
87
+ }
88
+ /* Partial decompression using dict with small external dict */
89
+ {
90
+ char* const partial = (char*)malloc(partialCapacity);
91
+ FUZZ_ASSERT(partial);
92
+ int const partialSize = LZ4_decompress_safe_partial_usingDict(
93
+ dst, partial, dstSize, partialCapacity, partialCapacity, smallDict, smallSize);
94
+ FUZZ_ASSERT(partialSize >= 0);
95
+ FUZZ_ASSERT_MSG(partialSize == partialCapacity, "Incorrect size");
96
+ FUZZ_ASSERT_MSG(!memcmp(data, partial, partialSize), "Corruption!");
97
+ free(partial);
98
+ }
99
+ /* Partial decompression using dict with large external dict */
100
+ {
101
+ char* const partial = (char*)malloc(partialCapacity);
102
+ FUZZ_ASSERT(partial);
103
+ int const partialSize = LZ4_decompress_safe_partial_usingDict(
104
+ dst, partial, dstSize, partialCapacity, partialCapacity, largeDict, largeSize);
105
+ FUZZ_ASSERT(partialSize >= 0);
106
+ FUZZ_ASSERT_MSG(partialSize == partialCapacity, "Incorrect size");
107
+ FUZZ_ASSERT_MSG(!memcmp(data, partial, partialSize), "Corruption!");
108
+ free(partial);
109
+ }
110
+
111
+ free(dstPlusLargePrefix);
112
+ free(largeDict);
113
+ free(rt);
114
+ FUZZ_dataProducer_free(producer);
115
+
116
+ return 0;
117
+ }
@@ -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
+ }
@@ -0,0 +1,74 @@
1
+ #include <stdint.h>
2
+ #include <stdio.h>
3
+ #include <stdlib.h>
4
+
5
+ #include "fuzz.h"
6
+
7
+ /**
8
+ * Main procedure for standalone fuzzing engine.
9
+ *
10
+ * Reads filenames from the argument array. For each filename, read the file
11
+ * into memory and then call the fuzzing interface with the data.
12
+ */
13
+ int main(int argc, char **argv)
14
+ {
15
+ int ii;
16
+ for(ii = 1; ii < argc; ii++)
17
+ {
18
+ FILE *infile;
19
+ printf("[%s] ", argv[ii]);
20
+
21
+ /* Try and open the file. */
22
+ infile = fopen(argv[ii], "rb");
23
+ if(infile)
24
+ {
25
+ uint8_t *buffer = NULL;
26
+ size_t buffer_len;
27
+
28
+ printf("Opened.. ");
29
+
30
+ /* Get the length of the file. */
31
+ fseek(infile, 0L, SEEK_END);
32
+ buffer_len = ftell(infile);
33
+
34
+ /* Reset the file indicator to the beginning of the file. */
35
+ fseek(infile, 0L, SEEK_SET);
36
+
37
+ /* Allocate a buffer for the file contents. */
38
+ buffer = (uint8_t *)calloc(buffer_len, sizeof(uint8_t));
39
+ if(buffer)
40
+ {
41
+ /* Read all the text from the file into the buffer. */
42
+ fread(buffer, sizeof(uint8_t), buffer_len, infile);
43
+ printf("Read %zu bytes, fuzzing.. ", buffer_len);
44
+
45
+ /* Call the fuzzer with the data. */
46
+ LLVMFuzzerTestOneInput(buffer, buffer_len);
47
+
48
+ printf("complete !!");
49
+
50
+ /* Free the buffer as it's no longer needed. */
51
+ free(buffer);
52
+ buffer = NULL;
53
+ }
54
+ else
55
+ {
56
+ fprintf(stderr,
57
+ "[%s] Failed to allocate %zu bytes \n",
58
+ argv[ii],
59
+ buffer_len);
60
+ }
61
+
62
+ /* Close the file as it's no longer needed. */
63
+ fclose(infile);
64
+ infile = NULL;
65
+ }
66
+ else
67
+ {
68
+ /* Failed to open the file. Maybe wrong name or wrong permissions? */
69
+ fprintf(stderr, "[%s] Open failed. \n", argv[ii]);
70
+ }
71
+
72
+ printf("\n");
73
+ }
74
+ }
@@ -0,0 +1,26 @@
1
+ #!/bin/bash
2
+
3
+ set -ex
4
+
5
+ # Clone the oss-fuzz repository
6
+ git clone https://github.com/google/oss-fuzz.git /tmp/ossfuzz
7
+
8
+ if [[ ! -d /tmp/ossfuzz/projects/lz4 ]]
9
+ then
10
+ echo "Could not find the lz4 project in ossfuzz"
11
+ exit 1
12
+ fi
13
+
14
+ # Modify the oss-fuzz Dockerfile so that we're checking out the current branch on travis.
15
+ if [ "x${TRAVIS_PULL_REQUEST}" = "xfalse" ]
16
+ then
17
+ sed -i "s@https://github.com/lz4/lz4.git@-b ${TRAVIS_BRANCH} https://github.com/lz4/lz4.git@" /tmp/ossfuzz/projects/lz4/Dockerfile
18
+ else
19
+ sed -i "s@https://github.com/lz4/lz4.git@-b ${TRAVIS_PULL_REQUEST_BRANCH} https://github.com/${TRAVIS_PULL_REQUEST_SLUG}.git@" /tmp/ossfuzz/projects/lz4/Dockerfile
20
+ fi
21
+
22
+ # Try and build the fuzzers
23
+ pushd /tmp/ossfuzz
24
+ python infra/helper.py build_image --pull lz4
25
+ python infra/helper.py build_fuzzers lz4
26
+ popd