Coverage Report

Created: 2025-10-08 19:34

/work/toxcore/events/group_invite.c
Line
Count
Source (jump to first uncovered line)
1
/* SPDX-License-Identifier: GPL-3.0-or-later
2
 * Copyright © 2023-2025 The TokTok team.
3
 */
4
5
#include "events_alloc.h"
6
7
#include <assert.h>
8
#include <stdlib.h>
9
#include <string.h>
10
11
#include "../attributes.h"
12
#include "../bin_pack.h"
13
#include "../bin_unpack.h"
14
#include "../ccompat.h"
15
#include "../mem.h"
16
#include "../tox.h"
17
#include "../tox_event.h"
18
#include "../tox_events.h"
19
20
/*****************************************************
21
 *
22
 * :: struct and accessors
23
 *
24
 *****************************************************/
25
26
struct Tox_Event_Group_Invite {
27
    uint32_t friend_number;
28
    uint8_t *invite_data;
29
    uint32_t invite_data_length;
30
    uint8_t *group_name;
31
    uint32_t group_name_length;
32
};
33
34
static void tox_event_group_invite_set_friend_number(Tox_Event_Group_Invite *_Nonnull group_invite, uint32_t friend_number)
35
97
{
36
97
    assert(group_invite != nullptr);
37
97
    group_invite->friend_number = friend_number;
38
97
}
39
uint32_t tox_event_group_invite_get_friend_number(const Tox_Event_Group_Invite *group_invite)
40
97
{
41
97
    assert(group_invite != nullptr);
42
97
    return group_invite->friend_number;
43
97
}
44
45
static bool tox_event_group_invite_set_invite_data(Tox_Event_Group_Invite *_Nonnull group_invite,
46
        const uint8_t *_Nullable invite_data, uint32_t invite_data_length)
47
97
{
48
97
    assert(group_invite != nullptr);
49
97
    if (group_invite->invite_data != nullptr) {
50
0
        free(group_invite->invite_data);
51
0
        group_invite->invite_data = nullptr;
52
0
        group_invite->invite_data_length = 0;
53
0
    }
54
55
97
    if (invite_data == nullptr) {
56
0
        assert(invite_data_length == 0);
57
0
        return true;
58
0
    }
59
60
97
    uint8_t *invite_data_copy = (uint8_t *)malloc(invite_data_length);
61
62
97
    if (invite_data_copy == nullptr) {
63
1
        return false;
64
1
    }
65
66
96
    memcpy(invite_data_copy, invite_data, invite_data_length);
67
96
    group_invite->invite_data = invite_data_copy;
68
96
    group_invite->invite_data_length = invite_data_length;
69
96
    return true;
70
97
}
71
uint32_t tox_event_group_invite_get_invite_data_length(const Tox_Event_Group_Invite *group_invite)
72
97
{
73
97
    assert(group_invite != nullptr);
74
97
    return group_invite->invite_data_length;
75
97
}
76
const uint8_t *tox_event_group_invite_get_invite_data(const Tox_Event_Group_Invite *group_invite)
77
97
{
78
97
    assert(group_invite != nullptr);
79
97
    return group_invite->invite_data;
80
97
}
81
82
static bool tox_event_group_invite_set_group_name(Tox_Event_Group_Invite *_Nonnull group_invite,
83
        const uint8_t *_Nullable group_name, uint32_t group_name_length)
84
97
{
85
97
    assert(group_invite != nullptr);
86
97
    if (group_invite->group_name != nullptr) {
87
0
        free(group_invite->group_name);
88
0
        group_invite->group_name = nullptr;
89
0
        group_invite->group_name_length = 0;
90
0
    }
91
92
97
    if (group_name == nullptr) {
93
0
        assert(group_name_length == 0);
94
0
        return true;
95
0
    }
96
97
97
    uint8_t *group_name_copy = (uint8_t *)malloc(group_name_length);
98
99
97
    if (group_name_copy == nullptr) {
100
1
        return false;
101
1
    }
102
103
96
    memcpy(group_name_copy, group_name, group_name_length);
104
96
    group_invite->group_name = group_name_copy;
105
96
    group_invite->group_name_length = group_name_length;
106
96
    return true;
107
97
}
108
uint32_t tox_event_group_invite_get_group_name_length(const Tox_Event_Group_Invite *group_invite)
109
0
{
110
0
    assert(group_invite != nullptr);
111
0
    return group_invite->group_name_length;
112
0
}
113
const uint8_t *tox_event_group_invite_get_group_name(const Tox_Event_Group_Invite *group_invite)
114
0
{
115
0
    assert(group_invite != nullptr);
116
0
    return group_invite->group_name;
117
0
}
118
119
static void tox_event_group_invite_construct(Tox_Event_Group_Invite *_Nonnull group_invite)
120
140
{
121
140
    *group_invite = (Tox_Event_Group_Invite) {
122
140
        0
123
140
    };
124
140
}
125
static void tox_event_group_invite_destruct(Tox_Event_Group_Invite *_Nonnull group_invite, const Memory *_Nonnull mem)
126
132
{
127
132
    free(group_invite->invite_data);
128
132
    free(group_invite->group_name);
129
132
}
130
131
bool tox_event_group_invite_pack(
132
    const Tox_Event_Group_Invite *event, Bin_Pack *bp)
