Coverage Report

Created: 2025-10-08 19:34

/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
}