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.
- checksums.yaml +4 -4
- data/HISTORY.ja.md +16 -1
- data/README.md +49 -51
- data/Rakefile +22 -0
- data/bin/extlz4 +1 -1
- data/contrib/lz4/LICENSE +2 -1
- data/contrib/lz4/Makefile.inc +111 -0
- data/contrib/lz4/NEWS +97 -0
- data/contrib/lz4/README.md +41 -36
- data/contrib/lz4/build/README.md +55 -0
- data/contrib/lz4/build/VS2010/datagen/datagen.vcxproj +169 -0
- data/contrib/lz4/build/VS2010/frametest/frametest.vcxproj +176 -0
- data/contrib/lz4/build/VS2010/fullbench/fullbench.vcxproj +176 -0
- data/contrib/lz4/build/VS2010/fullbench-dll/fullbench-dll.vcxproj +180 -0
- data/contrib/lz4/build/VS2010/fuzzer/fuzzer.vcxproj +173 -0
- data/contrib/lz4/build/VS2010/liblz4/liblz4.vcxproj +175 -0
- data/contrib/lz4/build/VS2010/liblz4-dll/liblz4-dll.rc +51 -0
- data/contrib/lz4/build/VS2010/liblz4-dll/liblz4-dll.vcxproj +179 -0
- data/contrib/lz4/build/VS2010/lz4/lz4.rc +51 -0
- data/contrib/lz4/build/VS2010/lz4/lz4.vcxproj +189 -0
- data/contrib/lz4/build/VS2010/lz4.sln +98 -0
- data/contrib/lz4/build/VS2017/datagen/datagen.vcxproj +173 -0
- data/contrib/lz4/build/VS2017/frametest/frametest.vcxproj +180 -0
- data/contrib/lz4/build/VS2017/fullbench/fullbench.vcxproj +180 -0
- data/contrib/lz4/build/VS2017/fullbench-dll/fullbench-dll.vcxproj +184 -0
- data/contrib/lz4/build/VS2017/fuzzer/fuzzer.vcxproj +177 -0
- data/contrib/lz4/build/VS2017/liblz4/liblz4.vcxproj +179 -0
- data/contrib/lz4/build/VS2017/liblz4-dll/liblz4-dll.rc +51 -0
- data/contrib/lz4/build/VS2017/liblz4-dll/liblz4-dll.vcxproj +183 -0
- data/contrib/lz4/build/VS2017/lz4/lz4.rc +51 -0
- data/contrib/lz4/build/VS2017/lz4/lz4.vcxproj +175 -0
- data/contrib/lz4/build/VS2017/lz4.sln +103 -0
- data/contrib/lz4/build/VS2022/datagen/datagen.vcxproj +173 -0
- data/contrib/lz4/build/VS2022/frametest/frametest.vcxproj +180 -0
- data/contrib/lz4/build/VS2022/fullbench/fullbench.vcxproj +180 -0
- data/contrib/lz4/build/VS2022/fullbench-dll/fullbench-dll.vcxproj +184 -0
- data/contrib/lz4/build/VS2022/fuzzer/fuzzer.vcxproj +177 -0
- data/contrib/lz4/build/VS2022/liblz4/liblz4.vcxproj +179 -0
- data/contrib/lz4/build/VS2022/liblz4-dll/liblz4-dll.rc +51 -0
- data/contrib/lz4/build/VS2022/liblz4-dll/liblz4-dll.vcxproj +183 -0
- data/contrib/lz4/build/VS2022/lz4.sln +103 -0
- data/contrib/lz4/build/cmake/CMakeLists.txt +273 -0
- data/contrib/lz4/build/cmake/lz4Config.cmake.in +2 -0
- data/contrib/lz4/lib/LICENSE +1 -1
- data/contrib/lz4/lib/README.md +111 -15
- data/contrib/lz4/lib/liblz4-dll.rc.in +35 -0
- data/contrib/lz4/lib/liblz4.pc.in +3 -3
- data/contrib/lz4/lib/lz4.c +1891 -733
- data/contrib/lz4/lib/lz4.h +597 -234
- data/contrib/lz4/lib/lz4file.c +311 -0
- data/contrib/lz4/lib/lz4file.h +93 -0
- data/contrib/lz4/lib/lz4frame.c +896 -493
- data/contrib/lz4/lib/lz4frame.h +408 -107
- data/contrib/lz4/lib/lz4frame_static.h +5 -112
- data/contrib/lz4/lib/lz4hc.c +1039 -301
- data/contrib/lz4/lib/lz4hc.h +264 -123
- data/contrib/lz4/lib/xxhash.c +376 -240
- data/contrib/lz4/lib/xxhash.h +128 -93
- data/contrib/lz4/ossfuzz/Makefile +79 -0
- data/contrib/lz4/ossfuzz/compress_frame_fuzzer.c +48 -0
- data/contrib/lz4/ossfuzz/compress_fuzzer.c +58 -0
- data/contrib/lz4/ossfuzz/compress_hc_fuzzer.c +64 -0
- data/contrib/lz4/ossfuzz/decompress_frame_fuzzer.c +75 -0
- data/contrib/lz4/ossfuzz/decompress_fuzzer.c +78 -0
- data/contrib/lz4/ossfuzz/fuzz.h +48 -0
- data/contrib/lz4/ossfuzz/fuzz_data_producer.c +77 -0
- data/contrib/lz4/ossfuzz/fuzz_data_producer.h +36 -0
- data/contrib/lz4/ossfuzz/fuzz_helpers.h +95 -0
- data/contrib/lz4/ossfuzz/lz4_helpers.c +51 -0
- data/contrib/lz4/ossfuzz/lz4_helpers.h +13 -0
- data/contrib/lz4/ossfuzz/ossfuzz.sh +23 -0
- data/contrib/lz4/ossfuzz/round_trip_frame_fuzzer.c +43 -0
- data/contrib/lz4/ossfuzz/round_trip_frame_uncompressed_fuzzer.c +134 -0
- data/contrib/lz4/ossfuzz/round_trip_fuzzer.c +117 -0
- data/contrib/lz4/ossfuzz/round_trip_hc_fuzzer.c +44 -0
- data/contrib/lz4/ossfuzz/round_trip_stream_fuzzer.c +302 -0
- data/contrib/lz4/ossfuzz/standaloneengine.c +74 -0
- data/contrib/lz4/ossfuzz/travisoss.sh +26 -0
- data/ext/blockapi.c +13 -48
- data/ext/extlz4.c +2 -0
- data/ext/extlz4.h +17 -0
- data/ext/frameapi.c +3 -14
- data/ext/hashargs.c +9 -3
- data/ext/hashargs.h +1 -1
- data/ext/lz4_amalgam.c +0 -23
- data/gemstub.rb +5 -16
- data/lib/extlz4/oldstream.rb +1 -1
- data/lib/extlz4.rb +51 -3
- data/test/common.rb +2 -2
- metadata +84 -16
- data/contrib/lz4/circle.yml +0 -38
- data/contrib/lz4/lib/lz4opt.h +0 -356
- 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
|