133
54
{
134
54
    return bin_pack_array(bp, 3)
135
54
           && bin_pack_u32(bp, event->friend_number)
136
54
           && bin_pack_bin(bp, event->invite_data, event->invite_data_length)
137
54
           && bin_pack_bin(bp, event->group_name, event->group_name_length);
138
54
}
139
140
static bool tox_event_group_invite_unpack_into(Tox_Event_Group_Invite *_Nonnull event, Bin_Unpack *_Nonnull bu)
141
42
{
142
42
    assert(event != nullptr);
143
42
    if (!bin_unpack_array_fixed(bu, 3, nullptr)) {
144
2
        return false;
145
2
    }
146
147
40
    return bin_unpack_u32(bu, &event->friend_number)
148
40
           && bin_unpack_bin(bu, &event->invite_data, &event->invite_data_length)
149
40
           && bin_unpack_bin(bu, &event->group_name, &event->group_name_length);
150
42
}
151
152
/*****************************************************
153
 *
154
 * :: new/free/add/get/size/unpack
155
 *
156
 *****************************************************/
157
158
const Tox_Event_Group_Invite *tox_event_get_group_invite(const Tox_Event *event)
159
0
{
160
0
    return event->type == TOX_EVENT_GROUP_INVITE ? event->data.group_invite : nullptr;
161
0
}
162
163
Tox_Event_Group_Invite *tox_event_group_invite_new(const Memory *mem)
164
142
{
165
142
    Tox_Event_Group_Invite *const group_invite =
166
142
        (Tox_Event_Group_Invite *)mem_alloc(mem, sizeof(Tox_Event_Group_Invite));
167
168
142
    if (group_invite == nullptr) {
169
2
        return nullptr;
170
2
    }
171
172
140
    tox_event_group_invite_construct(group_invite);
173
140
    return group_invite;
174
142
}
175
176
void tox_event_group_invite_free(Tox_Event_Group_Invite *group_invite, const Memory *mem)
177
133
{
178
133
    if (group_invite != nullptr) {
179
132
        tox_event_group_invite_destruct(group_invite, mem);
180
132
    }
181
133
    mem_delete(mem, group_invite);
182
133
}
183
184
static Tox_Event_Group_Invite *tox_events_add_group_invite(Tox_Events *_Nonnull events, const Memory *_Nonnull mem)
185
99
{
186
99
    Tox_Event_Group_Invite *const group_invite = tox_event_group_invite_new(mem);
187
188
99
    if (group_invite == nullptr) {
189
1
        return nullptr;
190
1
    }
191
192
98
    Tox_Event event;
193
98
    event.type = TOX_EVENT_GROUP_INVITE;
194
98
    event.data.group_invite = group_invite;
195
196
98
    if (!tox_events_add(events, &event)) {
197
1
        tox_event_group_invite_free(group_invite, mem);
198
1
        return nullptr;
199
1
    }
200
97
    return group_invite;
201
98
}
202
203
bool tox_event_group_invite_unpack(
204
    Tox_Event_Group_Invite **event, Bin_Unpack *bu, const Memory *mem)
205
43
{
206
43
    assert(event != nullptr);
207
43
    assert(*event == nullptr);
208
43
    *event = tox_event_group_invite_new(mem);
209
210
43
    if (*event == nullptr) {
211
1
        return false;
212
1
    }
213
214
42
    return tox_event_group_invite_unpack_into(*event, bu);
215
43
}
216
217
static Tox_Event_Group_Invite *tox_event_group_invite_alloc(void *_Nonnull user_data)
218
100
{
219
100
    Tox_Events_State *state = tox_events_alloc(user_data);
220
100
    assert(state != nullptr);
221
222
100
    if (state->events == nullptr) {
223
1
        return nullptr;
224
1
    }
225
226
99
    Tox_Event_Group_Invite *group_invite = tox_events_add_group_invite(state->events, state->mem);
227
228
99
    if (group_invite == nullptr) {
229
2
        state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
230
2
        return nullptr;
231
2
    }
232
233
97
    return group_invite;
234
99
}
235
236
/*****************************************************
237
 *
238
 * :: event handler
239
 *
240
 *****************************************************/
241
242
void tox_events_handle_group_invite(
243
    Tox *tox, uint32_t friend_number, const uint8_t *invite_data, size_t invite_data_length, const uint8_t *group_name, size_t group_name_length,
244
    void *user_data)
245
100
{
246
100
    Tox_Event_Group_Invite *group_invite = tox_event_group_invite_alloc(user_data);
247
248
100
    if (group_invite == nullptr) {
249
3
        return;
250
3
    }
251
252
97
    tox_event_group_invite_set_friend_number(group_invite, friend_number);
253
97
    tox_event_group_invite_set_invite_data(group_invite, invite_data, invite_data_length);
254
97
    tox_event_group_invite_set_group_name(group_invite, group_name, group_name_length);
255
97
}