Merge commit '8eb4892b4976e82e020d0e30dcf8f0705b76bb4e'

This commit is contained in:
2024-01-12 21:30:48 +01:00
126 changed files with 1556 additions and 2484 deletions

View File

@ -10,6 +10,23 @@ exports_files(
visibility = ["//c-toxcore:__pkg__"],
)
cc_library(
name = "test_util",
srcs = ["test_util.cc"],
hdrs = ["test_util.hh"],
)
cc_test(
name = "test_util_test",
size = "small",
srcs = ["test_util_test.cc"],
deps = [
":crypto_core_test_util",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)
cc_library(
name = "attributes",
hdrs = ["attributes.h"],
@ -71,6 +88,7 @@ cc_test(
srcs = ["util_test.cc"],
deps = [
":crypto_core",
":crypto_core_test_util",
":util",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
@ -142,6 +160,16 @@ cc_library(
],
)
cc_library(
name = "crypto_core_test_util",
srcs = ["crypto_core_test_util.cc"],
hdrs = ["crypto_core_test_util.hh"],
deps = [
":crypto_core",
":test_util",
],
)
cc_test(
name = "crypto_core_test",
size = "small",
@ -149,6 +177,7 @@ cc_test(
flaky = True,
deps = [
":crypto_core",
":crypto_core_test_util",
":util",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
@ -261,6 +290,17 @@ cc_library(
],
)
cc_library(
name = "network_test_util",
srcs = ["network_test_util.cc"],
hdrs = ["network_test_util.hh"],
deps = [
":crypto_core",
":network",
":test_util",
],
)
cc_test(
name = "network_test",
size = "small",
@ -357,13 +397,28 @@ cc_library(
],
)
cc_library(
name = "DHT_test_util",
srcs = ["DHT_test_util.cc"],
hdrs = ["DHT_test_util.hh"],
deps = [
":DHT",
":crypto_core",
":crypto_core_test_util",
":network_test_util",
":test_util",
],
)
cc_test(
name = "DHT_test",
size = "small",
srcs = ["DHT_test.cc"],
deps = [
":DHT",
":DHT_test_util",
":crypto_core",
":network_test_util",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
@ -881,6 +936,7 @@ cc_fuzz_test(
srcs = ["tox_events_fuzz_test.cc"],
corpus = ["//tools/toktok-fuzzer/corpus:tox_events_fuzz_test"],
deps = [
":tox_dispatch",
":tox_events",
"//c-toxcore/testing/fuzzing:fuzz_support",
],

View File

@ -448,8 +448,8 @@ int dht_create_packet(const Memory *mem, const Random *rng,
const uint8_t *plain, size_t plain_length,
uint8_t *packet, size_t length)
{
uint8_t *encrypted = (uint8_t *)mem_balloc(mem, plain_length + CRYPTO_MAC_SIZE);
uint8_t nonce[CRYPTO_NONCE_SIZE];
uint8_t *encrypted = (uint8_t *)mem_balloc(mem, plain_length + CRYPTO_MAC_SIZE);
if (encrypted == nullptr) {
return -1;
@ -750,16 +750,21 @@ static bool client_or_ip_port_in_list(const Logger *log, const Mono_Time *mono_t
return true;
}
bool add_to_list(Node_format *nodes_list, uint32_t length, const uint8_t *pk, const IP_Port *ip_port,
const uint8_t *cmp_pk)
bool add_to_list(
Node_format *nodes_list, uint32_t length, const uint8_t pk[CRYPTO_PUBLIC_KEY_SIZE],
const IP_Port *ip_port, const uint8_t cmp_pk[CRYPTO_PUBLIC_KEY_SIZE])
{
for (uint32_t i = 0; i < length; ++i) {
if (id_closest(cmp_pk, nodes_list[i].public_key, pk) == 2) {
Node_format *node = &nodes_list[i];
if (id_closest(cmp_pk, node->public_key, pk) == 2) {
uint8_t pk_bak[CRYPTO_PUBLIC_KEY_SIZE];
memcpy(pk_bak, nodes_list[i].public_key, CRYPTO_PUBLIC_KEY_SIZE);
const IP_Port ip_port_bak = nodes_list[i].ip_port;
memcpy(nodes_list[i].public_key, pk, CRYPTO_PUBLIC_KEY_SIZE);
nodes_list[i].ip_port = *ip_port;
memcpy(pk_bak, node->public_key, CRYPTO_PUBLIC_KEY_SIZE);
const IP_Port ip_port_bak = node->ip_port;
memcpy(node->public_key, pk, CRYPTO_PUBLIC_KEY_SIZE);
node->ip_port = *ip_port;
if (i != length - 1) {
add_to_list(nodes_list, length, pk_bak, &ip_port_bak, cmp_pk);
@ -776,10 +781,11 @@ bool add_to_list(Node_format *nodes_list, uint32_t length, const uint8_t *pk, co
* helper for `get_close_nodes()`. argument list is a monster :D
*/
non_null()
static void get_close_nodes_inner(uint64_t cur_time, const uint8_t *public_key, Node_format *nodes_list,
Family sa_family, const Client_data *client_list, uint32_t client_list_length,
uint32_t *num_nodes_ptr, bool is_lan,
bool want_announce)
static void get_close_nodes_inner(
uint64_t cur_time, const uint8_t *public_key,
Node_format *nodes_list, uint32_t *num_nodes_ptr,
Family sa_family, const Client_data *client_list, uint32_t client_list_length,
bool is_lan, bool want_announce)
{
if (!net_family_is_ipv4(sa_family) && !net_family_is_ipv6(sa_family) && !net_family_is_unspec(sa_family)) {
return;
@ -846,28 +852,44 @@ static void get_close_nodes_inner(uint64_t cur_time, const uint8_t *public_key,
* want_announce: return only nodes which implement the dht announcements protocol.
*/
non_null()
static int get_somewhat_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list,
Family sa_family, bool is_lan, bool want_announce)
static int get_somewhat_close_nodes(
uint64_t cur_time, const uint8_t *public_key, Node_format *nodes_list,
Family sa_family, const Client_data *close_clientlist,
const DHT_Friend *friends_list, uint16_t friends_list_size,
bool is_lan, bool want_announce)
{
uint32_t num_nodes = 0;
get_close_nodes_inner(dht->cur_time, public_key, nodes_list, sa_family,
dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_lan, want_announce);
memset(nodes_list, 0, MAX_SENT_NODES * sizeof(Node_format));
for (uint32_t i = 0; i < dht->num_friends; ++i) {
get_close_nodes_inner(dht->cur_time, public_key, nodes_list, sa_family,
dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
&num_nodes, is_lan, want_announce);
uint32_t num_nodes = 0;
get_close_nodes_inner(
cur_time, public_key,
nodes_list, &num_nodes,
sa_family, close_clientlist, LCLIENT_LIST,
is_lan, want_announce);
for (uint16_t i = 0; i < friends_list_size; ++i) {
const DHT_Friend *dht_friend = &friends_list[i];
get_close_nodes_inner(
cur_time, public_key,
nodes_list, &num_nodes,
sa_family, dht_friend->client_list, MAX_FRIEND_CLIENTS,
is_lan, want_announce);
}
return num_nodes;
}
int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list, Family sa_family,
bool is_lan, bool want_announce)
int get_close_nodes(
const DHT *dht, const uint8_t *public_key,
Node_format *nodes_list, Family sa_family,
bool is_lan, bool want_announce)
{
memset(nodes_list, 0, MAX_SENT_NODES * sizeof(Node_format));
return get_somewhat_close_nodes(dht, public_key, nodes_list, sa_family,
is_lan, want_announce);
return get_somewhat_close_nodes(
dht->cur_time, public_key, nodes_list,
sa_family, dht->close_clientlist,
dht->friends_list, dht->num_friends,
is_lan, want_announce);
}
typedef struct DHT_Cmp_Data {
@ -2903,23 +2925,27 @@ static State_Load_Status dht_load_state_callback(void *outer, const uint8_t *dat
}
mem_delete(dht->mem, dht->loaded_nodes_list);
// Copy to loaded_clients_list
dht->loaded_nodes_list = (Node_format *)mem_valloc(dht->mem, MAX_SAVED_DHT_NODES, sizeof(Node_format));
if (dht->loaded_nodes_list == nullptr) {
// Copy to loaded_clients_list
Node_format *nodes = (Node_format *)mem_valloc(dht->mem, MAX_SAVED_DHT_NODES, sizeof(Node_format));
if (nodes == nullptr) {
LOGGER_ERROR(dht->log, "could not allocate %u nodes", MAX_SAVED_DHT_NODES);
dht->loaded_num_nodes = 0;
break;
}
const int num = unpack_nodes(dht->loaded_nodes_list, MAX_SAVED_DHT_NODES, nullptr, data, length, false);
const int num = unpack_nodes(nodes, MAX_SAVED_DHT_NODES, nullptr, data, length, false);
if (num > 0) {
dht->loaded_num_nodes = num;
} else {
if (num < 0) {
// Unpack error happened, we ignore it.
dht->loaded_num_nodes = 0;
} else {
dht->loaded_num_nodes = num;
}
dht->loaded_nodes_list = nodes;
break;
}

View File

@ -370,7 +370,8 @@ unsigned int bit_by_bit_cmp(const uint8_t *pk1, const uint8_t *pk2);
*/
non_null()
bool add_to_list(
Node_format *nodes_list, uint32_t length, const uint8_t *pk, const IP_Port *ip_port, const uint8_t *cmp_pk);
Node_format *nodes_list, uint32_t length, const uint8_t pk[CRYPTO_PUBLIC_KEY_SIZE],
const IP_Port *ip_port, const uint8_t cmp_pk[CRYPTO_PUBLIC_KEY_SIZE]);
/** Return 1 if node can be added to close list, 0 if it can't. */
non_null()
@ -383,18 +384,20 @@ void set_announce_node(DHT *dht, const uint8_t *public_key);
#endif
/**
* Get the (maximum MAX_SENT_NODES) closest nodes to public_key we know
* @brief Get the (maximum MAX_SENT_NODES) closest nodes to public_key we know
* and put them in nodes_list (must be MAX_SENT_NODES big).
*
* sa_family = family (IPv4 or IPv6) (0 if we don't care)?
* is_LAN = return some LAN ips (true or false)
* want_announce: return only nodes which implement the dht announcements protocol.
* @param sa_family family (IPv4 or IPv6) (0 if we don't care)?
* @param is_lan return some LAN ips (true or false).
* @param want_announce return only nodes which implement the dht announcements protocol.
*
* @return the number of nodes returned.
*/
non_null()
int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list, Family sa_family,
bool is_lan, bool want_announce);
int get_close_nodes(
const DHT *dht, const uint8_t *public_key,
Node_format *nodes_list, Family sa_family,
bool is_lan, bool want_announce);
/** @brief Put up to max_num nodes in nodes from the random friends.

View File

@ -23,7 +23,7 @@ void TestHandleRequest(Fuzz_Data &input)
void TestUnpackNodes(Fuzz_Data &input)
{
CONSUME1_OR_RETURN(const bool tcp_enabled, input);
CONSUME1_OR_RETURN(const bool, tcp_enabled, input);
const uint16_t node_count = 5;
Node_format nodes[node_count];

View File

@ -1,15 +1,26 @@
#include "DHT.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <algorithm>
#include <array>
#include <cstring>
#include <random>
#include "DHT_test_util.hh"
#include "crypto_core.h"
#include "crypto_core_test_util.hh"
#include "network_test_util.hh"
namespace {
using PublicKey = std::array<uint8_t, CRYPTO_PUBLIC_KEY_SIZE>;
using ::testing::Each;
using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::PrintToString;
using ::testing::UnorderedElementsAre;
using SecretKey = std::array<uint8_t, CRYPTO_SECRET_KEY_SIZE>;
struct KeyPair {
@ -19,72 +30,66 @@ struct KeyPair {
explicit KeyPair(const Random *rng) { crypto_new_keypair(rng, pk.data(), sk.data()); }
};
template <typename T, size_t N>
std::array<T, N> to_array(T const (&arr)[N])
TEST(IdClosest, KeyIsClosestToItself)
{
std::array<T, N> stdarr;
std::copy(arr, arr + N, stdarr.begin());
return stdarr;
}
Test_Random rng;
PublicKey random_pk(const Random *rng)
{
PublicKey pk;
random_bytes(rng, pk.data(), pk.size());
return pk;
PublicKey pk0 = random_pk(rng);
PublicKey pk1;
do {
// Get a random key that's not the same as pk0.
pk1 = random_pk(rng);
} while (pk0 == pk1);
EXPECT_EQ(id_closest(pk0.data(), pk0.data(), pk1.data()), 1);
}
TEST(IdClosest, IdenticalKeysAreSameDistance)
{
const Random *rng = system_random();
ASSERT_NE(rng, nullptr);
Test_Random rng;
PublicKey pk0 = random_pk(rng);
PublicKey pk1 = random_pk(rng);
PublicKey pk2 = pk1;
EXPECT_EQ(id_closest(pk0.data(), pk1.data(), pk2.data()), 0);
EXPECT_EQ(id_closest(pk0.data(), pk1.data(), pk1.data()), 0);
}
TEST(IdClosest, DistanceIsCommutative)
{
const Random *rng = system_random();
ASSERT_NE(rng, nullptr);
Test_Random rng;
for (uint32_t i = 0; i < 100; ++i) {
PublicKey pk0 = random_pk(rng);
PublicKey pk1 = random_pk(rng);
PublicKey pk2 = random_pk(rng);
PublicKey pk0 = random_pk(rng);
PublicKey pk1 = random_pk(rng);
PublicKey pk2 = random_pk(rng);
ASSERT_NE(pk1, pk2); // RNG can't produce the same random key twice
ASSERT_NE(pk1, pk2); // RNG can't produce the same random key twice
// Two non-equal keys can't have the same distance from any given key.
EXPECT_NE(id_closest(pk0.data(), pk1.data(), pk2.data()), 0);
// Two non-equal keys can't have the same distance from any given key.
EXPECT_NE(id_closest(pk0.data(), pk1.data(), pk2.data()), 0);
if (id_closest(pk0.data(), pk1.data(), pk2.data()) == 1) {
EXPECT_EQ(id_closest(pk0.data(), pk2.data(), pk1.data()), 2);
}
if (id_closest(pk0.data(), pk1.data(), pk2.data()) == 1) {
EXPECT_EQ(id_closest(pk0.data(), pk2.data(), pk1.data()), 2);
}
if (id_closest(pk0.data(), pk1.data(), pk2.data()) == 2) {
EXPECT_EQ(id_closest(pk0.data(), pk2.data(), pk1.data()), 1);
}
if (id_closest(pk0.data(), pk1.data(), pk2.data()) == 2) {
EXPECT_EQ(id_closest(pk0.data(), pk2.data(), pk1.data()), 1);
}
}
TEST(IdClosest, SmallXorDistanceIsCloser)
{
PublicKey const pk0 = {{0xaa}};
PublicKey const pk1 = {{0xa0}};
PublicKey const pk2 = {{0x0a}};
PublicKey const pk0 = {0xaa};
PublicKey const pk1 = {0xa0};
PublicKey const pk2 = {0x0a};
EXPECT_EQ(id_closest(pk0.data(), pk1.data(), pk2.data()), 1);
}
TEST(IdClosest, DistinctKeysCannotHaveTheSameDistance)
{
PublicKey const pk0 = {{0x06}};
PublicKey const pk1 = {{0x00}};
PublicKey pk2 = {{0x00}};
PublicKey const pk0 = {0x06};
PublicKey const pk1 = {0x00};
PublicKey pk2 = {0x00};
for (uint8_t i = 1; i < 0xff; ++i) {
pk2[0] = i;
@ -94,14 +99,14 @@ TEST(IdClosest, DistinctKeysCannotHaveTheSameDistance)
TEST(AddToList, OverridesKeysWithCloserKeys)
{
PublicKey const self_pk = {{0xaa}};
PublicKey const self_pk = {0xaa};
PublicKey const keys[] = {
{{0xa0}}, // closest
{{0x0a}}, //
{{0x0b}}, //
{{0x0c}}, //
{{0x0d}}, //
{{0xa1}}, // closer than the 4 keys above
{0xa0}, // closest
{0x0a}, //
{0x0b}, //
{0x0c}, //
{0x0d}, //
{0xa1}, // closer than the 4 keys above
};
std::array<Node_format, 4> nodes{};
@ -128,10 +133,143 @@ TEST(AddToList, OverridesKeysWithCloserKeys)
EXPECT_EQ(to_array(nodes[3].public_key), keys[2]);
}
Node_format fill(Node_format v, PublicKey const &pk, IP_Port const &ip_port)
{
std::copy(pk.begin(), pk.end(), v.public_key);
v.ip_port = ip_port;
return v;
}
TEST(AddToList, AddsFirstKeysInOrder)
{
Test_Random rng;
// Make cmp_key the furthest away from 00000... as possible, so all initial inserts succeed.
PublicKey const cmp_pk{0xff, 0xff, 0xff, 0xff};
// Generate a bunch of other keys, sorted by distance from cmp_pk.
auto const keys
= sorted(array_of<20>(random_pk, rng), [&cmp_pk](auto const &pk1, auto const &pk2) {
return id_closest(cmp_pk.data(), pk1.data(), pk2.data()) == 1;
});
auto const ips = array_of<20>(increasing_ip_port(0, rng));
std::vector<Node_format> nodes(4);
// Add a bunch of nodes.
ASSERT_TRUE(add_to_list(nodes.data(), nodes.size(), keys[2].data(), &ips[2], cmp_pk.data()))
<< "failed to insert\n"
<< " cmp_pk = " << cmp_pk << "\n"
<< " pk = " << keys[2] << "\n"
<< " nodes_list = " << PrintToString(nodes);
ASSERT_TRUE(add_to_list(nodes.data(), nodes.size(), keys[5].data(), &ips[5], cmp_pk.data()))
<< "failed to insert\n"
<< " cmp_pk = " << cmp_pk << "\n"
<< " pk = " << keys[5] << "\n"
<< " nodes_list = " << PrintToString(nodes);
ASSERT_TRUE(add_to_list(nodes.data(), nodes.size(), keys[7].data(), &ips[7], cmp_pk.data()))
<< "failed to insert\n"
<< " cmp_pk = " << cmp_pk << "\n"
<< " pk = " << keys[7] << "\n"
<< " nodes_list = " << PrintToString(nodes);
ASSERT_TRUE(add_to_list(nodes.data(), nodes.size(), keys[9].data(), &ips[9], cmp_pk.data()))
<< "failed to insert\n"
<< " cmp_pk = " << cmp_pk << "\n"
<< " pk = " << keys[9] << "\n"
<< " nodes_list = " << PrintToString(nodes);
// They should all appear in order.
EXPECT_THAT(nodes,
ElementsAre( //
fill(Node_format{}, keys[2], ips[2]), //
fill(Node_format{}, keys[5], ips[5]), //
fill(Node_format{}, keys[7], ips[7]), //
fill(Node_format{}, keys[9], ips[9])));
// Adding another node that's further away will not happen.
ASSERT_FALSE(add_to_list(nodes.data(), nodes.size(), keys[10].data(), &ips[10], cmp_pk.data()))
<< "incorrectly inserted\n"
<< " cmp_pk = " << cmp_pk << "\n"
<< " pk = " << keys[10] << "\n"
<< " nodes_list = " << PrintToString(nodes);
// Now shuffle each time we add a node, which should work fine.
std::mt19937 mt_rng;
// Adding one that's closer will happen.
std::shuffle(nodes.begin(), nodes.end(), mt_rng);
ASSERT_TRUE(add_to_list(nodes.data(), nodes.size(), keys[8].data(), &ips[8], cmp_pk.data()))
<< "failed to insert\n"
<< " cmp_pk = " << cmp_pk << "\n"
<< " pk = " << keys[8] << "\n"
<< " nodes_list = " << PrintToString(nodes);
EXPECT_THAT(nodes,
UnorderedElementsAre( //
fill(Node_format{}, keys[2], ips[2]), //
fill(Node_format{}, keys[5], ips[5]), //
fill(Node_format{}, keys[7], ips[7]), //
fill(Node_format{}, keys[8], ips[8])));
// Adding one that's closer than almost all of them will happen.
std::shuffle(nodes.begin(), nodes.end(), mt_rng);
ASSERT_TRUE(add_to_list(nodes.data(), nodes.size(), keys[4].data(), &ips[4], cmp_pk.data()))
<< "failed to insert\n"
<< " cmp_pk = " << cmp_pk << "\n"
<< " pk = " << keys[4] << "\n"
<< " nodes_list = " << PrintToString(nodes);
EXPECT_THAT(nodes,
UnorderedElementsAre( //
fill(Node_format{}, keys[2], ips[2]), //
fill(Node_format{}, keys[4], ips[4]), //
fill(Node_format{}, keys[5], ips[5]), //
fill(Node_format{}, keys[7], ips[7])));
// Adding one that's closer than all of them will happen.
std::shuffle(nodes.begin(), nodes.end(), mt_rng);
ASSERT_TRUE(add_to_list(nodes.data(), nodes.size(), keys[1].data(), &ips[1], cmp_pk.data()))
<< "failed to insert\n"
<< " cmp_pk = " << cmp_pk << "\n"
<< " pk = " << keys[1] << "\n"
<< " nodes_list = " << PrintToString(nodes);
EXPECT_THAT(nodes,
UnorderedElementsAre( //
fill(Node_format{}, keys[1], ips[1]), //
fill(Node_format{}, keys[2], ips[2]), //
fill(Node_format{}, keys[4], ips[4]), //
fill(Node_format{}, keys[5], ips[5])));
}
TEST(AddToList, KeepsKeysInOrder)
{
Test_Random rng;
// Any random cmp_pk should work, as well as the smallest or (approximately) largest pk.
for (PublicKey const cmp_pk : {random_pk(rng), PublicKey{0x00}, PublicKey{0xff, 0xff}}) {
auto const by_distance = [&cmp_pk](auto const &node1, auto const &node2) {
return id_closest(cmp_pk.data(), node1.public_key, node2.public_key) == 1;
};
// Generate a bunch of other keys, not sorted.
auto const nodes = vector_of(16, random_node_format, rng);
std::vector<Node_format> node_list(4);
// Add all of them.
for (Node_format const &node : nodes) {
add_to_list(
node_list.data(), node_list.size(), node.public_key, &node.ip_port, cmp_pk.data());
// Nodes should always be sorted.
EXPECT_THAT(node_list, Eq(sorted(node_list, by_distance)));
}
}
}
TEST(Request, CreateAndParse)
{
const Random *rng = system_random();
ASSERT_NE(rng, nullptr);
Test_Random rng;
// Peers.
const KeyPair sender(rng);
@ -187,7 +325,7 @@ TEST(Request, CreateAndParse)
TEST(AnnounceNodes, SetAndTest)
{
const Random *rng = system_random();
Test_Random rng;
const Network *ns = system_network();
const Memory *mem = system_memory();
@ -195,40 +333,40 @@ TEST(AnnounceNodes, SetAndTest)
ASSERT_NE(log, nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
ASSERT_NE(mono_time, nullptr);
Networking_Core *net = new_networking_no_udp(log, mem, ns);
Ptr<Networking_Core> net(new_networking_no_udp(log, mem, ns));
ASSERT_NE(net, nullptr);
DHT *dht = new_dht(log, mem, rng, ns, mono_time, net, true, true);
Ptr<DHT> dht(new_dht(log, mem, rng, ns, mono_time, net.get(), true, true));
ASSERT_NE(dht, nullptr);
uint8_t pk_data[CRYPTO_PUBLIC_KEY_SIZE];
memcpy(pk_data, dht_get_self_public_key(dht), sizeof(pk_data));
PublicKey self_pk = to_array(pk_data);
memcpy(pk_data, dht_get_self_public_key(dht.get()), sizeof(pk_data));
PublicKey self_pk(to_array(pk_data));
PublicKey pk1 = random_pk(rng);
ASSERT_NE(pk1, self_pk);
// Test with maximally close key to self
pk_data[CRYPTO_PUBLIC_KEY_SIZE - 1] = ~pk_data[CRYPTO_PUBLIC_KEY_SIZE - 1];
PublicKey pk2 = to_array(pk_data);
PublicKey pk2(to_array(pk_data));
ASSERT_NE(pk2, pk1);
IP_Port ip_port = {0};
ip_port.ip.family = net_family_ipv4();
set_announce_node(dht, pk1.data());
set_announce_node(dht, pk2.data());
set_announce_node(dht.get(), pk1.data());
set_announce_node(dht.get(), pk2.data());
EXPECT_TRUE(addto_lists(dht, &ip_port, pk1.data()));
EXPECT_TRUE(addto_lists(dht, &ip_port, pk2.data()));
EXPECT_TRUE(addto_lists(dht.get(), &ip_port, pk1.data()));
EXPECT_TRUE(addto_lists(dht.get(), &ip_port, pk2.data()));
Node_format nodes[MAX_SENT_NODES];
EXPECT_EQ(0, get_close_nodes(dht, self_pk.data(), nodes, net_family_unspec(), true, true));
set_announce_node(dht, pk1.data());
set_announce_node(dht, pk2.data());
EXPECT_EQ(2, get_close_nodes(dht, self_pk.data(), nodes, net_family_unspec(), true, true));
EXPECT_EQ(
0, get_close_nodes(dht.get(), self_pk.data(), nodes, net_family_unspec(), true, true));
set_announce_node(dht.get(), pk1.data());
set_announce_node(dht.get(), pk2.data());
EXPECT_EQ(
2, get_close_nodes(dht.get(), self_pk.data(), nodes, net_family_unspec(), true, true));
kill_dht(dht);
kill_networking(net);
mono_time_free(mem, mono_time);
logger_kill(log);
}

View File

@ -0,0 +1,29 @@
#include "DHT_test_util.hh"
#include <cstring>
#include <iomanip>
#include "crypto_core_test_util.hh"
#include "network_test_util.hh"
Node_format random_node_format(const Random *rng)
{
Node_format node;
auto const pk = random_pk(rng);
std::copy(pk.begin(), pk.end(), node.public_key);
node.ip_port = random_ip_port(rng);
return node;
}
bool operator==(Node_format const &a, Node_format const &b)
{
return std::memcmp(a.public_key, b.public_key, sizeof(a.public_key)) == 0
&& a.ip_port == b.ip_port;
}
std::ostream &operator<<(std::ostream &out, Node_format const &v)
{
return out << "\n Node_format{\n"
<< " public_key = " << PublicKey(v.public_key) << ",\n"
<< " ip_port = " << v.ip_port << " }";
}

View File

@ -0,0 +1,18 @@
#ifndef C_TOXCORE_TOXCORE_DHT_TEST_UTIL_H
#define C_TOXCORE_TOXCORE_DHT_TEST_UTIL_H
#include <iosfwd>
#include "DHT.h"
#include "test_util.hh"
template <>
struct Deleter<DHT> : Function_Deleter<DHT, kill_dht> { };
bool operator==(Node_format const &a, Node_format const &b);
std::ostream &operator<<(std::ostream &out, Node_format const &v);
Node_format random_node_format(const Random *rng);
#endif // C_TOXCORE_TOXCORE_DHT_TEST_UTIL_H

View File

@ -62,35 +62,38 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns)
return nullptr;
}
IP_ADAPTER_INFO *pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
unsigned long ulOutBufLen = sizeof(IP_ADAPTER_INFO);
IP_ADAPTER_INFO *adapter_info = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
if (pAdapterInfo == nullptr) {
if (adapter_info == nullptr) {
free(broadcast);
return nullptr;
}
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
free(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);
unsigned long out_buf_len = sizeof(IP_ADAPTER_INFO);
if (pAdapterInfo == nullptr) {
if (GetAdaptersInfo(adapter_info, &out_buf_len) == ERROR_BUFFER_OVERFLOW) {
free(adapter_info);
IP_ADAPTER_INFO *new_adapter_info = (IP_ADAPTER_INFO *)malloc(out_buf_len);
if (new_adapter_info == nullptr) {
free(broadcast);
return nullptr;
}
adapter_info = new_adapter_info;
}
const int ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
const int ret = GetAdaptersInfo(adapter_info, &out_buf_len);
if (ret == NO_ERROR) {
IP_ADAPTER_INFO *pAdapter = pAdapterInfo;
IP_ADAPTER_INFO *adapter = adapter_info;
while (pAdapter != nullptr) {
while (adapter != nullptr) {
IP gateway = {0};
IP subnet_mask = {0};
if (addr_parse_ip(pAdapter->IpAddressList.IpMask.String, &subnet_mask)
&& addr_parse_ip(pAdapter->GatewayList.IpAddress.String, &gateway)) {
if (addr_parse_ip(adapter->IpAddressList.IpMask.String, &subnet_mask)
&& addr_parse_ip(adapter->GatewayList.IpAddress.String, &gateway)) {
if (net_family_is_ipv4(gateway.family) && net_family_is_ipv4(subnet_mask.family)) {
IP *ip = &broadcast->ips[broadcast->count];
ip->family = net_family_ipv4();
@ -106,12 +109,12 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns)
}
}
pAdapter = pAdapter->Next;
adapter = adapter->Next;
}
}
if (pAdapterInfo != nullptr) {
free(pAdapterInfo);
if (adapter_info != nullptr) {
free(adapter_info);
}
return broadcast;

View File

@ -105,17 +105,19 @@ static bool add_priority(TCP_Connection *con, const uint8_t *packet, uint16_t si
return false;
}
new_list->next = nullptr;
new_list->size = size;
new_list->sent = sent;
new_list->data = (uint8_t *)mem_balloc(con->mem, size);
uint8_t *data = (uint8_t *)mem_balloc(con->mem, size);
if (new_list->data == nullptr) {
if (data == nullptr) {
mem_delete(con->mem, new_list);
return false;
}
memcpy(new_list->data, packet, size);
memcpy(data, packet, size);
new_list->data = data;
new_list->size = size;
new_list->next = nullptr;
new_list->sent = sent;
if (p != nullptr) {
p->next = new_list;

View File

@ -290,8 +290,9 @@ static TCP_con *get_tcp_connection(const TCP_Connections *tcp_c, int tcp_connect
uint32_t tcp_connected_relays_count(const TCP_Connections *tcp_c)
{
uint32_t count = 0;
const uint32_t size = tcp_connections_count(tcp_c);
for (uint32_t i = 0; i < tcp_connections_count(tcp_c); ++i) {
for (uint32_t i = 0; i < size; ++i) {
const TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
if (tcp_con == nullptr) {

View File

@ -92,6 +92,9 @@ struct TCP_Server {
BS_List accepted_key_list;
};
static_assert(sizeof(TCP_Server) < 7 * 1024 * 1024,
"TCP_Server struct should not grow more; it's already 6MB");
const uint8_t *tcp_server_public_key(const TCP_Server *tcp_server)
{
return tcp_server->public_key;
@ -968,20 +971,22 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random
temp->ns = ns;
temp->rng = rng;
temp->socks_listening = (Socket *)mem_valloc(mem, num_sockets, sizeof(Socket));
Socket *socks_listening = (Socket *)mem_valloc(mem, num_sockets, sizeof(Socket));
if (temp->socks_listening == nullptr) {
if (socks_listening == nullptr) {
LOGGER_ERROR(logger, "socket allocation failed");
mem_delete(mem, temp);
return nullptr;
}
temp->socks_listening = socks_listening;
#ifdef TCP_SERVER_USE_EPOLL
temp->efd = epoll_create(8);
if (temp->efd == -1) {
LOGGER_ERROR(logger, "epoll initialisation failed");
mem_delete(mem, temp->socks_listening);
mem_delete(mem, socks_listening);
mem_delete(mem, temp);
return nullptr;
}

View File

@ -243,13 +243,15 @@ bool announce_store_data(Announcements *announce, const uint8_t *data_public_key
free(entry->data);
}
entry->data = (uint8_t *)malloc(length);
uint8_t *entry_data = (uint8_t *)malloc(length);
if (entry->data == nullptr) {
if (entry_data == nullptr) {
entry->data = nullptr; // TODO(iphydf): Is this necessary?
return false;
}
memcpy(entry->data, data, length);
memcpy(entry_data, data, length);
entry->data = entry_data;
}
entry->length = length;

View File

@ -6,13 +6,13 @@
#include <array>
#include <vector>
#include "crypto_core_test_util.hh"
#include "util.h"
namespace {
using HmacKey = std::array<uint8_t, CRYPTO_HMAC_KEY_SIZE>;
using Hmac = std::array<uint8_t, CRYPTO_HMAC_SIZE>;
using PublicKey = std::array<uint8_t, CRYPTO_PUBLIC_KEY_SIZE>;
using SecretKey = std::array<uint8_t, CRYPTO_SECRET_KEY_SIZE>;
using ExtPublicKey = std::array<uint8_t, EXT_PUBLIC_KEY_SIZE>;
using ExtSecretKey = std::array<uint8_t, EXT_SECRET_KEY_SIZE>;
@ -21,8 +21,7 @@ using Nonce = std::array<uint8_t, CRYPTO_NONCE_SIZE>;
TEST(CryptoCore, EncryptLargeData)
{
const Random *rng = system_random();
ASSERT_NE(rng, nullptr);
Test_Random rng;
Nonce nonce{};
PublicKey pk;
@ -71,8 +70,7 @@ TEST(CryptoCore, IncrementNonceNumber)
TEST(CryptoCore, Signatures)
{
const Random *rng = system_random();
ASSERT_NE(rng, nullptr);
Test_Random rng;
ExtPublicKey pk;
ExtSecretKey sk;
@ -96,8 +94,7 @@ TEST(CryptoCore, Signatures)
TEST(CryptoCore, Hmac)
{
const Random *rng = system_random();
ASSERT_NE(rng, nullptr);
Test_Random rng;
HmacKey sk;
new_hmac_key(rng, sk.data());

View File

@ -0,0 +1,39 @@
#include "crypto_core_test_util.hh"
#include <cstring>
#include <iomanip>
Random_Funcs const Random_Class::vtable = {
Method<crypto_random_bytes_cb, Random_Class>::invoke<&Random_Class::random_bytes>,
Method<crypto_random_uniform_cb, Random_Class>::invoke<&Random_Class::random_uniform>,
};
Random_Class::~Random_Class() = default;
void Test_Random::random_bytes(void *obj, uint8_t *bytes, size_t length)
{
std::generate(bytes, &bytes[length], std::ref(lcg));
}
uint32_t Test_Random::random_uniform(void *obj, uint32_t upper_bound)
{
std::uniform_int_distribution<uint32_t> distrib(0, upper_bound);
return distrib(lcg);
}
PublicKey random_pk(const Random *rng)
{
PublicKey pk;
random_bytes(rng, pk.data(), pk.size());
return pk;
}
std::ostream &operator<<(std::ostream &out, PublicKey const &pk)
{
out << '"';
for (uint8_t byte : pk) {
out << std::setw(2) << std::setfill('0') << std::hex << uint32_t(byte);
}
out << '"';
return out;
}

View File

@ -0,0 +1,88 @@
#ifndef C_TOXCORE_TOXCORE_CRYPTO_CORE_TEST_UTIL_H
#define C_TOXCORE_TOXCORE_CRYPTO_CORE_TEST_UTIL_H
#include <algorithm>
#include <array>
#include <iosfwd>
#include <random>
#include "crypto_core.h"
#include "test_util.hh"
struct Random_Class {
static Random_Funcs const vtable;
Random const self;
operator Random const *() const { return &self; }
Random_Class(Random_Class const &) = default;
Random_Class()
: self{&vtable, this}
{
}
virtual ~Random_Class();
virtual crypto_random_bytes_cb random_bytes = 0;
virtual crypto_random_uniform_cb random_uniform = 0;
};
/**
* A very simple, fast, and deterministic PRNG just for testing.
*
* We generally don't want to use system_random(), since it's a
* cryptographically secure PRNG and we don't need that in unit tests.
*/
class Test_Random : public Random_Class {
std::minstd_rand lcg;
void random_bytes(void *obj, uint8_t *bytes, size_t length) override;
uint32_t random_uniform(void *obj, uint32_t upper_bound) override;
};
struct PublicKey : private std::array<uint8_t, CRYPTO_PUBLIC_KEY_SIZE> {
using Base = std::array<uint8_t, CRYPTO_PUBLIC_KEY_SIZE>;
using Base::begin;
using Base::data;
using Base::end;
using Base::size;
using Base::operator[];
PublicKey() = default;
explicit PublicKey(uint8_t const (&arr)[CRYPTO_PUBLIC_KEY_SIZE])
: PublicKey(to_array(arr))
{
}
explicit PublicKey(std::array<uint8_t, CRYPTO_PUBLIC_KEY_SIZE> const &arr)
{
std::copy(arr.begin(), arr.end(), begin());
}
PublicKey(std::initializer_list<uint8_t> const &arr)
{
std::copy(arr.begin(), arr.end(), begin());
}
Base const &base() const { return *this; }
};
inline bool operator!=(PublicKey const &pk1, PublicKey const &pk2)
{
return pk1.base() != pk2.base();
}
inline bool operator==(PublicKey const &pk1, PublicKey const &pk2)
{
return pk1.base() == pk2.base();
}
inline bool operator==(PublicKey::Base const &pk1, PublicKey const &pk2)
{
return pk1 == pk2.base();
}
std::ostream &operator<<(std::ostream &out, PublicKey const &pk);
PublicKey random_pk(const Random *rng);
#endif // C_TOXCORE_TOXCORE_CRYPTO_CORE_TEST_UTIL_H

View File

@ -118,42 +118,6 @@ static Tox_Event_Conference_Connected *tox_events_add_conference_connected(Tox_E
return conference_connected;
}
const Tox_Event_Conference_Connected *tox_events_get_conference_connected(const Tox_Events *events, uint32_t index)
{
uint32_t conference_connected_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (conference_connected_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_CONFERENCE_CONNECTED) {
const Tox_Event_Conference_Connected *conference_connected = events->events[i].data.conference_connected;
if (conference_connected_index == index) {
return conference_connected;
}
++conference_connected_index;
}
}
return nullptr;
}
uint32_t tox_events_get_conference_connected_size(const Tox_Events *events)
{
uint32_t conference_connected_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_CONFERENCE_CONNECTED) {
++conference_connected_size;
}
}
return conference_connected_size;
}
bool tox_event_conference_connected_unpack(
Tox_Event_Conference_Connected **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -69,13 +69,14 @@ static bool tox_event_conference_invite_set_cookie(Tox_Event_Conference_Invite *
conference_invite->cookie_length = 0;
}
conference_invite->cookie = (uint8_t *)malloc(cookie_length);
uint8_t *cookie_copy = (uint8_t *)malloc(cookie_length);
if (conference_invite->cookie == nullptr) {
if (cookie_copy == nullptr) {
return false;
}
memcpy(conference_invite->cookie, cookie, cookie_length);
memcpy(cookie_copy, cookie, cookie_length);
conference_invite->cookie = cookie_copy;
conference_invite->cookie_length = cookie_length;
return true;
}
@ -179,42 +180,6 @@ static Tox_Event_Conference_Invite *tox_events_add_conference_invite(Tox_Events
return conference_invite;
}
const Tox_Event_Conference_Invite *tox_events_get_conference_invite(const Tox_Events *events, uint32_t index)
{
uint32_t conference_invite_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (conference_invite_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_CONFERENCE_INVITE) {
const Tox_Event_Conference_Invite *conference_invite = events->events[i].data.conference_invite;
if (conference_invite_index == index) {
return conference_invite;
}
++conference_invite_index;
}
}
return nullptr;
}
uint32_t tox_events_get_conference_invite_size(const Tox_Events *events)
{
uint32_t conference_invite_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_CONFERENCE_INVITE) {
++conference_invite_size;
}
}
return conference_invite_size;
}
bool tox_event_conference_invite_unpack(
Tox_Event_Conference_Invite **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -83,13 +83,14 @@ static bool tox_event_conference_message_set_message(Tox_Event_Conference_Messag
conference_message->message_length = 0;
}
conference_message->message = (uint8_t *)malloc(message_length);
uint8_t *message_copy = (uint8_t *)malloc(message_length);
if (conference_message->message == nullptr) {
if (message_copy == nullptr) {
return false;
}
memcpy(conference_message->message, message, message_length);
memcpy(message_copy, message, message_length);
conference_message->message = message_copy;
conference_message->message_length = message_length;
return true;
}
@ -195,42 +196,6 @@ static Tox_Event_Conference_Message *tox_events_add_conference_message(Tox_Event
return conference_message;
}
const Tox_Event_Conference_Message *tox_events_get_conference_message(const Tox_Events *events, uint32_t index)
{
uint32_t conference_message_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (conference_message_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_CONFERENCE_MESSAGE) {
const Tox_Event_Conference_Message *conference_message = events->events[i].data.conference_message;
if (conference_message_index == index) {
return conference_message;
}
++conference_message_index;
}
}
return nullptr;
}
uint32_t tox_events_get_conference_message_size(const Tox_Events *events)
{
uint32_t conference_message_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_CONFERENCE_MESSAGE) {
++conference_message_size;
}
}
return conference_message_size;
}
bool tox_event_conference_message_unpack(
Tox_Event_Conference_Message **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -118,42 +118,6 @@ static Tox_Event_Conference_Peer_List_Changed *tox_events_add_conference_peer_li
return conference_peer_list_changed;
}
const Tox_Event_Conference_Peer_List_Changed *tox_events_get_conference_peer_list_changed(const Tox_Events *events, uint32_t index)
{
uint32_t conference_peer_list_changed_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (conference_peer_list_changed_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_CONFERENCE_PEER_LIST_CHANGED) {
const Tox_Event_Conference_Peer_List_Changed *conference_peer_list_changed = events->events[i].data.conference_peer_list_changed;
if (conference_peer_list_changed_index == index) {
return conference_peer_list_changed;
}
++conference_peer_list_changed_index;
}
}
return nullptr;
}
uint32_t tox_events_get_conference_peer_list_changed_size(const Tox_Events *events)
{
uint32_t conference_peer_list_changed_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_CONFERENCE_PEER_LIST_CHANGED) {
++conference_peer_list_changed_size;
}
}
return conference_peer_list_changed_size;
}
bool tox_event_conference_peer_list_changed_unpack(
Tox_Event_Conference_Peer_List_Changed **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -68,13 +68,14 @@ static bool tox_event_conference_peer_name_set_name(Tox_Event_Conference_Peer_Na
conference_peer_name->name_length = 0;
}
conference_peer_name->name = (uint8_t *)malloc(name_length);
uint8_t *name_copy = (uint8_t *)malloc(name_length);
if (conference_peer_name->name == nullptr) {
if (name_copy == nullptr) {
return false;
}
memcpy(conference_peer_name->name, name, name_length);
memcpy(name_copy, name, name_length);
conference_peer_name->name = name_copy;
conference_peer_name->name_length = name_length;
return true;
}
@ -178,42 +179,6 @@ static Tox_Event_Conference_Peer_Name *tox_events_add_conference_peer_name(Tox_E
return conference_peer_name;
}
const Tox_Event_Conference_Peer_Name *tox_events_get_conference_peer_name(const Tox_Events *events, uint32_t index)
{
uint32_t conference_peer_name_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (conference_peer_name_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_CONFERENCE_PEER_NAME) {
const Tox_Event_Conference_Peer_Name *conference_peer_name = events->events[i].data.conference_peer_name;
if (conference_peer_name_index == index) {
return conference_peer_name;
}
++conference_peer_name_index;
}
}
return nullptr;
}
uint32_t tox_events_get_conference_peer_name_size(const Tox_Events *events)
{
uint32_t conference_peer_name_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_CONFERENCE_PEER_NAME) {
++conference_peer_name_size;
}
}
return conference_peer_name_size;
}
bool tox_event_conference_peer_name_unpack(
Tox_Event_Conference_Peer_Name **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -68,13 +68,14 @@ static bool tox_event_conference_title_set_title(Tox_Event_Conference_Title *con
conference_title->title_length = 0;
}
conference_title->title = (uint8_t *)malloc(title_length);
uint8_t *title_copy = (uint8_t *)malloc(title_length);
if (conference_title->title == nullptr) {
if (title_copy == nullptr) {
return false;
}
memcpy(conference_title->title, title, title_length);
memcpy(title_copy, title, title_length);
conference_title->title = title_copy;
conference_title->title_length = title_length;
return true;
}
@ -178,42 +179,6 @@ static Tox_Event_Conference_Title *tox_events_add_conference_title(Tox_Events *e
return conference_title;
}
const Tox_Event_Conference_Title *tox_events_get_conference_title(const Tox_Events *events, uint32_t index)
{
uint32_t conference_title_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (conference_title_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_CONFERENCE_TITLE) {
const Tox_Event_Conference_Title *conference_title = events->events[i].data.conference_title;
if (conference_title_index == index) {
return conference_title;
}
++conference_title_index;
}
}
return nullptr;
}
uint32_t tox_events_get_conference_title_size(const Tox_Events *events)
{
uint32_t conference_title_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_CONFERENCE_TITLE) {
++conference_title_size;
}
}
return conference_title_size;
}
bool tox_event_conference_title_unpack(
Tox_Event_Conference_Title **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -22,18 +22,21 @@ Tox_Events_State *tox_events_alloc(void *user_data)
return state;
}
state->events = (Tox_Events *)mem_alloc(state->mem, sizeof(Tox_Events));
Tox_Events *events = (Tox_Events *)mem_alloc(state->mem, sizeof(Tox_Events));
if (state->events == nullptr) {
if (events == nullptr) {
// It's still null => allocation failed.
state->events = nullptr;
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
} else {
*state->events = (Tox_Events) {
nullptr
};
state->events->mem = state->mem;
return state;
}
*events = (Tox_Events) {
nullptr
};
state->events = events;
state->events->mem = state->mem;
return state;
}

View File

@ -171,42 +171,6 @@ static Tox_Event_File_Chunk_Request *tox_events_add_file_chunk_request(Tox_Event
return file_chunk_request;
}
const Tox_Event_File_Chunk_Request *tox_events_get_file_chunk_request(const Tox_Events *events, uint32_t index)
{
uint32_t file_chunk_request_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (file_chunk_request_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_FILE_CHUNK_REQUEST) {
const Tox_Event_File_Chunk_Request *file_chunk_request = events->events[i].data.file_chunk_request;
if (file_chunk_request_index == index) {
return file_chunk_request;
}
++file_chunk_request_index;
}
}
return nullptr;
}
uint32_t tox_events_get_file_chunk_request_size(const Tox_Events *events)
{
uint32_t file_chunk_request_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_FILE_CHUNK_REQUEST) {
++file_chunk_request_size;
}
}
return file_chunk_request_size;
}
bool tox_event_file_chunk_request_unpack(
Tox_Event_File_Chunk_Request **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -96,13 +96,14 @@ static bool tox_event_file_recv_set_filename(Tox_Event_File_Recv *file_recv,
file_recv->filename_length = 0;
}
file_recv->filename = (uint8_t *)malloc(filename_length);
uint8_t *filename_copy = (uint8_t *)malloc(filename_length);
if (file_recv->filename == nullptr) {
if (filename_copy == nullptr) {
return false;
}
memcpy(file_recv->filename, filename, filename_length);
memcpy(filename_copy, filename, filename_length);
file_recv->filename = filename_copy;
file_recv->filename_length = filename_length;
return true;
}
@ -210,42 +211,6 @@ static Tox_Event_File_Recv *tox_events_add_file_recv(Tox_Events *events, const M
return file_recv;
}
const Tox_Event_File_Recv *tox_events_get_file_recv(const Tox_Events *events, uint32_t index)
{
uint32_t file_recv_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (file_recv_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_FILE_RECV) {
const Tox_Event_File_Recv *file_recv = events->events[i].data.file_recv;
if (file_recv_index == index) {
return file_recv;
}
++file_recv_index;
}
}
return nullptr;
}
uint32_t tox_events_get_file_recv_size(const Tox_Events *events)
{
uint32_t file_recv_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_FILE_RECV) {
++file_recv_size;
}
}
return file_recv_size;
}
bool tox_event_file_recv_unpack(
Tox_Event_File_Recv **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -82,13 +82,14 @@ static bool tox_event_file_recv_chunk_set_data(Tox_Event_File_Recv_Chunk *file_r
file_recv_chunk->data_length = 0;
}
file_recv_chunk->data = (uint8_t *)malloc(data_length);
uint8_t *data_copy = (uint8_t *)malloc(data_length);
if (file_recv_chunk->data == nullptr) {
if (data_copy == nullptr) {
return false;
}
memcpy(file_recv_chunk->data, data, data_length);
memcpy(data_copy, data, data_length);
file_recv_chunk->data = data_copy;
file_recv_chunk->data_length = data_length;
return true;
}
@ -194,42 +195,6 @@ static Tox_Event_File_Recv_Chunk *tox_events_add_file_recv_chunk(Tox_Events *eve
return file_recv_chunk;
}
const Tox_Event_File_Recv_Chunk *tox_events_get_file_recv_chunk(const Tox_Events *events, uint32_t index)
{
uint32_t file_recv_chunk_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (file_recv_chunk_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_FILE_RECV_CHUNK) {
const Tox_Event_File_Recv_Chunk *file_recv_chunk = events->events[i].data.file_recv_chunk;
if (file_recv_chunk_index == index) {
return file_recv_chunk;
}
++file_recv_chunk_index;
}
}
return nullptr;
}
uint32_t tox_events_get_file_recv_chunk_size(const Tox_Events *events)
{
uint32_t file_recv_chunk_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_FILE_RECV_CHUNK) {
++file_recv_chunk_size;
}
}
return file_recv_chunk_size;
}
bool tox_event_file_recv_chunk_unpack(
Tox_Event_File_Recv_Chunk **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -156,42 +156,6 @@ static Tox_Event_File_Recv_Control *tox_events_add_file_recv_control(Tox_Events
return file_recv_control;
}
const Tox_Event_File_Recv_Control *tox_events_get_file_recv_control(const Tox_Events *events, uint32_t index)
{
uint32_t file_recv_control_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (file_recv_control_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_FILE_RECV_CONTROL) {
const Tox_Event_File_Recv_Control *file_recv_control = events->events[i].data.file_recv_control;
if (file_recv_control_index == index) {
return file_recv_control;
}
++file_recv_control_index;
}
}
return nullptr;
}
uint32_t tox_events_get_file_recv_control_size(const Tox_Events *events)
{
uint32_t file_recv_control_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_FILE_RECV_CONTROL) {
++file_recv_control_size;
}
}
return file_recv_control_size;
}
bool tox_event_file_recv_control_unpack(
Tox_Event_File_Recv_Control **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -140,42 +140,6 @@ static Tox_Event_Friend_Connection_Status *tox_events_add_friend_connection_stat
return friend_connection_status;
}
const Tox_Event_Friend_Connection_Status *tox_events_get_friend_connection_status(const Tox_Events *events, uint32_t index)
{
uint32_t friend_connection_status_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (friend_connection_status_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_FRIEND_CONNECTION_STATUS) {
const Tox_Event_Friend_Connection_Status *friend_connection_status = events->events[i].data.friend_connection_status;
if (friend_connection_status_index == index) {
return friend_connection_status;
}
++friend_connection_status_index;
}
}
return nullptr;
}
uint32_t tox_events_get_friend_connection_status_size(const Tox_Events *events)
{
uint32_t friend_connection_status_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_FRIEND_CONNECTION_STATUS) {
++friend_connection_status_size;
}
}
return friend_connection_status_size;
}
bool tox_event_friend_connection_status_unpack(
Tox_Event_Friend_Connection_Status **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -54,13 +54,14 @@ static bool tox_event_friend_lossless_packet_set_data(Tox_Event_Friend_Lossless_
friend_lossless_packet->data_length = 0;
}
friend_lossless_packet->data = (uint8_t *)malloc(data_length);
uint8_t *data_copy = (uint8_t *)malloc(data_length);
if (friend_lossless_packet->data == nullptr) {
if (data_copy == nullptr) {
return false;
}
memcpy(friend_lossless_packet->data, data, data_length);
memcpy(data_copy, data, data_length);
friend_lossless_packet->data = data_copy;
friend_lossless_packet->data_length = data_length;
return true;
}
@ -162,42 +163,6 @@ static Tox_Event_Friend_Lossless_Packet *tox_events_add_friend_lossless_packet(T
return friend_lossless_packet;
}
const Tox_Event_Friend_Lossless_Packet *tox_events_get_friend_lossless_packet(const Tox_Events *events, uint32_t index)
{
uint32_t friend_lossless_packet_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (friend_lossless_packet_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_FRIEND_LOSSLESS_PACKET) {
const Tox_Event_Friend_Lossless_Packet *friend_lossless_packet = events->events[i].data.friend_lossless_packet;
if (friend_lossless_packet_index == index) {
return friend_lossless_packet;
}
++friend_lossless_packet_index;
}
}
return nullptr;
}
uint32_t tox_events_get_friend_lossless_packet_size(const Tox_Events *events)
{
uint32_t friend_lossless_packet_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_FRIEND_LOSSLESS_PACKET) {
++friend_lossless_packet_size;
}
}
return friend_lossless_packet_size;
}
bool tox_event_friend_lossless_packet_unpack(
Tox_Event_Friend_Lossless_Packet **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -54,13 +54,14 @@ static bool tox_event_friend_lossy_packet_set_data(Tox_Event_Friend_Lossy_Packet
friend_lossy_packet->data_length = 0;
}
friend_lossy_packet->data = (uint8_t *)malloc(data_length);
uint8_t *data_copy = (uint8_t *)malloc(data_length);
if (friend_lossy_packet->data == nullptr) {
if (data_copy == nullptr) {
return false;
}
memcpy(friend_lossy_packet->data, data, data_length);
memcpy(data_copy, data, data_length);
friend_lossy_packet->data = data_copy;
friend_lossy_packet->data_length = data_length;
return true;
}
@ -162,42 +163,6 @@ static Tox_Event_Friend_Lossy_Packet *tox_events_add_friend_lossy_packet(Tox_Eve
return friend_lossy_packet;
}
const Tox_Event_Friend_Lossy_Packet *tox_events_get_friend_lossy_packet(const Tox_Events *events, uint32_t index)
{
uint32_t friend_lossy_packet_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (friend_lossy_packet_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_FRIEND_LOSSY_PACKET) {
const Tox_Event_Friend_Lossy_Packet *friend_lossy_packet = events->events[i].data.friend_lossy_packet;
if (friend_lossy_packet_index == index) {
return friend_lossy_packet;
}
++friend_lossy_packet_index;
}
}
return nullptr;
}
uint32_t tox_events_get_friend_lossy_packet_size(const Tox_Events *events)
{
uint32_t friend_lossy_packet_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_FRIEND_LOSSY_PACKET) {
++friend_lossy_packet_size;
}
}
return friend_lossy_packet_size;
}
bool tox_event_friend_lossy_packet_unpack(
Tox_Event_Friend_Lossy_Packet **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -69,13 +69,14 @@ static bool tox_event_friend_message_set_message(Tox_Event_Friend_Message *frien
friend_message->message_length = 0;
}
friend_message->message = (uint8_t *)malloc(message_length);
uint8_t *message_copy = (uint8_t *)malloc(message_length);
if (friend_message->message == nullptr) {
if (message_copy == nullptr) {
return false;
}
memcpy(friend_message->message, message, message_length);
memcpy(message_copy, message, message_length);
friend_message->message = message_copy;
friend_message->message_length = message_length;
return true;
}
@ -179,42 +180,6 @@ static Tox_Event_Friend_Message *tox_events_add_friend_message(Tox_Events *event
return friend_message;
}
const Tox_Event_Friend_Message *tox_events_get_friend_message(const Tox_Events *events, uint32_t index)
{
uint32_t friend_message_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (friend_message_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_FRIEND_MESSAGE) {
const Tox_Event_Friend_Message *friend_message = events->events[i].data.friend_message;
if (friend_message_index == index) {
return friend_message;
}
++friend_message_index;
}
}
return nullptr;
}
uint32_t tox_events_get_friend_message_size(const Tox_Events *events)
{
uint32_t friend_message_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_FRIEND_MESSAGE) {
++friend_message_size;
}
}
return friend_message_size;
}
bool tox_event_friend_message_unpack(
Tox_Event_Friend_Message **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -54,13 +54,14 @@ static bool tox_event_friend_name_set_name(Tox_Event_Friend_Name *friend_name,
friend_name->name_length = 0;
}
friend_name->name = (uint8_t *)malloc(name_length);
uint8_t *name_copy = (uint8_t *)malloc(name_length);
if (friend_name->name == nullptr) {
if (name_copy == nullptr) {
return false;
}
memcpy(friend_name->name, name, name_length);
memcpy(name_copy, name, name_length);
friend_name->name = name_copy;
friend_name->name_length = name_length;
return true;
}
@ -162,42 +163,6 @@ static Tox_Event_Friend_Name *tox_events_add_friend_name(Tox_Events *events, con
return friend_name;
}
const Tox_Event_Friend_Name *tox_events_get_friend_name(const Tox_Events *events, uint32_t index)
{
uint32_t friend_name_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (friend_name_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_FRIEND_NAME) {
const Tox_Event_Friend_Name *friend_name = events->events[i].data.friend_name;
if (friend_name_index == index) {
return friend_name;
}
++friend_name_index;
}
}
return nullptr;
}
uint32_t tox_events_get_friend_name_size(const Tox_Events *events)
{
uint32_t friend_name_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_FRIEND_NAME) {
++friend_name_size;
}
}
return friend_name_size;
}
bool tox_event_friend_name_unpack(
Tox_Event_Friend_Name **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -139,42 +139,6 @@ static Tox_Event_Friend_Read_Receipt *tox_events_add_friend_read_receipt(Tox_Eve
return friend_read_receipt;
}
const Tox_Event_Friend_Read_Receipt *tox_events_get_friend_read_receipt(const Tox_Events *events, uint32_t index)
{
uint32_t friend_read_receipt_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (friend_read_receipt_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_FRIEND_READ_RECEIPT) {
const Tox_Event_Friend_Read_Receipt *friend_read_receipt = events->events[i].data.friend_read_receipt;
if (friend_read_receipt_index == index) {
return friend_read_receipt;
}
++friend_read_receipt_index;
}
}
return nullptr;
}
uint32_t tox_events_get_friend_read_receipt_size(const Tox_Events *events)
{
uint32_t friend_read_receipt_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_FRIEND_READ_RECEIPT) {
++friend_read_receipt_size;
}
}
return friend_read_receipt_size;
}
bool tox_event_friend_read_receipt_unpack(
Tox_Event_Friend_Read_Receipt **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -55,13 +55,14 @@ static bool tox_event_friend_request_set_message(Tox_Event_Friend_Request *frien
friend_request->message_length = 0;
}
friend_request->message = (uint8_t *)mem_balloc(mem, message_length * sizeof(uint8_t));
uint8_t *message_copy = (uint8_t *)mem_balloc(mem, message_length);
if (friend_request->message == nullptr) {
if (message_copy == nullptr) {
return false;
}
memcpy(friend_request->message, message, message_length * sizeof(uint8_t));
memcpy(message_copy, message, message_length);
friend_request->message = message_copy;
friend_request->message_length = message_length;
return true;
}
@ -157,44 +158,6 @@ static Tox_Event_Friend_Request *tox_events_add_friend_request(Tox_Events *event
return friend_request;
}
const Tox_Event_Friend_Request *tox_events_get_friend_request(
const Tox_Events *events, uint32_t index)
{
uint32_t friend_request_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (friend_request_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_FRIEND_REQUEST) {
const Tox_Event_Friend_Request *friend_request = events->events[i].data.friend_request;
if (friend_request_index == index) {
return friend_request;
}
++friend_request_index;
}
}
return nullptr;
}
uint32_t tox_events_get_friend_request_size(
const Tox_Events *events)
{
uint32_t friend_request_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_FRIEND_REQUEST) {
++friend_request_size;
}
}
return friend_request_size;
}
bool tox_event_friend_request_unpack(
Tox_Event_Friend_Request **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -140,42 +140,6 @@ static Tox_Event_Friend_Status *tox_events_add_friend_status(Tox_Events *events,
return friend_status;
}
const Tox_Event_Friend_Status *tox_events_get_friend_status(const Tox_Events *events, uint32_t index)
{
uint32_t friend_status_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (friend_status_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_FRIEND_STATUS) {
const Tox_Event_Friend_Status *friend_status = events->events[i].data.friend_status;
if (friend_status_index == index) {
return friend_status;
}
++friend_status_index;
}
}
return nullptr;
}
uint32_t tox_events_get_friend_status_size(const Tox_Events *events)
{
uint32_t friend_status_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_FRIEND_STATUS) {
++friend_status_size;
}
}
return friend_status_size;
}
bool tox_event_friend_status_unpack(
Tox_Event_Friend_Status **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -54,13 +54,14 @@ static bool tox_event_friend_status_message_set_message(Tox_Event_Friend_Status_
friend_status_message->message_length = 0;
}
friend_status_message->message = (uint8_t *)malloc(message_length);
uint8_t *message_copy = (uint8_t *)malloc(message_length);
if (friend_status_message->message == nullptr) {
if (message_copy == nullptr) {
return false;
}
memcpy(friend_status_message->message, message, message_length);
memcpy(message_copy, message, message_length);
friend_status_message->message = message_copy;
friend_status_message->message_length = message_length;
return true;
}
@ -162,42 +163,6 @@ static Tox_Event_Friend_Status_Message *tox_events_add_friend_status_message(Tox
return friend_status_message;
}
const Tox_Event_Friend_Status_Message *tox_events_get_friend_status_message(const Tox_Events *events, uint32_t index)
{
uint32_t friend_status_message_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (friend_status_message_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_FRIEND_STATUS_MESSAGE) {
const Tox_Event_Friend_Status_Message *friend_status_message = events->events[i].data.friend_status_message;
if (friend_status_message_index == index) {
return friend_status_message;
}
++friend_status_message_index;
}
}
return nullptr;
}
uint32_t tox_events_get_friend_status_message_size(const Tox_Events *events)
{
uint32_t friend_status_message_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_FRIEND_STATUS_MESSAGE) {
++friend_status_message_size;
}
}
return friend_status_message_size;
}
bool tox_event_friend_status_message_unpack(
Tox_Event_Friend_Status_Message **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -139,42 +139,6 @@ static Tox_Event_Friend_Typing *tox_events_add_friend_typing(Tox_Events *events,
return friend_typing;
}
const Tox_Event_Friend_Typing *tox_events_get_friend_typing(const Tox_Events *events, uint32_t index)
{
uint32_t friend_typing_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (friend_typing_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_FRIEND_TYPING) {
const Tox_Event_Friend_Typing *friend_typing = events->events[i].data.friend_typing;
if (friend_typing_index == index) {
return friend_typing;
}
++friend_typing_index;
}
}
return nullptr;
}
uint32_t tox_events_get_friend_typing_size(const Tox_Events *events)
{
uint32_t friend_typing_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_FRIEND_TYPING) {
++friend_typing_size;
}
}
return friend_typing_size;
}
bool tox_event_friend_typing_unpack(
Tox_Event_Friend_Typing **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -68,13 +68,14 @@ static bool tox_event_group_custom_packet_set_data(Tox_Event_Group_Custom_Packet
group_custom_packet->data_length = 0;
}
group_custom_packet->data = (uint8_t *)malloc(data_length);
uint8_t *data_copy = (uint8_t *)malloc(data_length);
if (group_custom_packet->data == nullptr) {
if (data_copy == nullptr) {
return false;
}
memcpy(group_custom_packet->data, data, data_length);
memcpy(data_copy, data, data_length);
group_custom_packet->data = data_copy;
group_custom_packet->data_length = data_length;
return true;
}
@ -178,42 +179,6 @@ static Tox_Event_Group_Custom_Packet *tox_events_add_group_custom_packet(Tox_Eve
return group_custom_packet;
}
const Tox_Event_Group_Custom_Packet *tox_events_get_group_custom_packet(const Tox_Events *events, uint32_t index)
{
uint32_t group_custom_packet_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (group_custom_packet_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_GROUP_CUSTOM_PACKET) {
const Tox_Event_Group_Custom_Packet *group_custom_packet = events->events[i].data.group_custom_packet;
if (group_custom_packet_index == index) {
return group_custom_packet;
}
++group_custom_packet_index;
}
}
return nullptr;
}
uint32_t tox_events_get_group_custom_packet_size(const Tox_Events *events)
{
uint32_t group_custom_packet_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_GROUP_CUSTOM_PACKET) {
++group_custom_packet_size;
}
}
return group_custom_packet_size;
}
bool tox_event_group_custom_packet_unpack(
Tox_Event_Group_Custom_Packet **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -68,13 +68,14 @@ static bool tox_event_group_custom_private_packet_set_data(Tox_Event_Group_Custo
group_custom_private_packet->data_length = 0;
}
group_custom_private_packet->data = (uint8_t *)malloc(data_length);
uint8_t *data_copy = (uint8_t *)malloc(data_length);
if (group_custom_private_packet->data == nullptr) {
if (data_copy == nullptr) {
return false;
}
memcpy(group_custom_private_packet->data, data, data_length);
memcpy(data_copy, data, data_length);
group_custom_private_packet->data = data_copy;
group_custom_private_packet->data_length = data_length;
return true;
}
@ -178,42 +179,6 @@ static Tox_Event_Group_Custom_Private_Packet *tox_events_add_group_custom_privat
return group_custom_private_packet;
}
const Tox_Event_Group_Custom_Private_Packet *tox_events_get_group_custom_private_packet(const Tox_Events *events, uint32_t index)
{
uint32_t group_custom_private_packet_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (group_custom_private_packet_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_GROUP_CUSTOM_PRIVATE_PACKET) {
const Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet = events->events[i].data.group_custom_private_packet;
if (group_custom_private_packet_index == index) {
return group_custom_private_packet;
}
++group_custom_private_packet_index;
}
}
return nullptr;
}
uint32_t tox_events_get_group_custom_private_packet_size(const Tox_Events *events)
{
uint32_t group_custom_private_packet_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_GROUP_CUSTOM_PRIVATE_PACKET) {
++group_custom_private_packet_size;
}
}
return group_custom_private_packet_size;
}
bool tox_event_group_custom_private_packet_unpack(
Tox_Event_Group_Custom_Private_Packet **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -56,13 +56,14 @@ static bool tox_event_group_invite_set_invite_data(Tox_Event_Group_Invite *group
group_invite->invite_data_length = 0;
}
group_invite->invite_data = (uint8_t *)malloc(invite_data_length);
uint8_t *invite_data_copy = (uint8_t *)malloc(invite_data_length);
if (group_invite->invite_data == nullptr) {
if (invite_data_copy == nullptr) {
return false;
}
memcpy(group_invite->invite_data, invite_data, invite_data_length);
memcpy(invite_data_copy, invite_data, invite_data_length);
group_invite->invite_data = invite_data_copy;
group_invite->invite_data_length = invite_data_length;
return true;
}
@ -89,13 +90,14 @@ static bool tox_event_group_invite_set_group_name(Tox_Event_Group_Invite *group_
group_invite->group_name_length = 0;
}
group_invite->group_name = (uint8_t *)malloc(group_name_length);
uint8_t *group_name_copy = (uint8_t *)malloc(group_name_length);
if (group_invite->group_name == nullptr) {
if (group_name_copy == nullptr) {
return false;
}
memcpy(group_invite->group_name, group_name, group_name_length);
memcpy(group_name_copy, group_name, group_name_length);
group_invite->group_name = group_name_copy;
group_invite->group_name_length = group_name_length;
return true;
}
@ -200,42 +202,6 @@ static Tox_Event_Group_Invite *tox_events_add_group_invite(Tox_Events *events, c
return group_invite;
}
const Tox_Event_Group_Invite *tox_events_get_group_invite(const Tox_Events *events, uint32_t index)
{
uint32_t group_invite_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (group_invite_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_GROUP_INVITE) {
const Tox_Event_Group_Invite *group_invite = events->events[i].data.group_invite;
if (group_invite_index == index) {
return group_invite;
}
++group_invite_index;
}
}
return nullptr;
}
uint32_t tox_events_get_group_invite_size(const Tox_Events *events)
{
uint32_t group_invite_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_GROUP_INVITE) {
++group_invite_size;
}
}
return group_invite_size;
}
bool tox_event_group_invite_unpack(
Tox_Event_Group_Invite **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -140,42 +140,6 @@ static Tox_Event_Group_Join_Fail *tox_events_add_group_join_fail(Tox_Events *eve
return group_join_fail;
}
const Tox_Event_Group_Join_Fail *tox_events_get_group_join_fail(const Tox_Events *events, uint32_t index)
{
uint32_t group_join_fail_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (group_join_fail_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_GROUP_JOIN_FAIL) {
const Tox_Event_Group_Join_Fail *group_join_fail = events->events[i].data.group_join_fail;
if (group_join_fail_index == index) {
return group_join_fail;
}
++group_join_fail_index;
}
}
return nullptr;
}
uint32_t tox_events_get_group_join_fail_size(const Tox_Events *events)
{
uint32_t group_join_fail_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_GROUP_JOIN_FAIL) {
++group_join_fail_size;
}
}
return group_join_fail_size;
}
bool tox_event_group_join_fail_unpack(
Tox_Event_Group_Join_Fail **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -84,13 +84,14 @@ static bool tox_event_group_message_set_message(Tox_Event_Group_Message *group_m
group_message->message_length = 0;
}
group_message->message = (uint8_t *)malloc(message_length);
uint8_t *message_copy = (uint8_t *)malloc(message_length);
if (group_message->message == nullptr) {
if (message_copy == nullptr) {
return false;
}
memcpy(group_message->message, message, message_length);
memcpy(message_copy, message, message_length);
group_message->message = message_copy;
group_message->message_length = message_length;
return true;
}
@ -211,42 +212,6 @@ static Tox_Event_Group_Message *tox_events_add_group_message(Tox_Events *events,
return group_message;
}
const Tox_Event_Group_Message *tox_events_get_group_message(const Tox_Events *events, uint32_t index)
{
uint32_t group_message_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (group_message_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_GROUP_MESSAGE) {
const Tox_Event_Group_Message *group_message = events->events[i].data.group_message;
if (group_message_index == index) {
return group_message;
}
++group_message_index;
}
}
return nullptr;
}
uint32_t tox_events_get_group_message_size(const Tox_Events *events)
{
uint32_t group_message_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_GROUP_MESSAGE) {
++group_message_size;
}
}
return group_message_size;
}
bool tox_event_group_message_unpack(
Tox_Event_Group_Message **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -172,42 +172,6 @@ static Tox_Event_Group_Moderation *tox_events_add_group_moderation(Tox_Events *e
return group_moderation;
}
const Tox_Event_Group_Moderation *tox_events_get_group_moderation(const Tox_Events *events, uint32_t index)
{
uint32_t group_moderation_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (group_moderation_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_GROUP_MODERATION) {
const Tox_Event_Group_Moderation *group_moderation = events->events[i].data.group_moderation;
if (group_moderation_index == index) {
return group_moderation;
}
++group_moderation_index;
}
}
return nullptr;
}
uint32_t tox_events_get_group_moderation_size(const Tox_Events *events)
{
uint32_t group_moderation_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_GROUP_MODERATION) {
++group_moderation_size;
}
}
return group_moderation_size;
}
bool tox_event_group_moderation_unpack(
Tox_Event_Group_Moderation **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -54,13 +54,14 @@ static bool tox_event_group_password_set_password(Tox_Event_Group_Password *grou
group_password->password_length = 0;
}
group_password->password = (uint8_t *)malloc(password_length);
uint8_t *password_copy = (uint8_t *)malloc(password_length);
if (group_password->password == nullptr) {
if (password_copy == nullptr) {
return false;
}
memcpy(group_password->password, password, password_length);
memcpy(password_copy, password, password_length);
group_password->password = password_copy;
group_password->password_length = password_length;
return true;
}
@ -162,42 +163,6 @@ static Tox_Event_Group_Password *tox_events_add_group_password(Tox_Events *event
return group_password;
}
const Tox_Event_Group_Password *tox_events_get_group_password(const Tox_Events *events, uint32_t index)
{
uint32_t group_password_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (group_password_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_GROUP_PASSWORD) {
const Tox_Event_Group_Password *group_password = events->events[i].data.group_password;
if (group_password_index == index) {
return group_password;
}
++group_password_index;
}
}
return nullptr;
}
uint32_t tox_events_get_group_password_size(const Tox_Events *events)
{
uint32_t group_password_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_GROUP_PASSWORD) {
++group_password_size;
}
}
return group_password_size;
}
bool tox_event_group_password_unpack(
Tox_Event_Group_Password **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -85,13 +85,14 @@ static bool tox_event_group_peer_exit_set_name(Tox_Event_Group_Peer_Exit *group_
group_peer_exit->name_length = 0;
}
group_peer_exit->name = (uint8_t *)malloc(name_length);
uint8_t *name_copy = (uint8_t *)malloc(name_length);
if (group_peer_exit->name == nullptr) {
if (name_copy == nullptr) {
return false;
}
memcpy(group_peer_exit->name, name, name_length);
memcpy(name_copy, name, name_length);
group_peer_exit->name = name_copy;
group_peer_exit->name_length = name_length;
return true;
}
@ -118,13 +119,14 @@ static bool tox_event_group_peer_exit_set_part_message(Tox_Event_Group_Peer_Exit
group_peer_exit->part_message_length = 0;
}
group_peer_exit->part_message = (uint8_t *)malloc(part_message_length);
uint8_t *part_message_copy = (uint8_t *)malloc(part_message_length);
if (group_peer_exit->part_message == nullptr) {
if (part_message_copy == nullptr) {
return false;
}
memcpy(group_peer_exit->part_message, part_message, part_message_length);
memcpy(part_message_copy, part_message, part_message_length);
group_peer_exit->part_message = part_message_copy;
group_peer_exit->part_message_length = part_message_length;
return true;
}
@ -233,42 +235,6 @@ static Tox_Event_Group_Peer_Exit *tox_events_add_group_peer_exit(Tox_Events *eve
return group_peer_exit;
}
const Tox_Event_Group_Peer_Exit *tox_events_get_group_peer_exit(const Tox_Events *events, uint32_t index)
{
uint32_t group_peer_exit_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (group_peer_exit_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_GROUP_PEER_EXIT) {
const Tox_Event_Group_Peer_Exit *group_peer_exit = events->events[i].data.group_peer_exit;
if (group_peer_exit_index == index) {
return group_peer_exit;
}
++group_peer_exit_index;
}
}
return nullptr;
}
uint32_t tox_events_get_group_peer_exit_size(const Tox_Events *events)
{
uint32_t group_peer_exit_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_GROUP_PEER_EXIT) {
++group_peer_exit_size;
}
}
return group_peer_exit_size;
}
bool tox_event_group_peer_exit_unpack(
Tox_Event_Group_Peer_Exit **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -139,42 +139,6 @@ static Tox_Event_Group_Peer_Join *tox_events_add_group_peer_join(Tox_Events *eve
return group_peer_join;
}
const Tox_Event_Group_Peer_Join *tox_events_get_group_peer_join(const Tox_Events *events, uint32_t index)
{
uint32_t group_peer_join_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (group_peer_join_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_GROUP_PEER_JOIN) {
const Tox_Event_Group_Peer_Join *group_peer_join = events->events[i].data.group_peer_join;
if (group_peer_join_index == index) {
return group_peer_join;
}
++group_peer_join_index;
}
}
return nullptr;
}
uint32_t tox_events_get_group_peer_join_size(const Tox_Events *events)
{
uint32_t group_peer_join_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_GROUP_PEER_JOIN) {
++group_peer_join_size;
}
}
return group_peer_join_size;
}
bool tox_event_group_peer_join_unpack(
Tox_Event_Group_Peer_Join **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -139,42 +139,6 @@ static Tox_Event_Group_Peer_Limit *tox_events_add_group_peer_limit(Tox_Events *e
return group_peer_limit;
}
const Tox_Event_Group_Peer_Limit *tox_events_get_group_peer_limit(const Tox_Events *events, uint32_t index)
{
uint32_t group_peer_limit_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (group_peer_limit_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_GROUP_PEER_LIMIT) {
const Tox_Event_Group_Peer_Limit *group_peer_limit = events->events[i].data.group_peer_limit;
if (group_peer_limit_index == index) {
return group_peer_limit;
}
++group_peer_limit_index;
}
}
return nullptr;
}
uint32_t tox_events_get_group_peer_limit_size(const Tox_Events *events)
{
uint32_t group_peer_limit_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_GROUP_PEER_LIMIT) {
++group_peer_limit_size;
}
}
return group_peer_limit_size;
}
bool tox_event_group_peer_limit_unpack(
Tox_Event_Group_Peer_Limit **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -68,13 +68,14 @@ static bool tox_event_group_peer_name_set_name(Tox_Event_Group_Peer_Name *group_
group_peer_name->name_length = 0;
}
group_peer_name->name = (uint8_t *)malloc(name_length);
uint8_t *name_copy = (uint8_t *)malloc(name_length);
if (group_peer_name->name == nullptr) {
if (name_copy == nullptr) {
return false;
}
memcpy(group_peer_name->name, name, name_length);
memcpy(name_copy, name, name_length);
group_peer_name->name = name_copy;
group_peer_name->name_length = name_length;
return true;
}
@ -178,42 +179,6 @@ static Tox_Event_Group_Peer_Name *tox_events_add_group_peer_name(Tox_Events *eve
return group_peer_name;
}
const Tox_Event_Group_Peer_Name *tox_events_get_group_peer_name(const Tox_Events *events, uint32_t index)
{
uint32_t group_peer_name_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (group_peer_name_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_GROUP_PEER_NAME) {
const Tox_Event_Group_Peer_Name *group_peer_name = events->events[i].data.group_peer_name;
if (group_peer_name_index == index) {
return group_peer_name;
}
++group_peer_name_index;
}
}
return nullptr;
}
uint32_t tox_events_get_group_peer_name_size(const Tox_Events *events)
{
uint32_t group_peer_name_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_GROUP_PEER_NAME) {
++group_peer_name_size;
}
}
return group_peer_name_size;
}
bool tox_event_group_peer_name_unpack(
Tox_Event_Group_Peer_Name **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -156,42 +156,6 @@ static Tox_Event_Group_Peer_Status *tox_events_add_group_peer_status(Tox_Events
return group_peer_status;
}
const Tox_Event_Group_Peer_Status *tox_events_get_group_peer_status(const Tox_Events *events, uint32_t index)
{
uint32_t group_peer_status_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (group_peer_status_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_GROUP_PEER_STATUS) {
const Tox_Event_Group_Peer_Status *group_peer_status = events->events[i].data.group_peer_status;
if (group_peer_status_index == index) {
return group_peer_status;
}
++group_peer_status_index;
}
}
return nullptr;
}
uint32_t tox_events_get_group_peer_status_size(const Tox_Events *events)
{
uint32_t group_peer_status_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_GROUP_PEER_STATUS) {
++group_peer_status_size;
}
}
return group_peer_status_size;
}
bool tox_event_group_peer_status_unpack(
Tox_Event_Group_Peer_Status **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -140,42 +140,6 @@ static Tox_Event_Group_Privacy_State *tox_events_add_group_privacy_state(Tox_Eve
return group_privacy_state;
}
const Tox_Event_Group_Privacy_State *tox_events_get_group_privacy_state(const Tox_Events *events, uint32_t index)
{
uint32_t group_privacy_state_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (group_privacy_state_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_GROUP_PRIVACY_STATE) {
const Tox_Event_Group_Privacy_State *group_privacy_state = events->events[i].data.group_privacy_state;
if (group_privacy_state_index == index) {
return group_privacy_state;
}
++group_privacy_state_index;
}
}
return nullptr;
}
uint32_t tox_events_get_group_privacy_state_size(const Tox_Events *events)
{
uint32_t group_privacy_state_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_GROUP_PRIVACY_STATE) {
++group_privacy_state_size;
}
}
return group_privacy_state_size;
}
bool tox_event_group_privacy_state_unpack(
Tox_Event_Group_Privacy_State **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -83,13 +83,14 @@ static bool tox_event_group_private_message_set_message(Tox_Event_Group_Private_
group_private_message->message_length = 0;
}
group_private_message->message = (uint8_t *)malloc(message_length);
uint8_t *message_copy = (uint8_t *)malloc(message_length);
if (group_private_message->message == nullptr) {
if (message_copy == nullptr) {
return false;
}
memcpy(group_private_message->message, message, message_length);
memcpy(message_copy, message, message_length);
group_private_message->message = message_copy;
group_private_message->message_length = message_length;
return true;
}
@ -195,42 +196,6 @@ static Tox_Event_Group_Private_Message *tox_events_add_group_private_message(Tox
return group_private_message;
}
const Tox_Event_Group_Private_Message *tox_events_get_group_private_message(const Tox_Events *events, uint32_t index)
{
uint32_t group_private_message_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (group_private_message_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_GROUP_PRIVATE_MESSAGE) {
const Tox_Event_Group_Private_Message *group_private_message = events->events[i].data.group_private_message;
if (group_private_message_index == index) {
return group_private_message;
}
++group_private_message_index;
}
}
return nullptr;
}
uint32_t tox_events_get_group_private_message_size(const Tox_Events *events)
{
uint32_t group_private_message_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_GROUP_PRIVATE_MESSAGE) {
++group_private_message_size;
}
}
return group_private_message_size;
}
bool tox_event_group_private_message_unpack(
Tox_Event_Group_Private_Message **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -118,42 +118,6 @@ static Tox_Event_Group_Self_Join *tox_events_add_group_self_join(Tox_Events *eve
return group_self_join;
}
const Tox_Event_Group_Self_Join *tox_events_get_group_self_join(const Tox_Events *events, uint32_t index)
{
uint32_t group_self_join_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (group_self_join_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_GROUP_SELF_JOIN) {
const Tox_Event_Group_Self_Join *group_self_join = events->events[i].data.group_self_join;
if (group_self_join_index == index) {
return group_self_join;
}
++group_self_join_index;
}
}
return nullptr;
}
uint32_t tox_events_get_group_self_join_size(const Tox_Events *events)
{
uint32_t group_self_join_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_GROUP_SELF_JOIN) {
++group_self_join_size;
}
}
return group_self_join_size;
}
bool tox_event_group_self_join_unpack(
Tox_Event_Group_Self_Join **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -68,13 +68,14 @@ static bool tox_event_group_topic_set_topic(Tox_Event_Group_Topic *group_topic,
group_topic->topic_length = 0;
}
group_topic->topic = (uint8_t *)malloc(topic_length);
uint8_t *topic_copy = (uint8_t *)malloc(topic_length);
if (group_topic->topic == nullptr) {
if (topic_copy == nullptr) {
return false;
}
memcpy(group_topic->topic, topic, topic_length);
memcpy(topic_copy, topic, topic_length);
group_topic->topic = topic_copy;
group_topic->topic_length = topic_length;
return true;
}
@ -178,42 +179,6 @@ static Tox_Event_Group_Topic *tox_events_add_group_topic(Tox_Events *events, con
return group_topic;
}
const Tox_Event_Group_Topic *tox_events_get_group_topic(const Tox_Events *events, uint32_t index)
{
uint32_t group_topic_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (group_topic_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_GROUP_TOPIC) {
const Tox_Event_Group_Topic *group_topic = events->events[i].data.group_topic;
if (group_topic_index == index) {
return group_topic;
}
++group_topic_index;
}
}
return nullptr;
}
uint32_t tox_events_get_group_topic_size(const Tox_Events *events)
{
uint32_t group_topic_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_GROUP_TOPIC) {
++group_topic_size;
}
}
return group_topic_size;
}
bool tox_event_group_topic_unpack(
Tox_Event_Group_Topic **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -140,42 +140,6 @@ static Tox_Event_Group_Topic_Lock *tox_events_add_group_topic_lock(Tox_Events *e
return group_topic_lock;
}
const Tox_Event_Group_Topic_Lock *tox_events_get_group_topic_lock(const Tox_Events *events, uint32_t index)
{
uint32_t group_topic_lock_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (group_topic_lock_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_GROUP_TOPIC_LOCK) {
const Tox_Event_Group_Topic_Lock *group_topic_lock = events->events[i].data.group_topic_lock;
if (group_topic_lock_index == index) {
return group_topic_lock;
}
++group_topic_lock_index;
}
}
return nullptr;
}
uint32_t tox_events_get_group_topic_lock_size(const Tox_Events *events)
{
uint32_t group_topic_lock_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_GROUP_TOPIC_LOCK) {
++group_topic_lock_size;
}
}
return group_topic_lock_size;
}
bool tox_event_group_topic_lock_unpack(
Tox_Event_Group_Topic_Lock **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -140,42 +140,6 @@ static Tox_Event_Group_Voice_State *tox_events_add_group_voice_state(Tox_Events
return group_voice_state;
}
const Tox_Event_Group_Voice_State *tox_events_get_group_voice_state(const Tox_Events *events, uint32_t index)
{
uint32_t group_voice_state_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (group_voice_state_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_GROUP_VOICE_STATE) {
const Tox_Event_Group_Voice_State *group_voice_state = events->events[i].data.group_voice_state;
if (group_voice_state_index == index) {
return group_voice_state;
}
++group_voice_state_index;
}
}
return nullptr;
}
uint32_t tox_events_get_group_voice_state_size(const Tox_Events *events)
{
uint32_t group_voice_state_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_GROUP_VOICE_STATE) {
++group_voice_state_size;
}
}
return group_voice_state_size;
}
bool tox_event_group_voice_state_unpack(
Tox_Event_Group_Voice_State **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -119,42 +119,6 @@ static Tox_Event_Self_Connection_Status *tox_events_add_self_connection_status(T
return self_connection_status;
}
const Tox_Event_Self_Connection_Status *tox_events_get_self_connection_status(const Tox_Events *events, uint32_t index)
{
uint32_t self_connection_status_index = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (self_connection_status_index > index) {
return nullptr;
}
if (events->events[i].type == TOX_EVENT_SELF_CONNECTION_STATUS) {
const Tox_Event_Self_Connection_Status *self_connection_status = events->events[i].data.self_connection_status;
if (self_connection_status_index == index) {
return self_connection_status;
}
++self_connection_status_index;
}
}
return nullptr;
}
uint32_t tox_events_get_self_connection_status_size(const Tox_Events *events)
{
uint32_t self_connection_status_size = 0;
const uint32_t size = tox_events_get_size(events);
for (uint32_t i = 0; i < size; ++i) {
if (events->events[i].type == TOX_EVENT_SELF_CONNECTION_STATUS) {
++self_connection_status_size;
}
}
return self_connection_status_size;
}
bool tox_event_self_connection_status_unpack(
Tox_Event_Self_Connection_Status **event, Bin_Unpack *bu, const Memory *mem)
{

View File

@ -1,47 +1,87 @@
#include "forwarding.h"
#include <cassert>
#include <cstring>
#include <memory>
#include <optional>
#include "../testing/fuzzing/fuzz_support.h"
#include "../testing/fuzzing/fuzz_tox.h"
namespace {
std::optional<std::tuple<IP_Port, IP_Port, const uint8_t *, size_t>> prepare(Fuzz_Data &input)
{
CONSUME_OR_RETURN_VAL(const uint8_t *ipp_packed, input, SIZE_IP_PORT, std::nullopt);
IP_Port ipp;
unpack_ip_port(&ipp, ipp_packed, SIZE_IP6, true);
CONSUME_OR_RETURN_VAL(const uint8_t *forwarder_packed, input, SIZE_IP_PORT, std::nullopt);
IP_Port forwarder;
unpack_ip_port(&forwarder, forwarder_packed, SIZE_IP6, true);
// 2 bytes: size of the request
CONSUME_OR_RETURN_VAL(const uint8_t *data_size_bytes, input, sizeof(uint16_t), std::nullopt);
uint16_t data_size;
std::memcpy(&data_size, data_size_bytes, sizeof(uint16_t));
// data bytes (max 64K)
CONSUME_OR_RETURN_VAL(const uint8_t *data, input, data_size, std::nullopt);
return {{ipp, forwarder, data, data_size}};
}
void TestSendForwardRequest(Fuzz_Data &input)
{
const Network *ns = system_network(); // TODO(iphydf): fuzz_network
assert(ns != nullptr);
const Memory *mem = system_memory(); // TODO(iphydf): fuzz_memory
assert(mem != nullptr);
CONSUME1_OR_RETURN(const uint16_t, chain_length, input);
const uint16_t chain_keys_size = chain_length * CRYPTO_PUBLIC_KEY_SIZE;
CONSUME_OR_RETURN(const uint8_t *chain_keys, input, chain_keys_size);
with<Logger>{} >> with<Networking_Core>{input, ns, mem} >> [&input](Ptr<Networking_Core> net) {
with<IP_Port>{input} >> [net = std::move(net), &input](const IP_Port &forwarder) {
CONSUME1_OR_RETURN(const uint16_t chain_length, input);
const uint16_t chain_keys_size = chain_length * CRYPTO_PUBLIC_KEY_SIZE;
CONSUME_OR_RETURN(const uint8_t *chain_keys, input, chain_keys_size);
auto prep = prepare(input);
if (!prep.has_value()) {
return;
}
auto [ipp, forwarder, data, data_size] = prep.value();
send_forward_request(
net.get(), &forwarder, chain_keys, chain_length, input.data, input.size);
};
};
// rest of the fuzz data is input for malloc and network
Fuzz_System sys(input);
Ptr<Logger> logger(logger_new(), logger_kill);
Ptr<Networking_Core> net(new_networking_ex(logger.get(), sys.mem.get(), sys.ns.get(), &ipp.ip,
ipp.port, ipp.port + 100, nullptr),
kill_networking);
if (net == nullptr) {
return;
}
send_forward_request(net.get(), &forwarder, chain_keys, chain_length, data, data_size);
}
void TestForwardReply(Fuzz_Data &input)
{
const Network *ns = system_network(); // TODO(iphydf): fuzz_network
assert(ns != nullptr);
const Memory *mem = system_memory(); // TODO(iphydf): fuzz_memory
assert(mem != nullptr);
CONSUME1_OR_RETURN(const uint16_t, sendback_length, input);
CONSUME_OR_RETURN(const uint8_t *sendback, input, sendback_length);
with<Logger>{} >> with<Networking_Core>{input, ns, mem} >> [&input](Ptr<Networking_Core> net) {
with<IP_Port>{input} >> [net = std::move(net), &input](const IP_Port &forwarder) {
CONSUME1_OR_RETURN(const uint16_t sendback_length, input);
CONSUME_OR_RETURN(const uint8_t *sendback, input, sendback_length);
auto prep = prepare(input);
if (!prep.has_value()) {
return;
}
auto [ipp, forwarder, data, data_size] = prep.value();
forward_reply(net.get(), &forwarder, sendback, sendback_length, input.data, input.size);
};
};
// rest of the fuzz data is input for malloc and network
Fuzz_System sys(input);
Ptr<Logger> logger(logger_new(), logger_kill);
Ptr<Networking_Core> net(new_networking_ex(logger.get(), sys.mem.get(), sys.ns.get(), &ipp.ip,
ipp.port, ipp.port + 100, nullptr),
kill_networking);
if (net == nullptr) {
return;
}
forward_reply(net.get(), &forwarder, sendback, sendback_length, data, data_size);
}
} // namespace

View File

@ -684,7 +684,7 @@ static bool delete_frozen(Group_c *g, uint32_t frozen_index)
g->frozen[frozen_index] = g->frozen[g->numfrozen];
}
Group_Peer *const frozen_temp = (Group_Peer *)realloc(g->frozen, sizeof(Group_Peer) * g->numfrozen);
Group_Peer *const frozen_temp = (Group_Peer *)realloc(g->frozen, g->numfrozen * sizeof(Group_Peer));
if (frozen_temp == nullptr) {
return false;
@ -725,7 +725,7 @@ static int note_peer_active(Group_Chats *g_c, uint32_t groupnumber, uint16_t pee
/* Now thaw the peer */
Group_Peer *temp = (Group_Peer *)realloc(g->group, sizeof(Group_Peer) * (g->numpeers + 1));
Group_Peer *temp = (Group_Peer *)realloc(g->group, (g->numpeers + 1) * sizeof(Group_Peer));
if (temp == nullptr) {
return -1;
@ -838,7 +838,7 @@ static int addpeer(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_p
delete_any_peer_with_pk(g_c, groupnumber, real_pk, userdata);
Group_Peer *temp = (Group_Peer *)realloc(g->group, sizeof(Group_Peer) * (g->numpeers + 1));
Group_Peer *temp = (Group_Peer *)realloc(g->group, (g->numpeers + 1) * sizeof(Group_Peer));
if (temp == nullptr) {
return -1;
@ -936,7 +936,7 @@ static bool delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void
g->group[peer_index] = g->group[g->numpeers];
}
Group_Peer *temp = (Group_Peer *)realloc(g->group, sizeof(Group_Peer) * g->numpeers);
Group_Peer *temp = (Group_Peer *)realloc(g->group, g->numpeers * sizeof(Group_Peer));
if (temp == nullptr) {
return false;
@ -995,7 +995,7 @@ static bool delete_old_frozen(Group_c *g)
qsort(g->frozen, g->numfrozen, sizeof(Group_Peer), cmp_frozen);
Group_Peer *temp = (Group_Peer *)realloc(g->frozen, sizeof(Group_Peer) * g->maxfrozen);
Group_Peer *temp = (Group_Peer *)realloc(g->frozen, g->maxfrozen * sizeof(Group_Peer));
if (temp == nullptr) {
return false;
@ -1020,7 +1020,7 @@ static bool freeze_peer(Group_Chats *g_c, uint32_t groupnumber, int peer_index,
return false;
}
Group_Peer *temp = (Group_Peer *)realloc(g->frozen, sizeof(Group_Peer) * (g->numfrozen + 1));
Group_Peer *temp = (Group_Peer *)realloc(g->frozen, (g->numfrozen + 1) * sizeof(Group_Peer));
if (temp == nullptr) {
return false;

View File

@ -339,6 +339,31 @@ int gca_unpack_announces_list(const Logger *log, const uint8_t *data, uint16_t l
return announces_count;
}
non_null()
static GC_Announces *gca_new_announces(
GC_Announces_List *gc_announces_list,
const GC_Public_Announce *public_announce)
{
GC_Announces *announces = (GC_Announces *)calloc(1, sizeof(GC_Announces));
if (announces == nullptr) {
return nullptr;
}
announces->index = 0;
announces->prev_announce = nullptr;
if (gc_announces_list->root_announces != nullptr) {
gc_announces_list->root_announces->prev_announce = announces;
}
announces->next_announce = gc_announces_list->root_announces;
gc_announces_list->root_announces = announces;
memcpy(announces->chat_id, public_announce->chat_public_key, CHAT_ID_SIZE);
return announces;
}
GC_Peer_Announce *gca_add_announce(const Mono_Time *mono_time, GC_Announces_List *gc_announces_list,
const GC_Public_Announce *public_announce)
{
@ -350,22 +375,11 @@ GC_Peer_Announce *gca_add_announce(const Mono_Time *mono_time, GC_Announces_List
// No entry for this chat_id exists so we create one
if (announces == nullptr) {
announces = (GC_Announces *)calloc(1, sizeof(GC_Announces));
announces = gca_new_announces(gc_announces_list, public_announce);
if (announces == nullptr) {
return nullptr;
}
announces->index = 0;
announces->prev_announce = nullptr;
if (gc_announces_list->root_announces != nullptr) {
gc_announces_list->root_announces->prev_announce = announces;
}
announces->next_announce = gc_announces_list->root_announces;
gc_announces_list->root_announces = announces;
memcpy(announces->chat_id, public_announce->chat_public_key, CHAT_ID_SIZE);
}
const uint64_t cur_time = mono_time_get(mono_time);
@ -396,8 +410,7 @@ bool gca_is_valid_announce(const GC_Announce *announce)
GC_Announces_List *new_gca_list(void)
{
GC_Announces_List *announces_list = (GC_Announces_List *)calloc(1, sizeof(GC_Announces_List));
return announces_list;
return (GC_Announces_List *)calloc(1, sizeof(GC_Announces_List));
}
void kill_gca(GC_Announces_List *announces_list)

View File

@ -11,19 +11,21 @@ namespace {
void TestUnpackAnnouncesList(Fuzz_Data &input)
{
CONSUME1_OR_RETURN(const uint8_t max_count, input);
std::vector<GC_Announce> announces(max_count);
CONSUME1_OR_RETURN(const uint8_t, max_count, input);
// Always allocate at least something to avoid passing nullptr to functions below.
std::vector<GC_Announce> announces(max_count + 1);
// TODO(iphydf): How do we know the packed size?
CONSUME1_OR_RETURN(const uint16_t packed_size, input);
CONSUME1_OR_RETURN(const uint16_t, packed_size, input);
Logger *logger = logger_new();
if (gca_unpack_announces_list(logger, input.data, input.size, announces.data(), max_count)
!= -1) {
std::vector<uint8_t> packed(packed_size);
// Always allocate at least something to avoid passing nullptr to functions below.
std::vector<uint8_t> packed(packed_size + 1);
size_t processed;
gca_pack_announces_list(
logger, packed.data(), packed.size(), announces.data(), announces.size(), &processed);
logger, packed.data(), packed_size, announces.data(), max_count, &processed);
}
logger_kill(logger);
}
@ -33,12 +35,13 @@ void TestUnpackPublicAnnounce(Fuzz_Data &input)
GC_Public_Announce public_announce;
// TODO(iphydf): How do we know the packed size?
CONSUME1_OR_RETURN(const uint16_t packed_size, input);
CONSUME1_OR_RETURN(const uint16_t, packed_size, input);
Logger *logger = logger_new();
if (gca_unpack_public_announce(logger, input.data, input.size, &public_announce) != -1) {
std::vector<uint8_t> packed(packed_size);
gca_pack_public_announce(logger, packed.data(), packed.size(), &public_announce);
// Always allocate at least something to avoid passing nullptr to functions below.
std::vector<uint8_t> packed(packed_size + 1);
gca_pack_public_announce(logger, packed.data(), packed_size, &public_announce);
}
logger_kill(logger);
}
@ -58,11 +61,11 @@ void TestDoGca(Fuzz_Data &input)
assert(gca != nullptr);
while (input.size > 0) {
CONSUME1_OR_RETURN(const uint8_t choice, input);
CONSUME1_OR_RETURN(const uint8_t, choice, input);
switch (choice) {
case 0: {
// Add an announce.
CONSUME1_OR_RETURN(const uint16_t length, input);
CONSUME1_OR_RETURN(const uint16_t, length, input);
CONSUME_OR_RETURN(const uint8_t *data, input, length);
GC_Public_Announce public_announce;
if (gca_unpack_public_announce(logger.get(), data, length, &public_announce) != -1) {
@ -72,7 +75,7 @@ void TestDoGca(Fuzz_Data &input)
}
case 1: {
// Advance the time by a number of tox_iteration_intervals.
CONSUME1_OR_RETURN(const uint8_t iterations, input);
CONSUME1_OR_RETURN(const uint8_t, iterations, input);
clock += iterations * 20;
// Do an iteration.
do_gca(mono_time.get(), gca.get());
@ -80,7 +83,7 @@ void TestDoGca(Fuzz_Data &input)
}
case 2: {
// Get announces.
CONSUME1_OR_RETURN(const uint8_t max_nodes, input);
CONSUME1_OR_RETURN(const uint8_t, max_nodes, input);
std::vector<GC_Announce> gc_announces(max_nodes);
CONSUME_OR_RETURN(const uint8_t *chat_id, input, CHAT_ID_SIZE);
CONSUME_OR_RETURN(const uint8_t *except_public_key, input, ENC_PUBLIC_KEY_SIZE);

View File

@ -2107,16 +2107,17 @@ static int handle_gc_tcp_relays(GC_Chat *chat, GC_Connection *gconn, const uint8
non_null()
static bool send_gc_invite_request(const GC_Chat *chat, GC_Connection *gconn)
{
uint16_t length = 0;
if (!chat_is_password_protected(chat)) {
return send_lossless_group_packet(chat, gconn, nullptr, 0, GP_INVITE_REQUEST);
}
uint8_t data[sizeof(uint16_t) + MAX_GC_PASSWORD_SIZE];
if (chat_is_password_protected(chat)) {
net_pack_u16(data, chat->shared_state.password_length);
length += sizeof(uint16_t);
net_pack_u16(data, chat->shared_state.password_length);
uint16_t length = sizeof(uint16_t);
memcpy(data + length, chat->shared_state.password, MAX_GC_PASSWORD_SIZE);
length += MAX_GC_PASSWORD_SIZE;
}
memcpy(data + length, chat->shared_state.password, MAX_GC_PASSWORD_SIZE);
length += MAX_GC_PASSWORD_SIZE;
return send_lossless_group_packet(chat, gconn, data, length, GP_INVITE_REQUEST);
}
@ -2261,34 +2262,64 @@ FAILED_INVITE:
return ret;
}
/** @brief Sends a lossless packet of type and length to all confirmed peers. */
/** @brief Sends a lossless packet of type and length to all confirmed peers.
*
* Return true if packet is successfully sent to at least one peer or the
* group is empty.
*/
non_null()
static void send_gc_lossless_packet_all_peers(const GC_Chat *chat, const uint8_t *data, uint16_t length, uint8_t type)
static bool send_gc_lossless_packet_all_peers(const GC_Chat *chat, const uint8_t *data, uint16_t length, uint8_t type)
{
uint32_t sent = 0;
uint32_t confirmed_peers = 0;
for (uint32_t i = 1; i < chat->numpeers; ++i) {
GC_Connection *gconn = get_gc_connection(chat, i);
assert(gconn != nullptr);
if (gconn->confirmed) {
send_lossless_group_packet(chat, gconn, data, length, type);
if (!gconn->confirmed) {
continue;
}
++confirmed_peers;
if (send_lossless_group_packet(chat, gconn, data, length, type)) {
++sent;
}
}
return sent > 0 || confirmed_peers == 0;
}
/** @brief Sends a lossy packet of type and length to all confirmed peers. */
/** @brief Sends a lossy packet of type and length to all confirmed peers.
*
* Return true if packet is successfully sent to at least one peer or the
* group is empty.
*/
non_null()
static void send_gc_lossy_packet_all_peers(const GC_Chat *chat, const uint8_t *data, uint16_t length, uint8_t type)
static bool send_gc_lossy_packet_all_peers(const GC_Chat *chat, const uint8_t *data, uint16_t length, uint8_t type)
{
uint32_t sent = 0;
uint32_t confirmed_peers = 0;
for (uint32_t i = 1; i < chat->numpeers; ++i) {
const GC_Connection *gconn = get_gc_connection(chat, i);
assert(gconn != nullptr);
if (gconn->confirmed) {
send_lossy_group_packet(chat, gconn, data, length, type);
if (!gconn->confirmed) {
continue;
}
++confirmed_peers;
if (send_lossy_group_packet(chat, gconn, data, length, type)) {
++sent;
}
}
return sent > 0 || confirmed_peers == 0;
}
/** @brief Creates packet with broadcast header info followed by data of length.
@ -2328,11 +2359,11 @@ static bool send_gc_broadcast_message(const GC_Chat *chat, const uint8_t *data,
const uint16_t packet_len = make_gc_broadcast_header(data, length, packet, bc_type);
send_gc_lossless_packet_all_peers(chat, packet, packet_len, GP_BROADCAST);
const bool ret = send_gc_lossless_packet_all_peers(chat, packet, packet_len, GP_BROADCAST);
free(packet);
return true;
return ret;
}
non_null()
@ -2786,9 +2817,7 @@ static bool broadcast_gc_shared_state(const GC_Chat *chat)
return false;
}
send_gc_lossless_packet_all_peers(chat, packet, (uint16_t)packet_len, GP_SHARED_STATE);
return true;
return send_gc_lossless_packet_all_peers(chat, packet, (uint16_t)packet_len, GP_SHARED_STATE);
}
/** @brief Helper function for `do_gc_shared_state_changes()`.
@ -3309,11 +3338,11 @@ static bool broadcast_gc_sanctions_list(const GC_Chat *chat)
return false;
}
send_gc_lossless_packet_all_peers(chat, packet, (uint16_t)packet_len, GP_SANCTIONS_LIST);
const bool ret = send_gc_lossless_packet_all_peers(chat, packet, (uint16_t)packet_len, GP_SANCTIONS_LIST);
free(packet);
return true;
return ret;
}
/** @brief Re-signs all sanctions list entries signed by public_sig_key and broadcasts
@ -3355,11 +3384,11 @@ static bool broadcast_gc_mod_list(const GC_Chat *chat)
return false;
}
send_gc_lossless_packet_all_peers(chat, packet, length, GP_MOD_LIST);
const bool ret = send_gc_lossless_packet_all_peers(chat, packet, length, GP_MOD_LIST);
free(packet);
return true;
return ret;
}
/** @brief Sends a parting signal to the group.
@ -3716,11 +3745,11 @@ static bool broadcast_gc_topic(const GC_Chat *chat)
return false;
}
send_gc_lossless_packet_all_peers(chat, packet, packet_buf_size, GP_TOPIC);
const bool ret = send_gc_lossless_packet_all_peers(chat, packet, packet_buf_size, GP_TOPIC);
free(packet);
return true;
return ret;
}
int gc_set_topic(GC_Chat *chat, const uint8_t *topic, uint16_t length)
@ -5071,13 +5100,15 @@ int gc_send_custom_packet(const GC_Chat *chat, bool lossless, const uint8_t *dat
return -3;
}
bool success;
if (lossless) {
send_gc_lossless_packet_all_peers(chat, data, length, GP_CUSTOM_PACKET);
success = send_gc_lossless_packet_all_peers(chat, data, length, GP_CUSTOM_PACKET);
} else {
send_gc_lossy_packet_all_peers(chat, data, length, GP_CUSTOM_PACKET);
success = send_gc_lossy_packet_all_peers(chat, data, length, GP_CUSTOM_PACKET);
}
return 0;
return success ? 0 : -4;
}
/** @brief Handles a custom packet.
@ -5295,7 +5326,7 @@ static int handle_gc_message_ack(const GC_Chat *chat, GC_Connection *gconn, cons
if (gcc_encrypt_and_send_lossless_packet(chat, gconn, gconn->send_array[idx].data,
gconn->send_array[idx].data_length,
gconn->send_array[idx].message_id,
gconn->send_array[idx].packet_type)) {
gconn->send_array[idx].packet_type) == 0) {
gconn->send_array[idx].last_send_try = tm;
LOGGER_DEBUG(chat->log, "Re-sent requested packet %llu", (unsigned long long)message_id);
} else {
@ -6211,6 +6242,39 @@ static bool handle_gc_lossless_packet(const GC_Session *c, GC_Chat *chat, const
return true;
}
non_null(1, 2, 3, 4, 6) nullable(8)
static int handle_gc_lossy_packet_decoded(
const GC_Session *c, GC_Chat *chat, GC_Connection *gconn, const GC_Peer *peer,
uint8_t packet_type, const uint8_t *data, uint16_t payload_len, void *userdata)
{
switch (packet_type) {
case GP_MESSAGE_ACK: {
return handle_gc_message_ack(chat, gconn, data, payload_len);
}
case GP_PING: {
return handle_gc_ping(chat, gconn, data, payload_len);
}
case GP_INVITE_RESPONSE_REJECT: {
return handle_gc_invite_response_reject(c, chat, data, payload_len, userdata);
}
case GP_CUSTOM_PACKET: {
return handle_gc_custom_packet(c, chat, peer, data, payload_len, false, userdata);
}
case GP_CUSTOM_PRIVATE_PACKET: {
return handle_gc_custom_private_packet(c, chat, peer, data, payload_len, false, userdata);
}
default: {
LOGGER_WARNING(chat->log, "Warning: handling invalid lossy group packet type 0x%02x", packet_type);
return -1;
}
}
}
/** @brief Handles lossy groupchat message packets.
*
* This function assumes the length has already been validated.
@ -6259,41 +6323,7 @@ static bool handle_gc_lossy_packet(const GC_Session *c, GC_Chat *chat, const uin
return false;
}
int ret = -1;
const uint16_t payload_len = (uint16_t)len;
switch (packet_type) {
case GP_MESSAGE_ACK: {
ret = handle_gc_message_ack(chat, gconn, data, payload_len);
break;
}
case GP_PING: {
ret = handle_gc_ping(chat, gconn, data, payload_len);
break;
}
case GP_INVITE_RESPONSE_REJECT: {
ret = handle_gc_invite_response_reject(c, chat, data, payload_len, userdata);
break;
}
case GP_CUSTOM_PACKET: {
ret = handle_gc_custom_packet(c, chat, peer, data, payload_len, false, userdata);
break;
}
case GP_CUSTOM_PRIVATE_PACKET: {
ret = handle_gc_custom_private_packet(c, chat, peer, data, payload_len, false, userdata);
break;
}
default: {
LOGGER_WARNING(chat->log, "Warning: handling invalid lossy group packet type 0x%02x", packet_type);
free(data);
return false;
}
}
const int ret = handle_gc_lossy_packet_decoded(c, chat, gconn, peer, packet_type, data, (uint16_t)len, userdata);
free(data);
@ -7729,7 +7759,9 @@ bool gc_disconnect_from_group(const GC_Session *c, GC_Chat *chat)
chat->connection_state = CS_DISCONNECTED;
send_gc_broadcast_message(chat, nullptr, 0, GM_PEER_EXIT);
if (!send_gc_broadcast_message(chat, nullptr, 0, GM_PEER_EXIT)) {
LOGGER_DEBUG(chat->log, "Failed to broadcast group exit packet");
}
for (uint32_t i = 1; i < chat->numpeers; ++i) {
GC_Connection *gconn = get_gc_connection(chat, i);

View File

@ -190,6 +190,7 @@ int gc_send_private_message(const GC_Chat *chat, uint32_t peer_id, uint8_t type,
* Returns -1 if the message is too long.
* Returns -2 if the message pointer is NULL or length is zero.
* Returns -3 if the sender has the observer role.
* Returns -4 if the packet did not successfully send to any peer.
*/
non_null()
int gc_send_custom_packet(const GC_Chat *chat, bool lossless, const uint8_t *data, uint16_t length);

View File

@ -85,30 +85,48 @@ void gcc_set_recv_message_id(GC_Connection *gconn, uint64_t id)
}
/** @brief Puts packet data in array_entry.
*
* Requires an empty array entry to be passed, and must not modify the passed
* array entry on error.
*
* Return true on success.
*/
non_null(1, 2) nullable(3)
static bool create_array_entry(const Mono_Time *mono_time, GC_Message_Array_Entry *array_entry, const uint8_t *data,
uint16_t length, uint8_t packet_type, uint64_t message_id)
non_null(1, 2, 3) nullable(4)
static bool create_array_entry(const Logger *log, const Mono_Time *mono_time, GC_Message_Array_Entry *array_entry,
const uint8_t *data, uint16_t length, uint8_t packet_type, uint64_t message_id)
{
if (length > 0) {
if (!array_entry_is_empty(array_entry)) {
LOGGER_WARNING(log, "Failed to create array entry; entry is not empty.");
return false;
}
if (length == 0) {
if (data != nullptr) {
LOGGER_FATAL(log, "Got non-null data with zero length (type %d)", packet_type); // should never happen
return false;
}
array_entry->data = nullptr;
array_entry->data_length = 0;
} else {
if (data == nullptr) {
LOGGER_FATAL(log, "Got null data with non-zero length (type %u)", packet_type); // should never happen
return false;
}
array_entry->data = (uint8_t *)malloc(sizeof(uint8_t) * length);
uint8_t *entry_data = (uint8_t *)malloc(length);
if (array_entry->data == nullptr) {
if (entry_data == nullptr) {
return false;
}
memcpy(array_entry->data, data, length);
memcpy(entry_data, data, length);
array_entry->data = entry_data;
array_entry->data_length = length;
}
const uint64_t tm = mono_time_get(mono_time);
array_entry->data_length = length;
array_entry->packet_type = packet_type;
array_entry->message_id = message_id;
array_entry->time_added = tm;
@ -119,7 +137,7 @@ static bool create_array_entry(const Mono_Time *mono_time, GC_Message_Array_Entr
/** @brief Adds data of length to gconn's send_array.
*
* Returns true on success and increments gconn's send_message_id.
* Returns true and increments gconn's send_message_id on success.
*/
non_null(1, 2, 3) nullable(4)
static bool add_to_send_array(const Logger *log, const Mono_Time *mono_time, GC_Connection *gconn, const uint8_t *data,
@ -134,13 +152,7 @@ static bool add_to_send_array(const Logger *log, const Mono_Time *mono_time, GC_
const uint16_t idx = gcc_get_array_index(gconn->send_message_id);
GC_Message_Array_Entry *array_entry = &gconn->send_array[idx];
if (!array_entry_is_empty(array_entry)) {
LOGGER_DEBUG(log, "Send array entry isn't empty");
return false;
}
if (!create_array_entry(mono_time, array_entry, data, length, packet_type, gconn->send_message_id)) {
LOGGER_WARNING(log, "Failed to create array entry");
if (!create_array_entry(log, mono_time, array_entry, data, length, packet_type, gconn->send_message_id)) {
return false;
}
@ -159,8 +171,15 @@ int gcc_send_lossless_packet(const GC_Chat *chat, GC_Connection *gconn, const ui
return -1;
}
if (!gcc_encrypt_and_send_lossless_packet(chat, gconn, data, length, message_id, packet_type)) {
LOGGER_DEBUG(chat->log, "Failed to send payload: (type: 0x%02x, length: %d)", packet_type, length);
// If the packet fails to wrap/encrypt, we remove it from the send array, since trying to-resend
// the same bad packet probably won't help much. Otherwise we don't care if it doesn't successfully
// send through the wire as it will keep retrying until the connection times out.
if (gcc_encrypt_and_send_lossless_packet(chat, gconn, data, length, message_id, packet_type) == -1) {
const uint16_t idx = gcc_get_array_index(message_id);
GC_Message_Array_Entry *array_entry = &gconn->send_array[idx];
clear_array_entry(array_entry);
gconn->send_message_id = message_id;
LOGGER_ERROR(chat->log, "Failed to encrypt payload: (type: 0x%02x, length: %d)", packet_type, length);
return -2;
}
@ -331,17 +350,7 @@ static bool store_in_recv_array(const Logger *log, const Mono_Time *mono_time, G
const uint16_t idx = gcc_get_array_index(message_id);
GC_Message_Array_Entry *ary_entry = &gconn->recv_array[idx];
if (!array_entry_is_empty(ary_entry)) {
LOGGER_DEBUG(log, "Recv array is not empty");
return false;
}
if (!create_array_entry(mono_time, ary_entry, data, length, packet_type, message_id)) {
LOGGER_WARNING(log, "Failed to create array entry");
return false;
}
return true;
return create_array_entry(log, mono_time, ary_entry, data, length, packet_type, message_id);
}
/**
@ -392,10 +401,9 @@ static uint16_t reassemble_packet(const Logger *log, GC_Connection *gconn, uint8
return 0;
}
assert(*payload == nullptr);
*payload = (uint8_t *)malloc(packet_length);
uint8_t *tmp_payload = (uint8_t *)malloc(packet_length);
if (*payload == nullptr) {
if (tmp_payload == nullptr) {
LOGGER_ERROR(log, "Failed to allocate %u bytes for payload buffer", packet_length);
return 0;
}
@ -409,12 +417,15 @@ static uint16_t reassemble_packet(const Logger *log, GC_Connection *gconn, uint8
entry = &gconn->recv_array[i];
assert(processed + entry->data_length <= packet_length);
memcpy(*payload + processed, entry->data, entry->data_length);
memcpy(tmp_payload + processed, entry->data, entry->data_length);
processed += entry->data_length;
clear_array_entry(entry);
}
assert(*payload == nullptr);
*payload = tmp_payload;
return processed;
}
@ -612,7 +623,7 @@ bool gcc_send_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint
return ret == 0 || direct_send_attempt;
}
bool gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *data,
int gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *data,
uint16_t length, uint64_t message_id, uint8_t packet_type)
{
const uint16_t packet_size = gc_get_wrapped_packet_size(length, NET_PACKET_GC_LOSSLESS);
@ -620,7 +631,7 @@ bool gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connecti
if (packet == nullptr) {
LOGGER_ERROR(chat->log, "Failed to allocate memory for packet buffer");
return false;
return -1;
}
const int enc_len = group_packet_wrap(
@ -630,18 +641,18 @@ bool gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connecti
if (enc_len < 0) {
LOGGER_ERROR(chat->log, "Failed to wrap packet (type: 0x%02x, error: %d)", packet_type, enc_len);
free(packet);
return false;
return -1;
}
if (!gcc_send_packet(chat, gconn, packet, (uint16_t)enc_len)) {
LOGGER_DEBUG(chat->log, "Failed to send packet (type: 0x%02x, enc_len: %d)", packet_type, enc_len);
free(packet);
return false;
return -2;
}
free(packet);
return true;
return 0;
}
void gcc_make_session_shared_key(GC_Connection *gconn, const uint8_t *sender_pk)

View File

@ -143,11 +143,11 @@ bool gcc_send_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint
/** @brief Sends a lossless packet to `gconn` comprised of `data` of size `length`.
*
* This function will add the packet to the lossless send array, encrypt/wrap it using the
* shared key associated with `gconn`, and send it over the wire.
* shared key associated with `gconn`, and try to send it over the wire.
*
* Return 0 on success.
* Return 0 if the packet was successfully encrypted and added to the send array.
* Return -1 if the packet couldn't be added to the send array.
* Return -2 if the packet failed to be encrypted or failed to send.
* Return -2 if the packet failed to be wrapped or encrypted.
*/
non_null(1, 2) nullable(3)
int gcc_send_lossless_packet(const GC_Chat *chat, GC_Connection *gconn, const uint8_t *data, uint16_t length,
@ -172,11 +172,13 @@ bool gcc_send_lossless_packet_fragments(const GC_Chat *chat, GC_Connection *gcon
*
* This function does not add the packet to the send array.
*
* Return true on success.
* Return 0 on success.
* Return -1 if packet wrapping and encryption fails.
* Return -2 if the packet fails to send.
*/
non_null(1, 2) nullable(3)
bool gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *data,
uint16_t length, uint64_t message_id, uint8_t packet_type);
int gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *data,
uint16_t length, uint64_t message_id, uint8_t packet_type);
/** @brief Called when a peer leaves the group. */
non_null()

View File

@ -59,14 +59,16 @@ int mod_list_unpack(Moderation *moderation, const uint8_t *data, uint16_t length
uint16_t unpacked_len = 0;
for (uint16_t i = 0; i < num_mods; ++i) {
tmp_list[i] = (uint8_t *)malloc(sizeof(uint8_t) * MOD_LIST_ENTRY_SIZE);
uint8_t *entry = (uint8_t *)malloc(MOD_LIST_ENTRY_SIZE);
if (tmp_list[i] == nullptr) {
if (entry == nullptr) {
free_uint8_t_pointer_array(moderation->mem, tmp_list, i);
return -1;
}
memcpy(tmp_list[i], &data[i * MOD_LIST_ENTRY_SIZE], MOD_LIST_ENTRY_SIZE);
memcpy(entry, &data[i * MOD_LIST_ENTRY_SIZE], MOD_LIST_ENTRY_SIZE);
tmp_list[i] = entry;
unpacked_len += MOD_LIST_ENTRY_SIZE;
}
@ -208,13 +210,15 @@ bool mod_list_add_entry(Moderation *moderation, const uint8_t *mod_data)
moderation->mod_list = tmp_list;
tmp_list[moderation->num_mods] = (uint8_t *)malloc(sizeof(uint8_t) * MOD_LIST_ENTRY_SIZE);
uint8_t *entry = (uint8_t *)malloc(MOD_LIST_ENTRY_SIZE);
if (tmp_list[moderation->num_mods] == nullptr) {
if (entry == nullptr) {
return false;
}
memcpy(tmp_list[moderation->num_mods], mod_data, MOD_LIST_ENTRY_SIZE);
memcpy(entry, mod_data, MOD_LIST_ENTRY_SIZE);
tmp_list[moderation->num_mods] = entry;
++moderation->num_mods;
return true;

View File

@ -6,7 +6,7 @@ namespace {
void TestModListUnpack(Fuzz_Data &input)
{
CONSUME1_OR_RETURN(const uint16_t num_mods, input);
CONSUME1_OR_RETURN(const uint16_t, num_mods, input);
Moderation mods{system_memory()};
mod_list_unpack(&mods, input.data, input.size, num_mods);
mod_list_cleanup(&mods);

View File

@ -123,7 +123,7 @@ static bool resize(BS_List *list, uint32_t new_size)
list->data = data;
int *ids = (int *)realloc(list->ids, sizeof(int) * new_size);
int *ids = (int *)realloc(list->ids, new_size * sizeof(int));
if (ids == nullptr) {
return false;

View File

@ -119,18 +119,20 @@ Mono_Time *mono_time_new(const Memory *mem, mono_time_current_time_cb *current_t
}
#ifndef ESP_PLATFORM
mono_time->time_update_lock = (pthread_rwlock_t *)mem_alloc(mem, sizeof(pthread_rwlock_t));
pthread_rwlock_t *rwlock = (pthread_rwlock_t *)mem_alloc(mem, sizeof(pthread_rwlock_t));
if (mono_time->time_update_lock == nullptr) {
if (rwlock == nullptr) {
mem_delete(mem, mono_time);
return nullptr;
}
if (pthread_rwlock_init(mono_time->time_update_lock, nullptr) != 0) {
mem_delete(mem, mono_time->time_update_lock);
if (pthread_rwlock_init(rwlock, nullptr) != 0) {
mem_delete(mem, rwlock);
mem_delete(mem, mono_time);
return nullptr;
}
mono_time->time_update_lock = rwlock;
#endif
mono_time_set_current_time_callback(mono_time, current_time_callback, user_data);

View File

@ -1868,25 +1868,26 @@ static int create_crypto_connection(Net_Crypto *c)
}
if (id != -1) {
pthread_mutex_t *mutex = (pthread_mutex_t *)mem_alloc(c->mem, sizeof(pthread_mutex_t));
if (mutex == nullptr) {
pthread_mutex_unlock(&c->connections_mutex);
return -1;
}
if (pthread_mutex_init(mutex, nullptr) != 0) {
mem_delete(c->mem, mutex);
pthread_mutex_unlock(&c->connections_mutex);
return -1;
}
// Memsetting float/double to 0 is non-portable, so we explicitly set them to 0
c->crypto_connections[id].packet_recv_rate = 0;
c->crypto_connections[id].packet_send_rate = 0;
c->crypto_connections[id].last_packets_left_rem = 0;
c->crypto_connections[id].packet_send_rate_requested = 0;
c->crypto_connections[id].last_packets_left_requested_rem = 0;
c->crypto_connections[id].mutex = (pthread_mutex_t *)mem_alloc(c->mem, sizeof(pthread_mutex_t));
if (c->crypto_connections[id].mutex == nullptr) {
pthread_mutex_unlock(&c->connections_mutex);
return -1;
}
if (pthread_mutex_init(c->crypto_connections[id].mutex, nullptr) != 0) {
mem_delete(c->mem, c->crypto_connections[id].mutex);
pthread_mutex_unlock(&c->connections_mutex);
return -1;
}
c->crypto_connections[id].packet_recv_rate = 0.0;
c->crypto_connections[id].packet_send_rate = 0.0;
c->crypto_connections[id].last_packets_left_rem = 0.0;
c->crypto_connections[id].packet_send_rate_requested = 0.0;
c->crypto_connections[id].last_packets_left_requested_rem = 0.0;
c->crypto_connections[id].mutex = mutex;
c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION;
}
@ -2022,13 +2023,14 @@ non_null(1, 2, 3) nullable(5)
static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const uint8_t *data, uint16_t length,
void *userdata)
{
New_Connection n_c;
n_c.cookie = (uint8_t *)mem_balloc(c->mem, COOKIE_LENGTH);
uint8_t *cookie = (uint8_t *)mem_balloc(c->mem, COOKIE_LENGTH);
if (n_c.cookie == nullptr) {
if (cookie == nullptr) {
return -1;
}
New_Connection n_c = {{{{0}}}};
n_c.cookie = cookie;
n_c.source = *source;
n_c.cookie_length = COOKIE_LENGTH;

View File

@ -1796,12 +1796,14 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if ((true)) {
*res = (IP_Port *)mem_alloc(mem, sizeof(IP_Port));
assert(*res != nullptr);
IP_Port *ip_port = *res;
IP_Port *ip_port = (IP_Port *)mem_alloc(mem, sizeof(IP_Port));
if (ip_port == nullptr) {
abort();
}
ip_port->ip.ip.v4.uint32 = net_htonl(0x7F000003); // 127.0.0.3
ip_port->ip.family = *make_tox_family(AF_INET);
*res = ip_port;
return 1;
}
#endif
@ -1838,14 +1840,15 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to
return 0;
}
*res = (IP_Port *)mem_valloc(mem, count, sizeof(IP_Port));
IP_Port *ip_port = (IP_Port *)mem_valloc(mem, count, sizeof(IP_Port));
if (*res == nullptr) {
if (ip_port == nullptr) {
freeaddrinfo(infos);
*res = nullptr;
return -1;
}
IP_Port *ip_port = *res;
*res = ip_port;
for (struct addrinfo *cur = infos; cur != nullptr; cur = cur->ai_next) {
if (cur->ai_socktype && type > 0 && cur->ai_socktype != type) {

View File

@ -0,0 +1,66 @@
#include "network_test_util.hh"
#include <iomanip>
IP_Port increasing_ip_port::operator()()
{
IP_Port ip_port;
ip_port.ip.family = net_family_ipv4();
ip_port.ip.ip.v4.uint8[0] = 192;
ip_port.ip.ip.v4.uint8[1] = 168;
ip_port.ip.ip.v4.uint8[2] = 0;
ip_port.ip.ip.v4.uint8[3] = start_;
ip_port.port = random_u16(rng_);
++start_;
return ip_port;
}
IP_Port random_ip_port(const Random *rng)
{
IP_Port ip_port;
ip_port.ip.family = net_family_ipv4();
ip_port.ip.ip.v4.uint8[0] = 192;
ip_port.ip.ip.v4.uint8[1] = 168;
ip_port.ip.ip.v4.uint8[2] = 0;
ip_port.ip.ip.v4.uint8[3] = random_u08(rng);
ip_port.port = random_u16(rng);
return ip_port;
}
bool operator==(Family const &a, Family const &b) { return a.value == b.value; }
bool operator==(IP4 const &a, IP4 const &b) { return a.uint32 == b.uint32; }
bool operator==(IP6 const &a, IP6 const &b)
{
return a.uint64[0] == b.uint64[0] && a.uint64[1] == b.uint64[1];
}
bool operator==(IP const &a, IP const &b)
{
if (!(a.family == b.family)) {
return false;
}
if (net_family_is_ipv4(a.family)) {
return a.ip.v4 == b.ip.v4;
} else {
return a.ip.v6 == b.ip.v6;
}
}
bool operator==(IP_Port const &a, IP_Port const &b) { return a.ip == b.ip && a.port == b.port; }
std::ostream &operator<<(std::ostream &out, IP const &v)
{
Ip_Ntoa ip_str;
out << '"' << net_ip_ntoa(&v, &ip_str) << '"';
return out;
}
std::ostream &operator<<(std::ostream &out, IP_Port const &v)
{
return out << "IP_Port{\n"
<< " ip = " << v.ip << ",\n"
<< " port = " << std::dec << std::setw(0) << v.port << " }";
}

View File

@ -0,0 +1,39 @@
#ifndef C_TOXCORE_TOXCORE_NETWORK_TEST_UTIL_H
#define C_TOXCORE_TOXCORE_NETWORK_TEST_UTIL_H
#include <iosfwd>
#include "crypto_core.h"
#include "network.h"
#include "test_util.hh"
template <>
struct Deleter<Networking_Core> : Function_Deleter<Networking_Core, kill_networking> { };
IP_Port random_ip_port(const Random *rng);
class increasing_ip_port {
uint8_t start_;
const Random *rng_;
public:
explicit increasing_ip_port(uint8_t start, const Random *rng)
: start_(start)
, rng_(rng)
{
}
IP_Port operator()();
};
bool operator==(Family const &a, Family const &b);
bool operator==(IP4 const &a, IP4 const &b);
bool operator==(IP6 const &a, IP6 const &b);
bool operator==(IP const &a, IP const &b);
bool operator==(IP_Port const &a, IP_Port const &b);
std::ostream &operator<<(std::ostream &out, IP const &v);
std::ostream &operator<<(std::ostream &out, IP_Port const &v);
#endif // C_TOXCORE_TOXCORE_NETWORK_TEST_UTIL_H

View File

@ -49,14 +49,15 @@ Ping_Array *ping_array_new(const Memory *mem, uint32_t size, uint32_t timeout)
return nullptr;
}
empty_array->mem = mem;
empty_array->entries = (Ping_Array_Entry *)mem_valloc(mem, size, sizeof(Ping_Array_Entry));
Ping_Array_Entry *entries = (Ping_Array_Entry *)mem_valloc(mem, size, sizeof(Ping_Array_Entry));
if (empty_array->entries == nullptr) {
if (entries == nullptr) {
mem_delete(mem, empty_array);
return nullptr;
}
empty_array->mem = mem;
empty_array->entries = entries;
empty_array->last_deleted = 0;
empty_array->last_added = 0;
empty_array->total_size = size;
@ -115,13 +116,16 @@ uint64_t ping_array_add(Ping_Array *array, const Mono_Time *mono_time, const Ran
clear_entry(array, index);
}
array->entries[index].data = (uint8_t *)mem_balloc(array->mem, length);
uint8_t *entry_data = (uint8_t *)mem_balloc(array->mem, length);
if (array->entries[index].data == nullptr) {
if (entry_data == nullptr) {
array->entries[index].data = nullptr;
return 0;
}
memcpy(array->entries[index].data, data, length);
memcpy(entry_data, data, length);
array->entries[index].data = entry_data;
array->entries[index].length = length;
array->entries[index].ping_time = mono_time_get(mono_time);
++array->last_added;

View File

@ -68,16 +68,19 @@ Shared_Key_Cache *shared_key_cache_new(const Logger *log, const Mono_Time *mono_
res->mem = mem;
res->log = log;
res->keys_per_slot = keys_per_slot;
// We take one byte from the public key for each bucket and store keys_per_slot elements there
const size_t cache_size = 256 * keys_per_slot;
res->keys = (Shared_Key *)mem_valloc(mem, cache_size, sizeof(Shared_Key));
Shared_Key *keys = (Shared_Key *)mem_valloc(mem, cache_size, sizeof(Shared_Key));
if (res->keys == nullptr) {
if (keys == nullptr) {
mem_delete(mem, res);
return nullptr;
}
crypto_memlock(res->keys, cache_size * sizeof(Shared_Key));
crypto_memlock(keys, cache_size * sizeof(Shared_Key));
res->keys = keys;
return res;
}

View File

@ -0,0 +1 @@
#include "test_util.hh"

View File

@ -0,0 +1,68 @@
#ifndef C_TOXCORE_TOXCORE_TEST_UTIL_H
#define C_TOXCORE_TOXCORE_TEST_UTIL_H
#include <algorithm>
#include <array>
#include <memory>
#include <vector>
template <typename T, void (*Delete)(T *)>
struct Function_Deleter {
void operator()(T *ptr) const { Delete(ptr); }
};
// No default deleter, because we want to catch when we forget to specialise this one.
template <typename T>
struct Deleter;
template <typename T>
using Ptr = std::unique_ptr<T, Deleter<T>>;
template <typename Func, typename Class>
struct Method;
template <typename R, typename Class, typename... Args>
struct Method<R(void *, Args...), Class> {
template <R (Class::*M)(void *, Args...)>
static R invoke(void *self, Args... args)
{
return (static_cast<Class *>(self)->*M)(self, args...);
}
};
template <typename T, std::size_t N>
std::array<T, N> to_array(T const (&arr)[N])
{
std::array<T, N> stdarr;
std::copy(arr, arr + N, stdarr.begin());
return stdarr;
}
template <std::size_t N, typename T, typename... Args>
auto array_of(T &&make, Args... args)
{
std::array<typename std::result_of<T(Args...)>::type, N> arr;
for (auto &elem : arr) {
elem = make(args...);
}
return arr;
}
template <typename T, typename... Args>
auto vector_of(std::size_t n, T &&make, Args... args)
{
std::vector<typename std::result_of<T(Args...)>::type> vec;
for (std::size_t i = 0; i < n; ++i) {
vec.push_back(make(args...));
}
return vec;
}
template <typename Container, typename Less>
Container sorted(Container arr, Less less)
{
std::sort(arr.begin(), arr.end(), less);
return arr;
}
#endif // C_TOXCORE_TOXCORE_TEST_UTIL_H

View File

@ -0,0 +1,64 @@
#include "test_util.hh"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <array>
#include "crypto_core_test_util.hh"
namespace {
using ::testing::Each;
using ::testing::Eq;
TEST(CryptoCoreTestUtil, RandomBytesDoesNotTouchZeroSizeArray)
{
const Test_Random rng;
std::array<uint8_t, 32> bytes{};
for (uint32_t i = 0; i < 100; ++i) {
random_bytes(rng, bytes.data(), 0);
ASSERT_THAT(bytes, Each(Eq(0x00)));
}
}
TEST(CryptoCoreTestUtil, RandomBytesFillsEntireArray)
{
const Test_Random rng;
std::array<uint8_t, 32> bytes{};
for (uint32_t size = 1; size < bytes.size(); ++size) {
bool const success = [&]() {
// Try a few times. There ought to be a non-zero byte in our randomness at
// some point.
for (uint32_t i = 0; i < 100; ++i) {
random_bytes(rng, bytes.data(), bytes.size());
if (bytes[size - 1] != 0x00) {
return true;
}
}
return false;
}();
ASSERT_TRUE(success);
}
}
TEST(CryptoCoreTestUtil, RandomBytesDoesNotBufferOverrun)
{
const Test_Random rng;
std::array<uint8_t, 32> bytes{};
// Try a few times. It should never overrun.
for (uint32_t i = 0; i < 100; ++i) {
for (uint32_t diff = 1; diff < sizeof(uint64_t); ++diff) {
bytes = {};
random_bytes(rng, bytes.data(), bytes.size() - diff);
// All bytes not in the range we want to write should be 0.
ASSERT_THAT(std::vector<uint8_t>(bytes.begin() + (bytes.size() - diff), bytes.end()),
Each(Eq(0x00)));
}
}
}
} // namespace

View File

@ -796,21 +796,21 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
}
if (tox_options_get_experimental_thread_safety(opts)) {
tox->mutex = (pthread_mutex_t *)mem_alloc(sys->mem, sizeof(pthread_mutex_t));
pthread_mutex_t *mutex = (pthread_mutex_t *)mem_alloc(sys->mem, sizeof(pthread_mutex_t));
if (tox->mutex == nullptr) {
if (mutex == nullptr) {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
mem_delete(sys->mem, tox);
tox_options_free(default_options);
return nullptr;
}
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(tox->mutex, &attr);
pthread_mutex_init(mutex, &attr);
tox->mutex = mutex;
} else {
tox->mutex = nullptr;
}
@ -4021,6 +4021,11 @@ bool tox_group_send_custom_packet(const Tox *tox, uint32_t group_number, bool lo
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_CUSTOM_PACKET_PERMISSIONS);
return false;
}
case -4: {
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_SEND_CUSTOM_PACKET_FAIL_SEND);
return false;
}
}
/* can't happen */

View File

@ -4736,6 +4736,12 @@ typedef enum Tox_Err_Group_Send_Custom_Packet {
*/
TOX_ERR_GROUP_SEND_CUSTOM_PACKET_DISCONNECTED,
/**
* The packet did not successfully send to any peer. This often indicates
* a connection issue on the sender's side.
*/
TOX_ERR_GROUP_SEND_CUSTOM_PACKET_FAIL_SEND,
} Tox_Err_Group_Send_Custom_Packet;
const char *tox_err_group_send_custom_packet_to_string(Tox_Err_Group_Send_Custom_Packet value);

View File

@ -1259,6 +1259,9 @@ const char *tox_err_group_send_custom_packet_to_string(Tox_Err_Group_Send_Custom
case TOX_ERR_GROUP_SEND_CUSTOM_PACKET_DISCONNECTED:
return "TOX_ERR_GROUP_SEND_CUSTOM_PACKET_DISCONNECTED";
case TOX_ERR_GROUP_SEND_CUSTOM_PACKET_FAIL_SEND:
return "TOX_ERR_GROUP_SEND_CUSTOM_PACKET_FAIL_SEND";
}
return "<invalid Tox_Err_Group_Send_Custom_Packet>";

View File

@ -278,7 +278,7 @@ void tox_events_callback_group_moderation(
dispatch->group_moderation_callback = callback;
}
non_null(1, 2, 3) nullable(4)
non_null(1, 2) nullable(3, 4)
static void tox_dispatch_invoke_event(const Tox_Dispatch *dispatch, const Tox_Event *event, Tox *tox, void *user_data)
{
switch (event->type) {

View File

@ -497,125 +497,6 @@ typedef struct Tox_Events Tox_Events;
uint32_t tox_events_get_size(const Tox_Events *events);
const Tox_Event *tox_events_get(const Tox_Events *events, uint32_t index);
uint32_t tox_events_get_conference_connected_size(const Tox_Events *events);
uint32_t tox_events_get_conference_invite_size(const Tox_Events *events);
uint32_t tox_events_get_conference_message_size(const Tox_Events *events);
uint32_t tox_events_get_conference_peer_list_changed_size(const Tox_Events *events);
uint32_t tox_events_get_conference_peer_name_size(const Tox_Events *events);
uint32_t tox_events_get_conference_title_size(const Tox_Events *events);
uint32_t tox_events_get_file_chunk_request_size(const Tox_Events *events);
uint32_t tox_events_get_file_recv_chunk_size(const Tox_Events *events);
uint32_t tox_events_get_file_recv_control_size(const Tox_Events *events);
uint32_t tox_events_get_file_recv_size(const Tox_Events *events);
uint32_t tox_events_get_friend_connection_status_size(const Tox_Events *events);
uint32_t tox_events_get_friend_lossless_packet_size(const Tox_Events *events);
uint32_t tox_events_get_friend_lossy_packet_size(const Tox_Events *events);
uint32_t tox_events_get_friend_message_size(const Tox_Events *events);
uint32_t tox_events_get_friend_name_size(const Tox_Events *events);
uint32_t tox_events_get_friend_read_receipt_size(const Tox_Events *events);
uint32_t tox_events_get_friend_request_size(const Tox_Events *events);
uint32_t tox_events_get_friend_status_message_size(const Tox_Events *events);
uint32_t tox_events_get_friend_status_size(const Tox_Events *events);
uint32_t tox_events_get_friend_typing_size(const Tox_Events *events);
uint32_t tox_events_get_self_connection_status_size(const Tox_Events *events);
uint32_t tox_events_get_group_peer_name_size(const Tox_Events *events);
uint32_t tox_events_get_group_peer_status_size(const Tox_Events *events);
uint32_t tox_events_get_group_topic_size(const Tox_Events *events);
uint32_t tox_events_get_group_privacy_state_size(const Tox_Events *events);
uint32_t tox_events_get_group_voice_state_size(const Tox_Events *events);
uint32_t tox_events_get_group_topic_lock_size(const Tox_Events *events);
uint32_t tox_events_get_group_peer_limit_size(const Tox_Events *events);
uint32_t tox_events_get_group_password_size(const Tox_Events *events);
uint32_t tox_events_get_group_message_size(const Tox_Events *events);
uint32_t tox_events_get_group_private_message_size(const Tox_Events *events);
uint32_t tox_events_get_group_custom_packet_size(const Tox_Events *events);
uint32_t tox_events_get_group_custom_private_packet_size(const Tox_Events *events);
uint32_t tox_events_get_group_invite_size(const Tox_Events *events);
uint32_t tox_events_get_group_peer_join_size(const Tox_Events *events);
uint32_t tox_events_get_group_peer_exit_size(const Tox_Events *events);
uint32_t tox_events_get_group_self_join_size(const Tox_Events *events);
uint32_t tox_events_get_group_join_fail_size(const Tox_Events *events);
uint32_t tox_events_get_group_moderation_size(const Tox_Events *events);
const Tox_Event_Conference_Connected *tox_events_get_conference_connected(
const Tox_Events *events, uint32_t index);
const Tox_Event_Conference_Invite *tox_events_get_conference_invite(
const Tox_Events *events, uint32_t index);
const Tox_Event_Conference_Message *tox_events_get_conference_message(
const Tox_Events *events, uint32_t index);
const Tox_Event_Conference_Peer_List_Changed *tox_events_get_conference_peer_list_changed(
const Tox_Events *events, uint32_t index);
const Tox_Event_Conference_Peer_Name *tox_events_get_conference_peer_name(
const Tox_Events *events, uint32_t index);
const Tox_Event_Conference_Title *tox_events_get_conference_title(
const Tox_Events *events, uint32_t index);
const Tox_Event_File_Chunk_Request *tox_events_get_file_chunk_request(
const Tox_Events *events, uint32_t index);
const Tox_Event_File_Recv_Chunk *tox_events_get_file_recv_chunk(
const Tox_Events *events, uint32_t index);
const Tox_Event_File_Recv_Control *tox_events_get_file_recv_control(
const Tox_Events *events, uint32_t index);
const Tox_Event_File_Recv *tox_events_get_file_recv(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Connection_Status *tox_events_get_friend_connection_status(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Lossless_Packet *tox_events_get_friend_lossless_packet(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Lossy_Packet *tox_events_get_friend_lossy_packet(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Message *tox_events_get_friend_message(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Name *tox_events_get_friend_name(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Read_Receipt *tox_events_get_friend_read_receipt(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Request *tox_events_get_friend_request(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Status_Message *tox_events_get_friend_status_message(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Status *tox_events_get_friend_status(
const Tox_Events *events, uint32_t index);
const Tox_Event_Friend_Typing *tox_events_get_friend_typing(
const Tox_Events *events, uint32_t index);
const Tox_Event_Self_Connection_Status *tox_events_get_self_connection_status(
const Tox_Events *events, uint32_t index);
const Tox_Event_Group_Peer_Name *tox_events_get_group_peer_name(
const Tox_Events *events, uint32_t index);
const Tox_Event_Group_Peer_Status *tox_events_get_group_peer_status(
const Tox_Events *events, uint32_t index);
const Tox_Event_Group_Topic *tox_events_get_group_topic(
const Tox_Events *events, uint32_t index);
const Tox_Event_Group_Privacy_State *tox_events_get_group_privacy_state(
const Tox_Events *events, uint32_t index);
const Tox_Event_Group_Voice_State *tox_events_get_group_voice_state(
const Tox_Events *events, uint32_t index);
const Tox_Event_Group_Topic_Lock *tox_events_get_group_topic_lock(
const Tox_Events *events, uint32_t index);
const Tox_Event_Group_Peer_Limit *tox_events_get_group_peer_limit(
const Tox_Events *events, uint32_t index);
const Tox_Event_Group_Password *tox_events_get_group_password(
const Tox_Events *events, uint32_t index);
const Tox_Event_Group_Message *tox_events_get_group_message(
const Tox_Events *events, uint32_t index);
const Tox_Event_Group_Private_Message *tox_events_get_group_private_message(
const Tox_Events *events, uint32_t index);
const Tox_Event_Group_Custom_Packet *tox_events_get_group_custom_packet(
const Tox_Events *events, uint32_t index);
const Tox_Event_Group_Custom_Private_Packet *tox_events_get_group_custom_private_packet(
const Tox_Events *events, uint32_t index);
const Tox_Event_Group_Invite *tox_events_get_group_invite(
const Tox_Events *events, uint32_t index);
const Tox_Event_Group_Peer_Join *tox_events_get_group_peer_join(
const Tox_Events *events, uint32_t index);
const Tox_Event_Group_Peer_Exit *tox_events_get_group_peer_exit(
const Tox_Events *events, uint32_t index);
const Tox_Event_Group_Self_Join *tox_events_get_group_self_join(
const Tox_Events *events, uint32_t index);
const Tox_Event_Group_Join_Fail *tox_events_get_group_join_fail(
const Tox_Events *events, uint32_t index);
const Tox_Event_Group_Moderation *tox_events_get_group_moderation(
const Tox_Events *events, uint32_t index);
/**
* Initialise the events recording system.
*

View File

@ -1,10 +1,12 @@
#include "tox_events.h"
#include <cassert>
#include <cstdint>
#include <cstring>
#include <vector>
#include "../testing/fuzzing/fuzz_support.h"
#include "tox_dispatch.h"
namespace {
@ -27,12 +29,59 @@ void TestUnpack(Fuzz_Data data)
// rest of the fuzz data is input for malloc
Fuzz_System sys{data};
Tox_Dispatch *dispatch = tox_dispatch_new(nullptr);
assert(dispatch != nullptr);
auto ignore = [](Tox *tox, auto *event, void *user_data) {};
tox_events_callback_conference_connected(dispatch, ignore);
tox_events_callback_conference_invite(dispatch, ignore);
tox_events_callback_conference_message(dispatch, ignore);
tox_events_callback_conference_peer_list_changed(dispatch, ignore);
tox_events_callback_conference_peer_name(dispatch, ignore);
tox_events_callback_conference_title(dispatch, ignore);
tox_events_callback_file_chunk_request(dispatch, ignore);
tox_events_callback_file_recv(dispatch, ignore);
tox_events_callback_file_recv_chunk(dispatch, ignore);
tox_events_callback_file_recv_control(dispatch, ignore);
tox_events_callback_friend_connection_status(dispatch, ignore);
tox_events_callback_friend_lossless_packet(dispatch, ignore);
tox_events_callback_friend_lossy_packet(dispatch, ignore);
tox_events_callback_friend_message(dispatch, ignore);
tox_events_callback_friend_name(dispatch, ignore);
tox_events_callback_friend_read_receipt(dispatch, ignore);
tox_events_callback_friend_request(dispatch, ignore);
tox_events_callback_friend_status(dispatch, ignore);
tox_events_callback_friend_status_message(dispatch, ignore);
tox_events_callback_friend_typing(dispatch, ignore);
tox_events_callback_self_connection_status(dispatch, ignore);
tox_events_callback_group_peer_name(dispatch, ignore);
tox_events_callback_group_peer_status(dispatch, ignore);
tox_events_callback_group_topic(dispatch, ignore);
tox_events_callback_group_privacy_state(dispatch, ignore);
tox_events_callback_group_voice_state(dispatch, ignore);
tox_events_callback_group_topic_lock(dispatch, ignore);
tox_events_callback_group_peer_limit(dispatch, ignore);
tox_events_callback_group_password(dispatch, ignore);
tox_events_callback_group_message(dispatch, ignore);
tox_events_callback_group_private_message(dispatch, ignore);
tox_events_callback_group_custom_packet(dispatch, ignore);
tox_events_callback_group_custom_private_packet(dispatch, ignore);
tox_events_callback_group_invite(dispatch, ignore);
tox_events_callback_group_peer_join(dispatch, ignore);
tox_events_callback_group_peer_exit(dispatch, ignore);
tox_events_callback_group_self_join(dispatch, ignore);
tox_events_callback_group_join_fail(dispatch, ignore);
tox_events_callback_group_moderation(dispatch, ignore);
Tox_Events *events = tox_events_load(sys.sys.get(), events_data, events_size);
if (events) {
std::vector<uint8_t> packed(tox_events_bytes_size(events));
tox_events_get_bytes(events, packed.data());
tox_dispatch_invoke(dispatch, events, nullptr, nullptr);
}
tox_events_free(events);
tox_dispatch_free(dispatch);
}
} // namespace

View File

@ -33,7 +33,7 @@ TEST(ToxEvents, UnpackEmptyArrayCreatesEmptyEvents)
std::array<uint8_t, 1> data{0x90}; // empty msgpack array
Tox_Events *events = tox_events_load(&sys, data.data(), data.size());
ASSERT_NE(events, nullptr);
EXPECT_EQ(tox_events_get_conference_connected_size(events), 0);
EXPECT_EQ(tox_events_get_size(events), 0);
tox_events_free(events);
}

View File

@ -3,13 +3,13 @@
#include <gtest/gtest.h>
#include "crypto_core.h"
#include "crypto_core_test_util.hh"
namespace {
TEST(Util, TwoRandomIdsAreNotEqual)
{
const Random *rng = system_random();
ASSERT_NE(rng, nullptr);
Test_Random rng;
uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t sk1[CRYPTO_SECRET_KEY_SIZE];
uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE];
@ -23,8 +23,7 @@ TEST(Util, TwoRandomIdsAreNotEqual)
TEST(Util, IdCopyMakesKeysEqual)
{
const Random *rng = system_random();
ASSERT_NE(rng, nullptr);
Test_Random rng;
uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t sk1[CRYPTO_SECRET_KEY_SIZE];
uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE] = {0};