Coverage Report

Created: 2026-10-24 08:16

/work/toxcore/events/group_password.c
Line
Count
Source (jump to first uncovered line)
1
/* SPDX-License-Identifier: GPL-3.0-or-later
2
 * Copyright © 2023-2026 The TokTok team.
3
 */
4
5
#include "events_alloc.h"
6
7
#include <assert.h>
8
#include <string.h>
9
10
#include "../attributes.h"
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_event.h"
17
#include "../tox_events.h"
18
#include "../tox_struct.h"
19
20
/*****************************************************
21
 *
22
 * :: struct and accessors
23
 *
24
 *****************************************************/
25
26
struct Tox_Event_Group_Password {
27
    uint32_t group_number;
28
    uint8_t *_Nullable password;
29
    uint32_t password_length;
30
};
31
32
static void tox_event_group_password_set_group_number(Tox_Event_Group_Password *_Nonnull group_password, uint32_t group_number)
33
7
{
34
7
    assert(group_password != nullptr);
35
7
    group_password->group_number = group_number;
36
7
}
37
uint32_t tox_event_group_password_get_group_number(const Tox_Event_Group_Password *group_password)
38
0
{
39
0
    assert(group_password != nullptr);
40
0
    return group_password->group_number;
41
0
}
42
43
static bool tox_event_group_password_set_password(Tox_Event_Group_Password *_Nonnull group_password,
44
        const Memory *_Nonnull mem, const uint8_t *_Nullable password, uint32_t password_length)
45
7
{
46
7
    assert(group_password != nullptr);
47
7
    if (group_password->password != nullptr) {
48
0
        mem_delete(mem, group_password->password);
49
0
        group_password->password = nullptr;
50
0
        group_password->password_length = 0;
51
0
    }
52
53
7
    if (password == nullptr) {
54
0
        assert(password_length == 0);
55
0
        return true;
56
0
    }
57
58
7
    if (password_length == 0) {
59
5
        group_password->password = nullptr;
60
5
        group_password->password_length = 0;
61
5
        return true;
62
5
    }
63
64
2
    uint8_t *password_copy = (uint8_t *)mem_balloc(mem, password_length);
65
66
2
    if (password_copy == nullptr) {
67
0
        return false;
68
0
    }
69
70
2
    memcpy(password_copy, password, password_length);
71
2
    group_password->password = password_copy;
72
2
    group_password->password_length = password_length;
73
2
    return true;
74
2
}
75
uint32_t tox_event_group_password_get_password_length(const Tox_Event_Group_Password *group_password)
76
4
{
77
4
    assert(group_password != nullptr);
78
4
    return group_password->password_length;
79
4
}
80
const uint8_t *tox_event_group_password_get_password(const Tox_Event_Group_Password *group_password)
81
0
{
82
0
    assert(group_password != nullptr);
83
0
    return group_password->password;
84
0
}
85
86
static void tox_event_group_password_construct(Tox_Event_Group_Password *_Nonnull group_password)
87
32
{
88
32
    *group_password = (Tox_Event_Group_Password) {
89
32
        0
90
32
    };
91
32
}
92
static void tox_event_group_password_destruct(Tox_Event_Group_Password *_Nonnull group_password, const Memory *_Nonnull mem)
93
32
{
94
32
    mem_delete(mem, group_password->password);
95
32
}
96
97
bool tox_event_group_password_pack(
98
    const Tox_Event_Group_Password *event, Bin_Pack *bp)
99
36
{
100
36
    return bin_pack_array(bp, 2)
101
36
           && bin_pack_u32(bp, event->group_number)
102
36
           && bin_pack_bin(bp, event->password, event->password_length);
103
36
}
104
105
static bool tox_event_group_password_unpack_into(Tox_Event_Group_Password *_Nonnull event, Bin_Unpack *_Nonnull bu)
106
25
{
107
25
    assert(event != nullptr);
108
25
    if (!bin_unpack_array_fixed(bu, 2, nullptr)) {
109
1
        return false;
110
1
    }
111
112
24
    return bin_unpack_u32(bu, &event->group_number)
113
24
           && bin_unpack_bin(bu, &event->password, &event->password_length);
114
25
}
115
116
/*****************************************************
117
 *
118
 * :: new/free/add/get/size/unpack
119
 *
120
 *****************************************************/
