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