/work/toxcore/group_announce_fuzz_test.cc
Line | Count | Source (jump to first uncovered line) |
1 | | #include "group_announce.h" |
2 | | |
3 | | #include <cassert> |
4 | | #include <functional> |
5 | | #include <memory> |
6 | | #include <vector> |
7 | | |
8 | | #include "../testing/fuzzing/fuzz_support.h" |
9 | | #include "mem_test_util.hh" |
10 | | |
11 | | namespace { |
12 | | |
13 | | void TestUnpackAnnouncesList(Fuzz_Data &input) |
14 | 103 | { |
15 | 103 | CONSUME1_OR_RETURN(const uint8_t, max_count, input); |
16 | | // Always allocate at least something to avoid passing nullptr to functions below. |
17 | 102 | std::vector<GC_Announce> announces(max_count + 1); |
18 | | |
19 | | // TODO(iphydf): How do we know the packed size? |
20 | 102 | CONSUME1_OR_RETURN(const uint16_t, packed_size, input); |
21 | | |
22 | 93 | Logger *logger = logger_new(); |
23 | 93 | if (gca_unpack_announces_list(logger, input.data(), input.size(), announces.data(), max_count) |
24 | 93 | != -1) { |
25 | | // Always allocate at least something to avoid passing nullptr to functions below. |
26 | 49 | std::vector<uint8_t> packed(packed_size + 1); |
27 | 49 | size_t processed; |
28 | 49 | gca_pack_announces_list( |
29 | 49 | logger, packed.data(), packed_size, announces.data(), max_count, &processed); |
30 | 49 | } |
31 | 93 | logger_kill(logger); |
32 | 93 | } |
33 | | |
34 | | void TestUnpackPublicAnnounce(Fuzz_Data &input) |
35 | 6 | { |
36 | 6 | GC_Public_Announce public_announce; |
37 | | |
38 | | // TODO(iphydf): How do we know the packed size? |
39 | 6 | CONSUME1_OR_RETURN(const uint16_t, packed_size, input); |
40 | | |
41 | 5 | Logger *logger = logger_new(); |
42 | 5 | if (gca_unpack_public_announce(logger, input.data(), input.size(), &public_announce) != -1) { |
43 | | // Always allocate at least something to avoid passing nullptr to functions below. |
44 | 3 | std::vector<uint8_t> packed(packed_size + 1); |
45 | 3 | gca_pack_public_announce(logger, packed.data(), packed_size, &public_announce); |
46 | 3 | } |
47 | 5 | logger_kill(logger); |
48 | 5 | } |
49 | | |
50 | | void TestDoGca(Fuzz_Data &input) |
51 | 202 | { |
52 | 202 | Test_Memory mem; |
53 | 202 | std::unique_ptr<Logger, void (*)(Logger *)> logger(logger_new(), logger_kill); |
54 | | |
55 | 202 | uint64_t clock = 1; |
56 | 202 | std::unique_ptr<Mono_Time, std::function<void(Mono_Time *)>> mono_time( |
57 | 202 | mono_time_new( |
58 | 202 | mem, [](void *user_data) { return *static_cast<uint64_t *>(user_data); }, &clock), |
59 | 202 | [mem](Mono_Time *ptr) { mono_time_free(mem, ptr); }); |
60 | 202 | assert(mono_time != nullptr); |
61 | 202 | std::unique_ptr<GC_Announces_List, void (*)(GC_Announces_List *)> gca(new_gca_list(), kill_gca); |
62 | 202 | assert(gca != nullptr); |
63 | | |
64 | 30.3k | while (!input.empty()) { |
65 | 30.2k | CONSUME1_OR_RETURN(const uint8_t, choice, input); |
66 | 30.2k | switch (choice) { |
67 | 4.70k | case 0: { |
68 | | // Add an announce. |
69 | 4.70k | CONSUME1_OR_RETURN(const uint16_t, length, input); |
70 | 4.68k | CONSUME_OR_RETURN(const uint8_t *data, input, length); |
71 | 4.63k | GC_Public_Announce public_announce; |
72 | 4.63k | if (gca_unpack_public_announce(logger.get(), data, length, &public_announce) != -1) { |
73 | 686 | gca_add_announce(mono_time.get(), gca.get(), &public_announce); |
74 | 686 | } |
75 | 4.63k | break; |
76 | 4.68k | } |
77 | 461 | case 1: { |
78 | | // Advance the time by a number of tox_iteration_intervals. |
79 | 461 | CONSUME1_OR_RETURN(const uint8_t, iterations, input); |
80 | 460 | clock += iterations * 20; |
81 | | // Do an iteration. |
82 | 460 | do_gca(mono_time.get(), gca.get()); |
83 | 460 | break; |
84 | 461 | } |
85 | 1.07k | case 2: { |
86 | | // Get announces. |
87 | 1.07k | CONSUME1_OR_RETURN(const uint8_t, max_nodes, input); |
88 | | // Always allocate at least something to avoid passing nullptr to functions below. |
89 | 1.07k | std::vector<GC_Announce> gc_announces(max_nodes + 1); |
90 | 1.07k | CONSUME_OR_RETURN(const uint8_t *chat_id, input, CHAT_ID_SIZE); |
91 | 1.05k | CONSUME_OR_RETURN(const uint8_t *except_public_key, input, ENC_PUBLIC_KEY_SIZE); |
92 | 1.04k | gca_get_announces( |
93 | 1.04k | gca.get(), gc_announces.data(), max_nodes, chat_id, except_public_key); |
94 | 1.04k | break; |
95 | 1.05k | } |
96 | 725 | case 3: { |
97 | | // Remove a chat. |
98 | 725 | CONSUME_OR_RETURN(const uint8_t *chat_id, input, CHAT_ID_SIZE); |
99 | 713 | cleanup_gca(gca.get(), chat_id); |
100 | 713 | break; |
101 | 725 | } |
102 | 30.2k | } |
103 | 30.2k | } |
104 | 202 | } |
105 | | |
106 | | } // namespace |
107 | | |
108 | | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); |
109 | | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) |
110 | 2.99k | { |
111 | 2.99k | fuzz_select_target<TestUnpackAnnouncesList, TestUnpackPublicAnnounce, TestDoGca>(data, size); |
112 | 2.99k | return 0; |
113 | 2.99k | } |