diff --git a/.circleci/cmake-ubsan b/.circleci/cmake-ubsan index 45e64d87..8275f832 100755 --- a/.circleci/cmake-ubsan +++ b/.circleci/cmake-ubsan @@ -6,6 +6,7 @@ CACHEDIR="$HOME/cache" . ".github/scripts/flags-$CC.sh" add_flag -Werror +add_flag -D_DEBUG add_flag -fdiagnostics-color=always add_flag -fno-omit-frame-pointer add_flag -fno-sanitize-recover=all diff --git a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 index 7ff16d76..b281b2b9 100644 --- a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 +++ b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 @@ -1 +1 @@ -949fc78e9b46da0ea6929c64263767b563012cc1ea0205fb89466422477326ab /usr/local/bin/tox-bootstrapd +3c31e0cef0463b0a37bb21c5322c1a219314404b2a93193f4fba49f901a9dfb6 /usr/local/bin/tox-bootstrapd diff --git a/toxcore/BUILD.bazel b/toxcore/BUILD.bazel index 52d4a69d..46d1cb40 100644 --- a/toxcore/BUILD.bazel +++ b/toxcore/BUILD.bazel @@ -369,6 +369,7 @@ cc_test( cc_fuzz_test( name = "DHT_fuzz_test", + size = "small", srcs = ["DHT_fuzz_test.cc"], corpus = ["//tools/toktok-fuzzer/corpus:DHT_fuzz_test"], deps = [ @@ -408,6 +409,7 @@ cc_library( cc_fuzz_test( name = "forwarding_fuzz_test", + size = "small", srcs = ["forwarding_fuzz_test.cc"], #corpus = ["//tools/toktok-fuzzer/corpus:forwarding_fuzz_test"], deps = [ @@ -606,6 +608,7 @@ cc_library( cc_fuzz_test( name = "group_announce_fuzz_test", + size = "small", srcs = ["group_announce_fuzz_test.cc"], #corpus = ["//tools/toktok-fuzzer/corpus:group_announce_fuzz_test"], deps = [ @@ -709,6 +712,7 @@ cc_test( cc_fuzz_test( name = "group_moderation_fuzz_test", + size = "small", srcs = ["group_moderation_fuzz_test.cc"], corpus = ["//tools/toktok-fuzzer/corpus:group_moderation_fuzz_test"], deps = [ @@ -865,6 +869,7 @@ cc_test( cc_fuzz_test( name = "tox_events_fuzz_test", + size = "small", srcs = ["tox_events_fuzz_test.cc"], corpus = ["//tools/toktok-fuzzer/corpus:tox_events_fuzz_test"], deps = [ diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index dddea120..cd1e53d9 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -757,6 +757,20 @@ int m_set_statusmessage(Messenger *m, const uint8_t *status, uint16_t length) return 0; } +static Userstatus userstatus_from_int(uint8_t status) +{ + switch (status) { + case 0: + return USERSTATUS_NONE; + case 1: + return USERSTATUS_AWAY; + case 2: + return USERSTATUS_BUSY; + default: + return USERSTATUS_INVALID; + } +} + int m_set_userstatus(Messenger *m, uint8_t status) { if (status >= USERSTATUS_INVALID) { @@ -767,7 +781,7 @@ int m_set_userstatus(Messenger *m, uint8_t status) return 0; } - m->userstatus = (Userstatus)status; + m->userstatus = userstatus_from_int(status); for (uint32_t i = 0; i < m->numfriends; ++i) { m->friendlist[i].userstatus_sent = false; @@ -923,7 +937,7 @@ static int set_friend_statusmessage(const Messenger *m, int32_t friendnumber, co non_null() static void set_friend_userstatus(const Messenger *m, int32_t friendnumber, uint8_t status) { - m->friendlist[friendnumber].userstatus = (Userstatus)status; + m->friendlist[friendnumber].userstatus = userstatus_from_int(status); } non_null() @@ -2081,9 +2095,9 @@ static int m_handle_packet_userstatus(Messenger *m, const int i, const uint8_t * return 0; } - const Userstatus status = (Userstatus)data[0]; + const Userstatus status = userstatus_from_int(data[0]); - if (status >= USERSTATUS_INVALID) { + if (status == USERSTATUS_INVALID) { return 0; } @@ -3622,7 +3636,9 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random * m->onion = new_onion(m->log, m->mem, m->mono_time, m->rng, m->dht); m->onion_a = new_onion_announce(m->log, m->mem, m->rng, m->mono_time, m->dht); m->onion_c = new_onion_client(m->log, m->mem, m->rng, m->mono_time, m->net_crypto); - m->fr_c = new_friend_connections(m->log, m->mono_time, m->ns, m->onion_c, options->local_discovery_enabled); + if (m->onion_c != nullptr) { + m->fr_c = new_friend_connections(m->log, m->mono_time, m->ns, m->onion_c, options->local_discovery_enabled); + } if ((options->dht_announcements_enabled && (m->forwarding == nullptr || m->announce == nullptr)) || m->onion == nullptr || m->onion_a == nullptr || m->onion_c == nullptr || m->fr_c == nullptr) { diff --git a/toxcore/attributes.h b/toxcore/attributes.h index 3da768f2..3d3aeda0 100644 --- a/toxcore/attributes.h +++ b/toxcore/attributes.h @@ -18,7 +18,7 @@ #define GNU_PRINTF(f, a) #endif -#if defined(__GNUC__) && defined(_DEBUG) && !defined(__OPTIMIZE__) +#if defined(__GNUC__) && defined(_DEBUG) #define non_null(...) __attribute__((__nonnull__(__VA_ARGS__))) #else #define non_null(...) diff --git a/toxcore/crypto_core_test.cc b/toxcore/crypto_core_test.cc index 9f14751d..c3c8a6f9 100644 --- a/toxcore/crypto_core_test.cc +++ b/toxcore/crypto_core_test.cc @@ -79,7 +79,8 @@ TEST(CryptoCore, Signatures) EXPECT_TRUE(create_extended_keypair(pk.data(), sk.data())); - std::vector message; + std::vector message{0}; + message.clear(); // Try a few different sizes, including empty 0 length message. for (uint8_t i = 0; i < 100; ++i) { @@ -101,7 +102,8 @@ TEST(CryptoCore, Hmac) HmacKey sk; new_hmac_key(rng, sk.data()); - std::vector message; + std::vector message{0}; + message.clear(); // Try a few different sizes, including empty 0 length message. for (uint8_t i = 0; i < 100; ++i) { diff --git a/toxcore/group_announce_test.cc b/toxcore/group_announce_test.cc index d3d5d715..4f0eac6c 100644 --- a/toxcore/group_announce_test.cc +++ b/toxcore/group_announce_test.cc @@ -50,8 +50,10 @@ TEST_F(Announces, CanBeCreatedAndDeleted) GC_Public_Announce ann{}; ann.chat_public_key[0] = 0x88; ASSERT_NE(gca_add_announce(mono_time_, gca_, &ann), nullptr); +#ifndef _DEBUG ASSERT_EQ(gca_add_announce(mono_time_, gca_, nullptr), nullptr); ASSERT_EQ(gca_add_announce(mono_time_, nullptr, &ann), nullptr); +#endif } TEST_F(Announces, AnnouncesCanTimeOut) @@ -103,7 +105,9 @@ TEST_F(Announces, AnnouncesGetAndCleanup) cleanup_gca(gca_, ann2.chat_public_key); ASSERT_EQ(gca_get_announces(gca_, &announces, 1, ann2.chat_public_key, empty_pk), 0); +#ifndef _DEBUG ASSERT_EQ(gca_get_announces(gca_, nullptr, 1, ann2.chat_public_key, empty_pk), -1); +#endif } struct AnnouncesPack : ::testing::Test { @@ -162,19 +166,23 @@ TEST_F(AnnouncesPack, PublicAnnounceCanBePackedAndUnpacked) TEST_F(AnnouncesPack, UnpackEmptyPublicAnnounce) { +#ifndef _DEBUG GC_Public_Announce ann{}; std::vector packed(GCA_PUBLIC_ANNOUNCE_MAX_SIZE); EXPECT_EQ(gca_unpack_public_announce(logger_, nullptr, 0, &ann), -1); EXPECT_EQ(gca_unpack_public_announce(logger_, packed.data(), packed.size(), nullptr), -1); +#endif } TEST_F(AnnouncesPack, PackEmptyPublicAnnounce) { +#ifndef _DEBUG GC_Public_Announce ann{}; std::vector packed(GCA_PUBLIC_ANNOUNCE_MAX_SIZE); EXPECT_EQ(gca_pack_public_announce(logger_, packed.data(), packed.size(), nullptr), -1); EXPECT_EQ(gca_pack_public_announce(logger_, nullptr, 0, &ann), -1); +#endif } TEST_F(AnnouncesPack, PublicAnnouncePackNull) @@ -198,7 +206,9 @@ TEST_F(AnnouncesPack, PublicAnnouncePackNull) TEST_F(AnnouncesPack, AnnouncesValidationCheck) { +#ifndef _DEBUG EXPECT_EQ(gca_is_valid_announce(nullptr), false); +#endif GC_Announce announce = {0}; EXPECT_EQ(gca_is_valid_announce(&announce), false); @@ -217,8 +227,10 @@ TEST_F(AnnouncesPack, UnpackIncompleteAnnouncesList) GC_Announce announce; EXPECT_EQ(gca_unpack_announces_list(logger_, data, sizeof(data), &announce, 1), -1); +#ifndef _DEBUG EXPECT_EQ(gca_unpack_announces_list(logger_, data, sizeof(data), nullptr, 1), -1); EXPECT_EQ(gca_unpack_announces_list(logger_, nullptr, 0, &announce, 1), -1); +#endif } TEST_F(AnnouncesPack, PackedAnnouncesListCanBeUnpacked) @@ -246,17 +258,21 @@ TEST_F(AnnouncesPack, PackingEmptyAnnounceFails) std::vector packed(gca_pack_announces_list_size(1)); EXPECT_EQ( gca_pack_announces_list(logger_, packed.data(), packed.size(), &announce, 1, nullptr), -1); +#ifndef _DEBUG EXPECT_EQ( gca_pack_announces_list(logger_, packed.data(), packed.size(), nullptr, 1, nullptr), -1); EXPECT_EQ(gca_pack_announces_list(logger_, nullptr, 0, &announce, 1, nullptr), -1); +#endif } TEST_F(AnnouncesPack, PackAnnounceNull) { +#ifndef _DEBUG std::vector data(GCA_ANNOUNCE_MAX_SIZE); GC_Announce announce; ASSERT_EQ(gca_pack_announce(logger_, nullptr, 0, &announce), -1); ASSERT_EQ(gca_pack_announce(logger_, data.data(), data.size(), nullptr), -1); +#endif } } // namespace diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c index 3b6d6197..e7e7422f 100644 --- a/toxcore/group_chats.c +++ b/toxcore/group_chats.c @@ -1270,8 +1270,8 @@ static uint16_t unpack_gc_shared_state(GC_SharedState *shared_state, const uint8 memcpy(&voice_state, data + len_processed, sizeof(uint8_t)); len_processed += sizeof(uint8_t); - shared_state->voice_state = (Group_Voice_State)voice_state; - shared_state->privacy_state = (Group_Privacy_State)privacy_state; + shared_state->voice_state = group_voice_state_from_int(voice_state); + shared_state->privacy_state = group_privacy_state_from_int(privacy_state); return len_processed; } @@ -7279,7 +7279,7 @@ static bool init_gc_tcp_connection(const GC_Session *c, GC_Chat *chat) /** Initializes default shared state values. */ non_null() -static void init_gc_shared_state(GC_Chat *chat, const Group_Privacy_State privacy_state) +static void init_gc_shared_state(GC_Chat *chat, Group_Privacy_State privacy_state) { chat->shared_state.maxpeers = MAX_GC_PEERS_DEFAULT; chat->shared_state.privacy_state = privacy_state; diff --git a/toxcore/group_chats.h b/toxcore/group_chats.h index 656dd471..c6a35e0b 100644 --- a/toxcore/group_chats.h +++ b/toxcore/group_chats.h @@ -162,7 +162,7 @@ uint16_t gc_get_wrapped_packet_size(uint16_t length, Net_Packet_Type packet_type * Returns -4 if the sender does not have permission to speak. * Returns -5 if the packet fails to send. */ -non_null(1, 2, 3, 4) nullable(5) +non_null(1, 2) nullable(5) int gc_send_message(const GC_Chat *chat, const uint8_t *message, uint16_t length, uint8_t type, uint32_t *message_id); diff --git a/toxcore/group_pack.c b/toxcore/group_pack.c index db41ba92..2102e37f 100644 --- a/toxcore/group_pack.c +++ b/toxcore/group_pack.c @@ -19,6 +19,32 @@ #include "ccompat.h" #include "util.h" +Group_Privacy_State group_privacy_state_from_int(uint8_t value) +{ + switch (value) { + case 0: + return GI_PUBLIC; + case 1: + return GI_PRIVATE; + default: + return GI_PUBLIC; + } +} + +Group_Voice_State group_voice_state_from_int(uint8_t value) +{ + switch (value) { + case 0: + return GV_ALL; + case 1: + return GV_MODS; + case 2: + return GV_FOUNDER; + default: + return GV_ALL; + } +} + non_null() static bool load_unpack_state_values(GC_Chat *chat, Bin_Unpack *bu) { @@ -44,8 +70,8 @@ static bool load_unpack_state_values(GC_Chat *chat, Bin_Unpack *bu) } chat->connection_state = manually_disconnected ? CS_DISCONNECTED : CS_CONNECTING; - chat->shared_state.privacy_state = (Group_Privacy_State)privacy_state; - chat->shared_state.voice_state = (Group_Voice_State)voice_state; + chat->shared_state.privacy_state = group_privacy_state_from_int(privacy_state); + chat->shared_state.voice_state = group_voice_state_from_int(voice_state); // we always load saved groups as private in case the group became private while we were offline. // this will have no detrimental effect if the group is public, as the correct privacy diff --git a/toxcore/group_pack.h b/toxcore/group_pack.h index ae831ac7..9d188407 100644 --- a/toxcore/group_pack.h +++ b/toxcore/group_pack.h @@ -32,4 +32,7 @@ void gc_save_pack_group(const GC_Chat *chat, Bin_Pack *bp); non_null() bool gc_load_unpack_group(GC_Chat *chat, Bin_Unpack *bu); +Group_Privacy_State group_privacy_state_from_int(uint8_t value); +Group_Voice_State group_voice_state_from_int(uint8_t value); + #endif // GROUP_PACK_H diff --git a/toxcore/tox_unpack.c b/toxcore/tox_unpack.c index 6508399e..e3a461d6 100644 --- a/toxcore/tox_unpack.c +++ b/toxcore/tox_unpack.c @@ -9,6 +9,17 @@ #include "bin_unpack.h" #include "ccompat.h" +static Tox_Conference_Type tox_conference_type_from_int(uint32_t value) +{ + switch (value) { + case 0: + return TOX_CONFERENCE_TYPE_TEXT; + case 1: + return TOX_CONFERENCE_TYPE_AV; + default: + return TOX_CONFERENCE_TYPE_TEXT; + } +} bool tox_unpack_conference_type(Bin_Unpack *bu, Tox_Conference_Type *val) { uint32_t u32; @@ -17,10 +28,23 @@ bool tox_unpack_conference_type(Bin_Unpack *bu, Tox_Conference_Type *val) return false; } - *val = (Tox_Conference_Type)u32; + *val = tox_conference_type_from_int(u32); return true; } +static Tox_Connection tox_connection_from_int(uint32_t value) +{ + switch (value) { + case 0: + return TOX_CONNECTION_NONE; + case 1: + return TOX_CONNECTION_TCP; + case 2: + return TOX_CONNECTION_UDP; + default: + return TOX_CONNECTION_NONE; + } +} bool tox_unpack_connection(Bin_Unpack *bu, Tox_Connection *val) { uint32_t u32; @@ -29,10 +53,23 @@ bool tox_unpack_connection(Bin_Unpack *bu, Tox_Connection *val) return false; } - *val = (Tox_Connection)u32; + *val = tox_connection_from_int(u32); return true; } +static Tox_File_Control tox_file_control_from_int(uint32_t value) +{ + switch (value) { + case 0: + return TOX_FILE_CONTROL_RESUME; + case 1: + return TOX_FILE_CONTROL_PAUSE; + case 2: + return TOX_FILE_CONTROL_CANCEL; + default: + return TOX_FILE_CONTROL_RESUME; + } +} bool tox_unpack_file_control(Bin_Unpack *bu, Tox_File_Control *val) { uint32_t u32; @@ -41,10 +78,21 @@ bool tox_unpack_file_control(Bin_Unpack *bu, Tox_File_Control *val) return false; } - *val = (Tox_File_Control)u32; + *val = tox_file_control_from_int(u32); return true; } +static Tox_Message_Type tox_message_type_from_int(uint32_t value) +{ + switch (value) { + case 0: + return TOX_MESSAGE_TYPE_NORMAL; + case 1: + return TOX_MESSAGE_TYPE_ACTION; + default: + return TOX_MESSAGE_TYPE_NORMAL; + } +} bool tox_unpack_message_type(Bin_Unpack *bu, Tox_Message_Type *val) { uint32_t u32; @@ -53,10 +101,23 @@ bool tox_unpack_message_type(Bin_Unpack *bu, Tox_Message_Type *val) return false; } - *val = (Tox_Message_Type)u32; + *val = tox_message_type_from_int(u32); return true; } +static Tox_User_Status tox_user_status_from_int(uint32_t value) +{ + switch (value) { + case 0: + return TOX_USER_STATUS_NONE; + case 1: + return TOX_USER_STATUS_AWAY; + case 2: + return TOX_USER_STATUS_BUSY; + default: + return TOX_USER_STATUS_NONE; + } +} bool tox_unpack_user_status(Bin_Unpack *bu, Tox_User_Status *val) { uint32_t u32; @@ -65,6 +126,6 @@ bool tox_unpack_user_status(Bin_Unpack *bu, Tox_User_Status *val) return false; } - *val = (Tox_User_Status)u32; + *val = tox_user_status_from_int(u32); return true; }