Coverage Report

Created: 2024-01-26 01:52

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