/src/ndpi/fuzz/fuzz_ds_tree.cpp
Line | Count | Source |
1 | | #include "ndpi_api.h" |
2 | | #include "fuzz_common_code.h" |
3 | | |
4 | | #include <stdint.h> |
5 | | #include <stdio.h> |
6 | | #include <assert.h> |
7 | | #include "fuzzer/FuzzedDataProvider.h" |
8 | | |
9 | | static int __compare(const void *a, const void *b) |
10 | 382k | { |
11 | 382k | u_int32_t *entry_a, *entry_b; |
12 | | |
13 | 382k | entry_a = (u_int32_t *)a; |
14 | 382k | entry_b = (u_int32_t *)b; |
15 | | |
16 | 382k | return *entry_a == *entry_b ? 0 : (*entry_a < *entry_b ? -1 : +1); |
17 | 382k | } |
18 | | static void __free(void * const node) |
19 | 8.83k | { |
20 | 8.83k | u_int32_t *entry = (u_int32_t *)node; |
21 | 8.83k | ndpi_free(entry); |
22 | 8.83k | } |
23 | | static void __walk(const void *a, ndpi_VISIT which, int depth, void *user_data) |
24 | 44.1k | { |
25 | 44.1k | (void)which; |
26 | 44.1k | (void)depth; |
27 | | |
28 | 44.1k | assert(user_data == NULL && a); |
29 | 44.1k | } |
30 | | |
31 | 222 | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
32 | 222 | FuzzedDataProvider fuzzed_data(data, size); |
33 | 222 | u_int16_t i, num_iteration, is_added = 0; |
34 | 222 | void *root = NULL; |
35 | 222 | u_int32_t *entry, value_added, e, *e2; |
36 | | |
37 | | /* Just to have some data */ |
38 | 222 | if (fuzzed_data.remaining_bytes() < 1024) |
39 | 18 | return -1; |
40 | | |
41 | | /* To allow memory allocation failures */ |
42 | 204 | fuzz_set_alloc_callbacks_and_seed(size); |
43 | | |
44 | 204 | num_iteration = fuzzed_data.ConsumeIntegral<u_int8_t>(); |
45 | 23.6k | for (i = 0; i < num_iteration; i++) { |
46 | 23.4k | entry = (u_int32_t *)ndpi_malloc(sizeof(u_int32_t)); |
47 | 23.4k | if (!entry) |
48 | 1.71k | continue; |
49 | 21.7k | *entry = fuzzed_data.ConsumeIntegral<u_int32_t>(); |
50 | | |
51 | 21.7k | if(ndpi_tfind(entry, &root, __compare) == NULL) { |
52 | 17.1k | if(ndpi_tsearch(entry, fuzzed_data.ConsumeBool() ? &root : NULL, __compare) == NULL) { |
53 | 7.50k | ndpi_free(entry); |
54 | 9.69k | } else { |
55 | | /* Keep one random entry really added */ |
56 | 9.69k | if (is_added == 0 && fuzzed_data.ConsumeBool()) { |
57 | 136 | value_added = *entry; |
58 | 136 | is_added = 1; |
59 | 136 | } |
60 | 9.69k | } |
61 | 17.1k | } else { |
62 | 4.52k | ndpi_free(entry); |
63 | 4.52k | } |
64 | 21.7k | } |
65 | | |
66 | | /* "Random" search */ |
67 | 204 | num_iteration = fuzzed_data.ConsumeIntegral<u_int8_t>(); |
68 | 8.39k | for (i = 0; i < num_iteration; i++) { |
69 | 8.19k | e = fuzzed_data.ConsumeIntegral<u_int32_t>(); |
70 | | |
71 | 8.19k | ndpi_tfind(&e, fuzzed_data.ConsumeBool() ? &root : NULL, __compare); |
72 | 8.19k | } |
73 | | /* Search of an added node */ |
74 | 204 | if (is_added) { |
75 | 136 | ndpi_tfind(&value_added, &root, __compare); |
76 | 136 | } |
77 | | |
78 | 204 | ndpi_twalk(root, __walk, NULL); |
79 | | |
80 | | /* "Random" delete */ |
81 | 204 | num_iteration = fuzzed_data.ConsumeIntegral<u_int8_t>(); |
82 | 12.9k | for (i = 0; i < num_iteration; i++) { |
83 | 12.7k | e = fuzzed_data.ConsumeIntegral<u_int32_t>(); |
84 | | |
85 | 12.7k | e2 = (u_int32_t *)ndpi_tdelete(&e, &root, __compare); |
86 | 12.7k | ndpi_free(e2); |
87 | 12.7k | } |
88 | | /* Delete of an added node */ |
89 | 204 | if (is_added) { |
90 | 136 | e2 = (u_int32_t *)ndpi_tdelete(&value_added, &root, __compare); |
91 | 136 | ndpi_free(e2); |
92 | 136 | } |
93 | | |
94 | 204 | ndpi_twalk(root, __walk, NULL); |
95 | | |
96 | 204 | ndpi_tdestroy(root, __free); |
97 | | |
98 | 204 | return 0; |
99 | 222 | } |