Fix errors on error paths found by oomer.

* Use-after-free because we free network before dht in one case.
* Various unchecked allocs in tests (not so important).
* We used to not check whether ping arrays were actually allocated in DHT.
* `ping_kill` and `ping_array_kill` used to crash when passing NULL.

Also:
* Added an assert in all public API functions to ensure tox isn't NULL.
  The error message you get from that is a bit nicer than "Segmentation
  fault" when clients (or our tests) do things wrong.
* Decreased the sleep time in iterate_all_wait from 20ms to 5ms.
  Everything seems to still work with 5ms, and this greatly decreases
  the amount of time spent per test run, making oomer run much faster.
This commit is contained in:
iphydf 2020-05-02 20:49:41 +01:00
parent e057bae563
commit 2570ddcb17
No known key found for this signature in database
GPG Key ID: 3855DBA2D74403C9
16 changed files with 197 additions and 22 deletions

View File

@ -39,7 +39,7 @@ static void iterate_all_wait(uint32_t tox_count, Tox **toxes, State *state, uint
}
/* Also actually sleep a little, to allow for local network processing */
c_sleep(20);
c_sleep(5);
}
static uint64_t get_state_clock_callback(Mono_Time *mono_time, void *user_data)
@ -63,6 +63,9 @@ static void run_auto_test(uint32_t tox_count, void test(Tox **toxes, State *stat
Tox **toxes = (Tox **)calloc(tox_count, sizeof(Tox *));
State *state = (State *)calloc(tox_count, sizeof(State));
ck_assert(toxes != nullptr);
ck_assert(state != nullptr);
for (uint32_t i = 0; i < tox_count; i++) {
state[i].index = i;
toxes[i] = tox_new_log(nullptr, nullptr, &state[i].index);
@ -82,7 +85,9 @@ static void run_auto_test(uint32_t tox_count, void test(Tox **toxes, State *stat
uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
tox_self_get_public_key(toxes[j], public_key);
tox_friend_add_norequest(toxes[i], public_key, nullptr);
Tox_Err_Friend_Add err;
tox_friend_add_norequest(toxes[i], public_key, &err);
ck_assert(err == TOX_ERR_FRIEND_ADD_OK);
}
}
} else {
@ -93,7 +98,9 @@ static void run_auto_test(uint32_t tox_count, void test(Tox **toxes, State *stat
if (i != j) {
uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
tox_self_get_public_key(toxes[j], public_key);
tox_friend_add_norequest(toxes[i], public_key, nullptr);
Tox_Err_Friend_Add err;
tox_friend_add_norequest(toxes[i], public_key, &err);
ck_assert(err == TOX_ERR_FRIEND_ADD_OK);
}
}
}
@ -105,7 +112,9 @@ static void run_auto_test(uint32_t tox_count, void test(Tox **toxes, State *stat
const uint16_t dht_port = tox_self_get_udp_port(toxes[0], nullptr);
for (uint32_t i = 1; i < tox_count; i++) {
tox_bootstrap(toxes[i], "localhost", dht_port, dht_key, nullptr);
Tox_Err_Bootstrap err;
tox_bootstrap(toxes[i], "localhost", dht_port, dht_key, &err);
ck_assert(err == TOX_ERR_BOOTSTRAP_OK);
}
do {

View File

@ -38,8 +38,10 @@ static void test_one(void)
uint32_t index[] = { 1, 2 };
Tox *tox1 = tox_new_log(nullptr, nullptr, &index[0]);
ck_assert(tox1 != nullptr);
set_random_name_and_status_message(tox1, name, status_message);
Tox *tox2 = tox_new_log(nullptr, nullptr, &index[1]);
ck_assert(tox2 != nullptr);
set_random_name_and_status_message(tox2, name2, status_message2);
uint8_t address[TOX_ADDRESS_SIZE];
@ -49,7 +51,7 @@ static void test_one(void)
ck_assert_msg(ret == UINT32_MAX && error == TOX_ERR_FRIEND_ADD_OWN_KEY, "Adding own address worked.");
tox_self_get_address(tox2, address);
uint8_t message[TOX_MAX_FRIEND_REQUEST_LENGTH + 1];
uint8_t message[TOX_MAX_FRIEND_REQUEST_LENGTH + 1] = {0};
ret = tox_friend_add(tox1, address, nullptr, 0, &error);
ck_assert_msg(ret == UINT32_MAX && error == TOX_ERR_FRIEND_ADD_NULL, "Sending request with no message worked.");
ret = tox_friend_add(tox1, address, message, 0, &error);
@ -85,6 +87,7 @@ static void test_one(void)
Tox_Err_New err_n;
struct Tox_Options *options = tox_options_new(nullptr);
ck_assert(options != nullptr);
tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE);
tox_options_set_savedata_data(options, data, save_size);
tox2 = tox_new_log(options, &err_n, &index[1]);

View File

@ -1 +1 @@
c8bb5365e2cd01dab8d10a0d9c2e8f8e3be0996062151fbf95bf6304a0f1ecf1 /usr/local/bin/tox-bootstrapd
e7b6d31485b5e1561659be08f3e3ef003cef186042d7e0fe2ef48cf341932b5a /usr/local/bin/tox-bootstrapd

View File

@ -0,0 +1,24 @@
#!/bin/sh
set -eux
docker_build() {
tar c $(git ls-files) | docker build -f other/bootstrap_daemon/docker/Dockerfile -t toxchat/bootstrap-node -
}
# Run Docker build once. If it succeeds, we're good.
if docker_build; then
exit 0
fi
# We're not good. Run it again, but now capture the output.
OUTPUT=$(docker_build || true 2>&1)
if echo "$OUTPUT" | grep '/usr/local/bin/tox-bootstrapd: FAILED'; then
# This is a checksum warning, so we need to update it.
IMAGE=$(echo "$OUTPUT" | grep '^ ---> [0-9a-f]*$' | grep -o '[0-9a-f]*$' | tail -n1)
docker run --rm "$IMAGE" sha256sum /usr/local/bin/tox-bootstrapd > other/bootstrap_daemon/docker/tox-bootstrapd.sha256
fi
# Run once last time to complete the build.
docker_build

View File

@ -1,11 +1,11 @@
#include "ring_buffer.h"
#include <gtest/gtest.h>
#include <algorithm>
#include <cassert>
#include <vector>
#include <gtest/gtest.h>
namespace {
template <typename T>

View File

@ -1,9 +1,9 @@
#include "rtp.h"
#include "../toxcore/crypto_core.h"
#include <gtest/gtest.h>
#include "../toxcore/crypto_core.h"
namespace {
RTPHeader random_header() {

View File

@ -2721,6 +2721,11 @@ DHT *new_dht(const Logger *log, Mono_Time *mono_time, Networking_Core *net, bool
dht->dht_ping_array = ping_array_new(DHT_PING_ARRAY_SIZE, PING_TIMEOUT);
dht->dht_harden_ping_array = ping_array_new(DHT_PING_ARRAY_SIZE, PING_TIMEOUT);
if (dht->dht_ping_array == nullptr || dht->dht_harden_ping_array == nullptr) {
kill_dht(dht);
return nullptr;
}
for (uint32_t i = 0; i < DHT_FAKE_FRIEND_NUMBER; ++i) {
uint8_t random_public_key_bytes[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t random_secret_key_bytes[CRYPTO_SECRET_KEY_SIZE];

View File

@ -1999,8 +1999,8 @@ Messenger *new_messenger(Mono_Time *mono_time, Messenger_Options *options, unsig
m->net_crypto = new_net_crypto(m->log, m->mono_time, m->dht, &options->proxy_info);
if (m->net_crypto == nullptr) {
kill_networking(m->net);
kill_dht(m->dht);
kill_networking(m->net);
friendreq_kill(m->fr);
logger_kill(m->log);
free(m);
@ -2012,7 +2012,7 @@ Messenger *new_messenger(Mono_Time *mono_time, Messenger_Options *options, unsig
m->onion_c = new_onion_client(m->mono_time, m->net_crypto);
m->fr_c = new_friend_connections(m->mono_time, m->onion_c, options->local_discovery_enabled);
if (!(m->onion && m->onion_a && m->onion_c)) {
if (!(m->onion && m->onion_a && m->onion_c && m->fr_c)) {
kill_friend_connections(m->fr_c);
kill_onion(m->onion);
kill_onion_announce(m->onion_a);

View File

@ -12,12 +12,12 @@
#include "config.h"
#endif
#include "ccompat.h"
#include "crypto_core.h"
#include <stdlib.h>
#include <string.h>
#include "ccompat.h"
#include "crypto_core.h"
#ifndef VANILLA_NACL
/* We use libsodium by default. */
#include <sodium.h>

View File

@ -29,8 +29,6 @@
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
#include <windows.h>
#include <wincrypt.h>
#elif defined(HAVE_EXPLICIT_BZERO)
#include <string.h>
#endif
#endif

View File

@ -1,10 +1,10 @@
#include "crypto_core.h"
#include <gtest/gtest.h>
#include <algorithm>
#include <vector>
#include <gtest/gtest.h>
namespace {
enum {

View File

@ -364,6 +364,10 @@ Ping *ping_new(const Mono_Time *mono_time, DHT *dht)
void ping_kill(Ping *ping)
{
if (ping == nullptr) {
return;
}
networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_REQUEST, nullptr, nullptr);
networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_RESPONSE, nullptr, nullptr);
ping_array_kill(ping->ping_array);

View File

@ -75,6 +75,10 @@ static void clear_entry(Ping_Array *array, uint32_t index)
void ping_array_kill(Ping_Array *array)
{
if (array == nullptr) {
return;
}
while (array->last_deleted != array->last_added) {
const uint32_t index = array->last_deleted % array->total_size;
clear_entry(array, index);

View File

@ -1,8 +1,9 @@
#include "ping_array.h"
#include <gtest/gtest.h>
#include <memory>
#include <gtest/gtest.h>
#include "mono_time.h"
namespace {

View File

@ -646,6 +646,7 @@ static void end_save(uint8_t *data)
size_t tox_get_savedata_size(const Tox *tox)
{
assert(tox != nullptr);
lock(tox);
size_t ret = 2 * sizeof(uint32_t)
+ messenger_size(tox->m)
@ -657,6 +658,8 @@ size_t tox_get_savedata_size(const Tox *tox)
void tox_get_savedata(const Tox *tox, uint8_t *savedata)
{
assert(tox != nullptr);
if (savedata == nullptr) {
return;
}
@ -682,6 +685,8 @@ void tox_get_savedata(const Tox *tox, uint8_t *savedata)
bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *public_key, Tox_Err_Bootstrap *error)
{
assert(tox != nullptr);
if (!host || !public_key) {
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_NULL);
return 0;
@ -729,6 +734,8 @@ bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *pub
bool tox_add_tcp_relay(Tox *tox, const char *host, uint16_t port, const uint8_t *public_key,
Tox_Err_Bootstrap *error)
{
assert(tox != nullptr);
if (!host || !public_key) {
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_NULL);
return 0;
@ -774,6 +781,7 @@ bool tox_add_tcp_relay(Tox *tox, const char *host, uint16_t port, const uint8_t
Tox_Connection tox_self_get_connection_status(const Tox *tox)
{
assert(tox != nullptr);
lock(tox);
const unsigned int ret = onion_connection_status(tox->m->onion_c);
unlock(tox);
@ -792,11 +800,13 @@ Tox_Connection tox_self_get_connection_status(const Tox *tox)
void tox_callback_self_connection_status(Tox *tox, tox_self_connection_status_cb *callback)
{
assert(tox != nullptr);
tox->self_connection_status_callback = callback;
}
uint32_t tox_iteration_interval(const Tox *tox)
{
assert(tox != nullptr);
lock(tox);
uint32_t ret = messenger_run_interval(tox->m);
unlock(tox);
@ -805,6 +815,7 @@ uint32_t tox_iteration_interval(const Tox *tox)
void tox_iterate(Tox *tox, void *user_data)
{
assert(tox != nullptr);
lock(tox);
mono_time_update(tox->mono_time);
@ -818,6 +829,8 @@ void tox_iterate(Tox *tox, void *user_data)
void tox_self_get_address(const Tox *tox, uint8_t *address)
{
assert(tox != nullptr);
if (address) {
lock(tox);
getaddress(tox->m, address);
@ -827,6 +840,7 @@ void tox_self_get_address(const Tox *tox, uint8_t *address)
void tox_self_set_nospam(Tox *tox, uint32_t nospam)
{
assert(tox != nullptr);
lock(tox);
set_nospam(tox->m->fr, net_htonl(nospam));
unlock(tox);
@ -834,6 +848,7 @@ void tox_self_set_nospam(Tox *tox, uint32_t nospam)
uint32_t tox_self_get_nospam(const Tox *tox)
{
assert(tox != nullptr);
lock(tox);
uint32_t ret = net_ntohl(get_nospam(tox->m->fr));
unlock(tox);
@ -842,6 +857,8 @@ uint32_t tox_self_get_nospam(const Tox *tox)
void tox_self_get_public_key(const Tox *tox, uint8_t *public_key)
{
assert(tox != nullptr);
if (public_key) {
lock(tox);
memcpy(public_key, nc_get_self_public_key(tox->m->net_crypto), CRYPTO_PUBLIC_KEY_SIZE);
@ -851,6 +868,8 @@ void tox_self_get_public_key(const Tox *tox, uint8_t *public_key)
void tox_self_get_secret_key(const Tox *tox, uint8_t *secret_key)
{
assert(tox != nullptr);
if (secret_key) {
lock(tox);
memcpy(secret_key, nc_get_self_secret_key(tox->m->net_crypto), CRYPTO_SECRET_KEY_SIZE);
@ -860,6 +879,8 @@ void tox_self_get_secret_key(const Tox *tox, uint8_t *secret_key)
bool tox_self_set_name(Tox *tox, const uint8_t *name, size_t length, Tox_Err_Set_Info *error)
{
assert(tox != nullptr);
if (!name && length != 0) {
SET_ERROR_PARAMETER(error, TOX_ERR_SET_INFO_NULL);
return 0;
@ -882,6 +903,7 @@ bool tox_self_set_name(Tox *tox, const uint8_t *name, size_t length, Tox_Err_Set
size_t tox_self_get_name_size(const Tox *tox)
{
assert(tox != nullptr);
lock(tox);
size_t ret = m_get_self_name_size(tox->m);
unlock(tox);
@ -890,6 +912,8 @@ size_t tox_self_get_name_size(const Tox *tox)
void tox_self_get_name(const Tox *tox, uint8_t *name)
{
assert(tox != nullptr);
if (name) {
lock(tox);
getself_name(tox->m, name);
@ -899,6 +923,8 @@ void tox_self_get_name(const Tox *tox, uint8_t *name)
bool tox_self_set_status_message(Tox *tox, const uint8_t *status_message, size_t length, Tox_Err_Set_Info *error)
{
assert(tox != nullptr);
if (!status_message && length != 0) {
SET_ERROR_PARAMETER(error, TOX_ERR_SET_INFO_NULL);
return 0;
@ -919,6 +945,7 @@ bool tox_self_set_status_message(Tox *tox, const uint8_t *status_message, size_t
size_t tox_self_get_status_message_size(const Tox *tox)
{
assert(tox != nullptr);
lock(tox);
size_t ret = m_get_self_statusmessage_size(tox->m);
unlock(tox);
@ -927,6 +954,8 @@ size_t tox_self_get_status_message_size(const Tox *tox)
void tox_self_get_status_message(const Tox *tox, uint8_t *status_message)
{
assert(tox != nullptr);
if (status_message) {
lock(tox);
m_copy_self_statusmessage(tox->m, status_message);
@ -936,6 +965,7 @@ void tox_self_get_status_message(const Tox *tox, uint8_t *status_message)
void tox_self_set_status(Tox *tox, Tox_User_Status status)
{
assert(tox != nullptr);
lock(tox);
m_set_userstatus(tox->m, status);
unlock(tox);
@ -943,6 +973,7 @@ void tox_self_set_status(Tox *tox, Tox_User_Status status)
Tox_User_Status tox_self_get_status(const Tox *tox)
{
assert(tox != nullptr);
lock(tox);
const uint8_t status = m_get_self_userstatus(tox->m);
unlock(tox);
@ -990,6 +1021,8 @@ static void set_friend_error(const Logger *log, int32_t ret, Tox_Err_Friend_Add
uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message, size_t length,
Tox_Err_Friend_Add *error)
{
assert(tox != nullptr);
if (!address || !message) {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_NULL);
return UINT32_MAX;
@ -1011,6 +1044,8 @@ uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message
uint32_t tox_friend_add_norequest(Tox *tox, const uint8_t *public_key, Tox_Err_Friend_Add *error)
{
assert(tox != nullptr);
if (!public_key) {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_NULL);
return UINT32_MAX;
@ -1032,6 +1067,7 @@ uint32_t tox_friend_add_norequest(Tox *tox, const uint8_t *public_key, Tox_Err_F
bool tox_friend_delete(Tox *tox, uint32_t friend_number, Tox_Err_Friend_Delete *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = m_delfriend(tox->m, friend_number);
unlock(tox);
@ -1048,6 +1084,8 @@ bool tox_friend_delete(Tox *tox, uint32_t friend_number, Tox_Err_Friend_Delete *
uint32_t tox_friend_by_public_key(const Tox *tox, const uint8_t *public_key, Tox_Err_Friend_By_Public_Key *error)
{
assert(tox != nullptr);
if (!public_key) {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_BY_PUBLIC_KEY_NULL);
return UINT32_MAX;
@ -1069,6 +1107,8 @@ uint32_t tox_friend_by_public_key(const Tox *tox, const uint8_t *public_key, Tox
bool tox_friend_get_public_key(const Tox *tox, uint32_t friend_number, uint8_t *public_key,
Tox_Err_Friend_Get_Public_Key *error)
{
assert(tox != nullptr);
if (!public_key) {
return 0;
}
@ -1088,6 +1128,7 @@ bool tox_friend_get_public_key(const Tox *tox, uint32_t friend_number, uint8_t *
bool tox_friend_exists(const Tox *tox, uint32_t friend_number)
{
assert(tox != nullptr);
lock(tox);
bool ret = m_friend_exists(tox->m, friend_number);
unlock(tox);
@ -1096,6 +1137,7 @@ bool tox_friend_exists(const Tox *tox, uint32_t friend_number)
uint64_t tox_friend_get_last_online(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Get_Last_Online *error)
{
assert(tox != nullptr);
lock(tox);
const uint64_t timestamp = m_get_last_online(tox->m, friend_number);
unlock(tox);
@ -1111,6 +1153,7 @@ uint64_t tox_friend_get_last_online(const Tox *tox, uint32_t friend_number, Tox_
size_t tox_self_get_friend_list_size(const Tox *tox)
{
assert(tox != nullptr);
lock(tox);
size_t ret = count_friendlist(tox->m);
unlock(tox);
@ -1119,6 +1162,8 @@ size_t tox_self_get_friend_list_size(const Tox *tox)
void tox_self_get_friend_list(const Tox *tox, uint32_t *friend_list)
{
assert(tox != nullptr);
if (friend_list) {
lock(tox);
// TODO(irungentoo): size parameter?
@ -1129,6 +1174,7 @@ void tox_self_get_friend_list(const Tox *tox, uint32_t *friend_list)
size_t tox_friend_get_name_size(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = m_get_name_size(tox->m, friend_number);
unlock(tox);
@ -1144,6 +1190,8 @@ size_t tox_friend_get_name_size(const Tox *tox, uint32_t friend_number, Tox_Err_
bool tox_friend_get_name(const Tox *tox, uint32_t friend_number, uint8_t *name, Tox_Err_Friend_Query *error)
{
assert(tox != nullptr);
if (!name) {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_NULL);
return 0;
@ -1164,11 +1212,13 @@ bool tox_friend_get_name(const Tox *tox, uint32_t friend_number, uint8_t *name,
void tox_callback_friend_name(Tox *tox, tox_friend_name_cb *callback)
{
assert(tox != nullptr);
tox->friend_name_callback = callback;
}
size_t tox_friend_get_status_message_size(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = m_get_statusmessage_size(tox->m, friend_number);
unlock(tox);
@ -1185,6 +1235,8 @@ size_t tox_friend_get_status_message_size(const Tox *tox, uint32_t friend_number
bool tox_friend_get_status_message(const Tox *tox, uint32_t friend_number, uint8_t *status_message,
Tox_Err_Friend_Query *error)
{
assert(tox != nullptr);
if (!status_message) {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_NULL);
return false;
@ -1209,11 +1261,13 @@ bool tox_friend_get_status_message(const Tox *tox, uint32_t friend_number, uint8
void tox_callback_friend_status_message(Tox *tox, tox_friend_status_message_cb *callback)
{
assert(tox != nullptr);
tox->friend_status_message_callback = callback;
}
Tox_User_Status tox_friend_get_status(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = m_get_userstatus(tox->m, friend_number);
unlock(tox);
@ -1229,11 +1283,13 @@ Tox_User_Status tox_friend_get_status(const Tox *tox, uint32_t friend_number, To
void tox_callback_friend_status(Tox *tox, tox_friend_status_cb *callback)
{
assert(tox != nullptr);
tox->friend_status_callback = callback;
}
Tox_Connection tox_friend_get_connection_status(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = m_get_friend_connectionstatus(tox->m, friend_number);
unlock(tox);
@ -1249,11 +1305,13 @@ Tox_Connection tox_friend_get_connection_status(const Tox *tox, uint32_t friend_
void tox_callback_friend_connection_status(Tox *tox, tox_friend_connection_status_cb *callback)
{
assert(tox != nullptr);
tox->friend_connection_status_callback = callback;
}
bool tox_friend_get_typing(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = m_get_istyping(tox->m, friend_number);
unlock(tox);
@ -1269,11 +1327,13 @@ bool tox_friend_get_typing(const Tox *tox, uint32_t friend_number, Tox_Err_Frien
void tox_callback_friend_typing(Tox *tox, tox_friend_typing_cb *callback)
{
assert(tox != nullptr);
tox->friend_typing_callback = callback;
}
bool tox_self_set_typing(Tox *tox, uint32_t friend_number, bool typing, Tox_Err_Set_Typing *error)
{
assert(tox != nullptr);
lock(tox);
if (m_set_usertyping(tox->m, friend_number, typing) == -1) {
@ -1324,6 +1384,8 @@ static void set_message_error(const Logger *log, int ret, Tox_Err_Friend_Send_Me
uint32_t tox_friend_send_message(Tox *tox, uint32_t friend_number, Tox_Message_Type type, const uint8_t *message,
size_t length, Tox_Err_Friend_Send_Message *error)
{
assert(tox != nullptr);
if (!message) {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_NULL);
return 0;
@ -1344,16 +1406,19 @@ uint32_t tox_friend_send_message(Tox *tox, uint32_t friend_number, Tox_Message_T
void tox_callback_friend_read_receipt(Tox *tox, tox_friend_read_receipt_cb *callback)
{
assert(tox != nullptr);
tox->friend_read_receipt_callback = callback;
}
void tox_callback_friend_request(Tox *tox, tox_friend_request_cb *callback)
{
assert(tox != nullptr);
tox->friend_request_callback = callback;
}
void tox_callback_friend_message(Tox *tox, tox_friend_message_cb *callback)
{
assert(tox != nullptr);
tox->friend_message_callback = callback;
}
@ -1370,6 +1435,7 @@ bool tox_hash(uint8_t *hash, const uint8_t *data, size_t length)
bool tox_file_control(Tox *tox, uint32_t friend_number, uint32_t file_number, Tox_File_Control control,
Tox_Err_File_Control *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = file_control(tox->m, friend_number, file_number, control);
unlock(tox);
@ -1420,6 +1486,7 @@ bool tox_file_control(Tox *tox, uint32_t friend_number, uint32_t file_number, To
bool tox_file_seek(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position,
Tox_Err_File_Seek *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = file_seek(tox->m, friend_number, file_number, position);
unlock(tox);
@ -1462,12 +1529,15 @@ bool tox_file_seek(Tox *tox, uint32_t friend_number, uint32_t file_number, uint6
void tox_callback_file_recv_control(Tox *tox, tox_file_recv_control_cb *callback)
{
assert(tox != nullptr);
tox->file_recv_control_callback = callback;
}
bool tox_file_get_file_id(const Tox *tox, uint32_t friend_number, uint32_t file_number, uint8_t *file_id,
Tox_Err_File_Get *error)
{
assert(tox != nullptr);
if (!file_id) {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_GET_NULL);
return 0;
@ -1494,6 +1564,8 @@ bool tox_file_get_file_id(const Tox *tox, uint32_t friend_number, uint32_t file_
uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t file_size, const uint8_t *file_id,
const uint8_t *filename, size_t filename_length, Tox_Err_File_Send *error)
{
assert(tox != nullptr);
if (filename_length && !filename) {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_NULL);
return UINT32_MAX;
@ -1541,6 +1613,7 @@ uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t
bool tox_file_send_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, const uint8_t *data,
size_t length, Tox_Err_File_Send_Chunk *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = file_data(tox->m, friend_number, file_number, position, data, length);
unlock(tox);
@ -1586,51 +1659,61 @@ bool tox_file_send_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number,
void tox_callback_file_chunk_request(Tox *tox, tox_file_chunk_request_cb *callback)
{
assert(tox != nullptr);
tox->file_chunk_request_callback = callback;
}
void tox_callback_file_recv(Tox *tox, tox_file_recv_cb *callback)
{
assert(tox != nullptr);
tox->file_recv_callback = callback;
}
void tox_callback_file_recv_chunk(Tox *tox, tox_file_recv_chunk_cb *callback)
{
assert(tox != nullptr);
tox->file_recv_chunk_callback = callback;
}
void tox_callback_conference_invite(Tox *tox, tox_conference_invite_cb *callback)
{
assert(tox != nullptr);
tox->conference_invite_callback = callback;
}
void tox_callback_conference_connected(Tox *tox, tox_conference_connected_cb *callback)
{
assert(tox != nullptr);
tox->conference_connected_callback = callback;
}
void tox_callback_conference_message(Tox *tox, tox_conference_message_cb *callback)
{
assert(tox != nullptr);
tox->conference_message_callback = callback;
}
void tox_callback_conference_title(Tox *tox, tox_conference_title_cb *callback)
{
assert(tox != nullptr);
tox->conference_title_callback = callback;
}
void tox_callback_conference_peer_name(Tox *tox, tox_conference_peer_name_cb *callback)
{
assert(tox != nullptr);
tox->conference_peer_name_callback = callback;
}
void tox_callback_conference_peer_list_changed(Tox *tox, tox_conference_peer_list_changed_cb *callback)
{
assert(tox != nullptr);
tox->conference_peer_list_changed_callback = callback;
}
uint32_t tox_conference_new(Tox *tox, Tox_Err_Conference_New *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = add_groupchat(tox->m->conferences_object, GROUPCHAT_TYPE_TEXT);
unlock(tox);
@ -1646,6 +1729,7 @@ uint32_t tox_conference_new(Tox *tox, Tox_Err_Conference_New *error)
bool tox_conference_delete(Tox *tox, uint32_t conference_number, Tox_Err_Conference_Delete *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = del_groupchat(tox->m->conferences_object, conference_number, true);
unlock(tox);
@ -1661,6 +1745,7 @@ bool tox_conference_delete(Tox *tox, uint32_t conference_number, Tox_Err_Confere
uint32_t tox_conference_peer_count(const Tox *tox, uint32_t conference_number, Tox_Err_Conference_Peer_Query *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = group_number_peers(tox->m->conferences_object, conference_number, false);
unlock(tox);
@ -1677,6 +1762,7 @@ uint32_t tox_conference_peer_count(const Tox *tox, uint32_t conference_number, T
size_t tox_conference_peer_get_name_size(const Tox *tox, uint32_t conference_number, uint32_t peer_number,
Tox_Err_Conference_Peer_Query *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = group_peername_size(tox->m->conferences_object, conference_number, peer_number, false);
unlock(tox);
@ -1698,6 +1784,7 @@ size_t tox_conference_peer_get_name_size(const Tox *tox, uint32_t conference_num
bool tox_conference_peer_get_name(const Tox *tox, uint32_t conference_number, uint32_t peer_number, uint8_t *name,
Tox_Err_Conference_Peer_Query *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = group_peername(tox->m->conferences_object, conference_number, peer_number, name, false);
unlock(tox);
@ -1719,6 +1806,7 @@ bool tox_conference_peer_get_name(const Tox *tox, uint32_t conference_number, ui
bool tox_conference_peer_get_public_key(const Tox *tox, uint32_t conference_number, uint32_t peer_number,
uint8_t *public_key, Tox_Err_Conference_Peer_Query *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = group_peer_pubkey(tox->m->conferences_object, conference_number, peer_number, public_key, false);
unlock(tox);
@ -1740,6 +1828,7 @@ bool tox_conference_peer_get_public_key(const Tox *tox, uint32_t conference_numb
bool tox_conference_peer_number_is_ours(const Tox *tox, uint32_t conference_number, uint32_t peer_number,
Tox_Err_Conference_Peer_Query *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = group_peernumber_is_ours(tox->m->conferences_object, conference_number, peer_number);
unlock(tox);
@ -1765,6 +1854,7 @@ bool tox_conference_peer_number_is_ours(const Tox *tox, uint32_t conference_numb
uint32_t tox_conference_offline_peer_count(const Tox *tox, uint32_t conference_number,
Tox_Err_Conference_Peer_Query *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = group_number_peers(tox->m->conferences_object, conference_number, true);
unlock(tox);
@ -1782,6 +1872,7 @@ size_t tox_conference_offline_peer_get_name_size(const Tox *tox, uint32_t confer
uint32_t offline_peer_number,
Tox_Err_Conference_Peer_Query *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = group_peername_size(tox->m->conferences_object, conference_number, offline_peer_number, true);
unlock(tox);
@ -1804,6 +1895,7 @@ bool tox_conference_offline_peer_get_name(const Tox *tox, uint32_t conference_nu
uint8_t *name,
Tox_Err_Conference_Peer_Query *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = group_peername(tox->m->conferences_object, conference_number, offline_peer_number, name, true);
unlock(tox);
@ -1826,6 +1918,7 @@ bool tox_conference_offline_peer_get_public_key(const Tox *tox, uint32_t confere
uint32_t offline_peer_number,
uint8_t *public_key, Tox_Err_Conference_Peer_Query *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = group_peer_pubkey(tox->m->conferences_object, conference_number, offline_peer_number, public_key, true);
unlock(tox);
@ -1848,6 +1941,7 @@ uint64_t tox_conference_offline_peer_get_last_active(const Tox *tox, uint32_t co
uint32_t offline_peer_number,
Tox_Err_Conference_Peer_Query *error)
{
assert(tox != nullptr);
uint64_t last_active = UINT64_MAX;
lock(tox);
const int ret = group_frozen_last_active(tox->m->conferences_object, conference_number, offline_peer_number,
@ -1872,6 +1966,7 @@ bool tox_conference_set_max_offline(Tox *tox, uint32_t conference_number,
uint32_t max_offline_peers,
Tox_Err_Conference_Set_Max_Offline *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = group_set_max_frozen(tox->m->conferences_object, conference_number, max_offline_peers);
unlock(tox);
@ -1888,6 +1983,7 @@ bool tox_conference_set_max_offline(Tox *tox, uint32_t conference_number,
bool tox_conference_invite(Tox *tox, uint32_t friend_number, uint32_t conference_number,
Tox_Err_Conference_Invite *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = invite_friend(tox->m->conferences_object, friend_number, conference_number);
unlock(tox);
@ -1913,6 +2009,7 @@ bool tox_conference_invite(Tox *tox, uint32_t friend_number, uint32_t conference
uint32_t tox_conference_join(Tox *tox, uint32_t friend_number, const uint8_t *cookie, size_t length,
Tox_Err_Conference_Join *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = join_groupchat(tox->m->conferences_object, friend_number, GROUPCHAT_TYPE_TEXT, cookie, length);
unlock(tox);
@ -1950,6 +2047,7 @@ uint32_t tox_conference_join(Tox *tox, uint32_t friend_number, const uint8_t *co
bool tox_conference_send_message(Tox *tox, uint32_t conference_number, Tox_Message_Type type, const uint8_t *message,
size_t length, Tox_Err_Conference_Send_Message *error)
{
assert(tox != nullptr);
lock(tox);
int ret = 0;
@ -1985,6 +2083,7 @@ bool tox_conference_send_message(Tox *tox, uint32_t conference_number, Tox_Messa
size_t tox_conference_get_title_size(const Tox *tox, uint32_t conference_number, Tox_Err_Conference_Title *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = group_title_get_size(tox->m->conferences_object, conference_number);
unlock(tox);
@ -2006,6 +2105,7 @@ size_t tox_conference_get_title_size(const Tox *tox, uint32_t conference_number,
bool tox_conference_get_title(const Tox *tox, uint32_t conference_number, uint8_t *title,
Tox_Err_Conference_Title *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = group_title_get(tox->m->conferences_object, conference_number, title);
unlock(tox);
@ -2027,6 +2127,7 @@ bool tox_conference_get_title(const Tox *tox, uint32_t conference_number, uint8_
bool tox_conference_set_title(Tox *tox, uint32_t conference_number, const uint8_t *title, size_t length,
Tox_Err_Conference_Title *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = group_title_send(tox->m->conferences_object, conference_number, title, length);
unlock(tox);
@ -2051,6 +2152,7 @@ bool tox_conference_set_title(Tox *tox, uint32_t conference_number, const uint8_
size_t tox_conference_get_chatlist_size(const Tox *tox)
{
assert(tox != nullptr);
lock(tox);
size_t ret = count_chatlist(tox->m->conferences_object);
unlock(tox);
@ -2059,6 +2161,7 @@ size_t tox_conference_get_chatlist_size(const Tox *tox)
void tox_conference_get_chatlist(const Tox *tox, uint32_t *chatlist)
{
assert(tox != nullptr);
lock(tox);
const size_t list_size = count_chatlist(tox->m->conferences_object);
copy_chatlist(tox->m->conferences_object, chatlist, list_size);
@ -2068,6 +2171,7 @@ void tox_conference_get_chatlist(const Tox *tox, uint32_t *chatlist)
Tox_Conference_Type tox_conference_get_type(const Tox *tox, uint32_t conference_number,
Tox_Err_Conference_Get_Type *error)
{
assert(tox != nullptr);
lock(tox);
const int ret = group_get_type(tox->m->conferences_object, conference_number);
unlock(tox);
@ -2084,6 +2188,7 @@ Tox_Conference_Type tox_conference_get_type(const Tox *tox, uint32_t conference_
/* id is TOX_CONFERENCE_ID_SIZE bytes */
bool tox_conference_get_id(const Tox *tox, uint32_t conference_number, uint8_t *id)
{
assert(tox != nullptr);
lock(tox);
bool ret = conference_get_id(tox->m->conferences_object, conference_number, id);
unlock(tox);
@ -2094,11 +2199,14 @@ bool tox_conference_get_id(const Tox *tox, uint32_t conference_number, uint8_t *
/* uid is TOX_CONFERENCE_ID_SIZE bytes */
bool tox_conference_get_uid(const Tox *tox, uint32_t conference_number, uint8_t *uid)
{
assert(tox != nullptr);
return tox_conference_get_id(tox, conference_number, uid);
}
uint32_t tox_conference_by_id(const Tox *tox, const uint8_t *id, Tox_Err_Conference_By_Id *error)
{
assert(tox != nullptr);
if (!id) {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_BY_ID_NULL);
return UINT32_MAX;
@ -2120,6 +2228,7 @@ uint32_t tox_conference_by_id(const Tox *tox, const uint8_t *id, Tox_Err_Confere
// TODO(iphydf): Delete in 0.3.0.
uint32_t tox_conference_by_uid(const Tox *tox, const uint8_t *uid, Tox_Err_Conference_By_Uid *error)
{
assert(tox != nullptr);
Tox_Err_Conference_By_Id id_error;
const uint32_t res = tox_conference_by_id(tox, uid, &id_error);
@ -2172,6 +2281,8 @@ static void set_custom_packet_error(int ret, Tox_Err_Friend_Custom_Packet *error
bool tox_friend_send_lossy_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
Tox_Err_Friend_Custom_Packet *error)
{
assert(tox != nullptr);
if (!data) {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_NULL);
return 0;
@ -2202,6 +2313,8 @@ bool tox_friend_send_lossy_packet(Tox *tox, uint32_t friend_number, const uint8_
void tox_callback_friend_lossy_packet(Tox *tox, tox_friend_lossy_packet_cb *callback)
{
assert(tox != nullptr);
/* start at PACKET_ID_RANGE_LOSSY_CUSTOM_START so ToxAV Packets are excluded */
for (uint8_t i = PACKET_ID_RANGE_LOSSY_CUSTOM_START; i <= PACKET_ID_RANGE_LOSSY_END; ++i) {
tox->friend_lossy_packet_callback_per_pktid[i] = callback;
@ -2210,6 +2323,8 @@ void tox_callback_friend_lossy_packet(Tox *tox, tox_friend_lossy_packet_cb *call
void tox_callback_friend_lossy_packet_per_pktid(Tox *tox, tox_friend_lossy_packet_cb *callback, uint8_t pktid)
{
assert(tox != nullptr);
if (pktid >= PACKET_ID_RANGE_LOSSY_START && pktid <= PACKET_ID_RANGE_LOSSY_END) {
tox->friend_lossy_packet_callback_per_pktid[pktid] = callback;
}
@ -2218,6 +2333,8 @@ void tox_callback_friend_lossy_packet_per_pktid(Tox *tox, tox_friend_lossy_packe
bool tox_friend_send_lossless_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
Tox_Err_Friend_Custom_Packet *error)
{
assert(tox != nullptr);
if (!data) {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_NULL);
return 0;
@ -2243,6 +2360,8 @@ bool tox_friend_send_lossless_packet(Tox *tox, uint32_t friend_number, const uin
void tox_callback_friend_lossless_packet(Tox *tox, tox_friend_lossless_packet_cb *callback)
{
assert(tox != nullptr);
for (uint8_t i = PACKET_ID_RANGE_LOSSLESS_CUSTOM_START; i <= PACKET_ID_RANGE_LOSSLESS_CUSTOM_END; ++i) {
tox->friend_lossless_packet_callback_per_pktid[i] = callback;
}
@ -2250,6 +2369,8 @@ void tox_callback_friend_lossless_packet(Tox *tox, tox_friend_lossless_packet_cb
void tox_callback_friend_lossless_packet_per_pktid(Tox *tox, tox_friend_lossless_packet_cb *callback, uint8_t pktid)
{
assert(tox != nullptr);
if ((pktid >= PACKET_ID_RANGE_LOSSLESS_CUSTOM_START && pktid <= PACKET_ID_RANGE_LOSSLESS_CUSTOM_END)
|| pktid == PACKET_ID_MSI) {
tox->friend_lossless_packet_callback_per_pktid[pktid] = callback;
@ -2258,6 +2379,8 @@ void tox_callback_friend_lossless_packet_per_pktid(Tox *tox, tox_friend_lossless
void tox_self_get_dht_id(const Tox *tox, uint8_t *dht_id)
{
assert(tox != nullptr);
if (dht_id) {
lock(tox);
memcpy(dht_id, dht_get_self_public_key(tox->m->dht), CRYPTO_PUBLIC_KEY_SIZE);
@ -2267,6 +2390,7 @@ void tox_self_get_dht_id(const Tox *tox, uint8_t *dht_id)
void tox_set_av_object(Tox *tox, void *object)
{
assert(tox != nullptr);
lock(tox);
tox->toxav_object = object;
unlock(tox);
@ -2274,6 +2398,7 @@ void tox_set_av_object(Tox *tox, void *object)
void *tox_get_av_object(const Tox *tox)
{
assert(tox != nullptr);
lock(tox);
void *object = tox->toxav_object;
unlock(tox);
@ -2282,6 +2407,7 @@ void *tox_get_av_object(const Tox *tox)
uint16_t tox_self_get_udp_port(const Tox *tox, Tox_Err_Get_Port *error)
{
assert(tox != nullptr);
lock(tox);
const uint16_t port = net_htons(net_port(tox->m->net));
unlock(tox);
@ -2297,6 +2423,7 @@ uint16_t tox_self_get_udp_port(const Tox *tox, Tox_Err_Get_Port *error)
uint16_t tox_self_get_tcp_port(const Tox *tox, Tox_Err_Get_Port *error)
{
assert(tox != nullptr);
lock(tox);
if (tox->m->tcp_server) {

View File

@ -1,9 +1,9 @@
#include "util.h"
#include "crypto_core.h"
#include <gtest/gtest.h>
#include "crypto_core.h"
namespace {
TEST(Util, TwoRandomIdsAreNotEqual) {