121
122
const Tox_Event_Group_Password *tox_event_get_group_password(const Tox_Event *event)
123
0
{
124
0
    return event->type == TOX_EVENT_GROUP_PASSWORD ? event->data.group_password : nullptr;
125
0
}
126
127
Tox_Event_Group_Password *tox_event_group_password_new(const Memory *mem)
128
33
{
129
33
    Tox_Event_Group_Password *const group_password =
130
33
        (Tox_Event_Group_Password *)mem_alloc(mem, sizeof(Tox_Event_Group_Password));
131
132
33
    if (group_password == nullptr) {
133
1
        return nullptr;
134
1
    }
135
136
32
    tox_event_group_password_construct(group_password);
137
32
    return group_password;
138
33
}
139
140
void tox_event_group_password_free(Tox_Event_Group_Password *group_password, const Memory *mem)
141
33
{
142
33
    if (group_password != nullptr) {
143
32
        tox_event_group_password_destruct(group_password, mem);
144
32
    }
145
33
    mem_delete(mem, group_password);
146
33
}
147
148
static Tox_Event_Group_Password *_Nullable tox_events_add_group_password(Tox_Events *_Nonnull events, const Memory *_Nonnull mem)
149
7
{
150
7
    Tox_Event_Group_Password *const group_password = tox_event_group_password_new(mem);
151
152
7
    if (group_password == nullptr) {
153
0
        return nullptr;
154
0
    }
155
156
7
    Tox_Event event;
157
7
    event.type = TOX_EVENT_GROUP_PASSWORD;
158
7
    event.data.group_password = group_password;
159
160
7
    if (!tox_events_add(events, &event)) {
161
0
        tox_event_group_password_free(group_password, mem);
162
0
        return nullptr;
163
0
    }
164
7
    return group_password;
165
7
}
166
167
bool tox_event_group_password_unpack(
168
    Tox_Event_Group_Password **event, Bin_Unpack *bu, const Memory *mem)
169
26
{
170
26
    assert(event != nullptr);
171
26
    assert(*event == nullptr);
172
26
    *event = tox_event_group_password_new(mem);
173
174
26
    if (*event == nullptr) {
175
1
        return false;
176
1
    }
177
178
25
    return tox_event_group_password_unpack_into(*event, bu);
179
26
}
180
181
static Tox_Event_Group_Password *_Nullable tox_event_group_password_alloc(Tox_Events_State *_Nonnull state)
182
7
{
183
7
    if (state->events == nullptr) {
184
0
        return nullptr;
185
0
    }
186
187
7
    Tox_Event_Group_Password *group_password = tox_events_add_group_password(state->events, state->mem);
188
189
7
    if (group_password == nullptr) {
190
0
        state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
191
0
        return nullptr;
192
0
    }
193
194
7
    return group_password;
195
7
}
196
197
/*****************************************************
198
 *
199
 * :: event handler
200
 *
201
 *****************************************************/
202
203
void tox_events_handle_group_password(
204
    Tox *_Nonnull tox,
205
    uint32_t group_number,
206
    const uint8_t *_Nullable password, size_t password_length,
207
    void *_Nullable user_data)
208
7
{
209
7
    Tox_Events_State *state = tox_events_alloc(user_data);
210
7
    Tox_Event_Group_Password *group_password = tox_event_group_password_alloc(state);
211
212
7
    if (group_password == nullptr) {
213
0
        return;
214
0
    }
215
216
7
    tox_event_group_password_set_group_number(group_password, group_number);
217
7
    if (!tox_event_group_password_set_password(group_password, state->mem, password, password_length)) {
218
0
        tox_event_group_password_free(group_password, state->mem);
219
0
        state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
220
0
        return;
221
0
    }
222
7
}
223
224
void tox_events_handle_group_password_dispatch(Tox *tox, const Tox_Event_Group_Password *event, void *user_data)
225
0
{
226
0
    if (tox->group_password_callback == nullptr) {
227
0
        return;
228
0
    }
229
230
0
    tox_unlock(tox);
231
0
    tox->group_password_callback(tox, event->group_number, event->password, event->password_length, user_data);
232
0
    tox_lock(tox);
233
0
}