fix: Correct a use-after-free and fix some memory leaks.

Also: use `find_package` to find gtest. This fixes the coverage build to
include unit tests.
This commit is contained in:
iphydf 2023-12-20 23:41:22 +00:00
parent 4b1cfa3e08
commit 425216d9ec
No known key found for this signature in database
GPG Key ID: 3855DBA2D74403C9
24 changed files with 143 additions and 156 deletions

View File

@ -65,6 +65,8 @@ add_cxx_flag -Wno-c++98-compat-pedantic
add_cxx_flag -Wno-c99-extensions
# We're C-compatible, so use C style casts.
add_cxx_flag -Wno-old-style-cast
# GTest does this.
add_cxx_flag -Wno-global-constructors
# Downgrade to warning so we still see it.
add_flag -Wno-error=unreachable-code

View File

@ -14,7 +14,7 @@ add_flag --coverage
add_c_flag -fno-inline -fno-omit-frame-pointer
# Show useful stack traces on crash.
add_flag -fsanitize=undefined -fno-sanitize-recover=all
add_flag -fsanitize=undefined -fno-sanitize-recover=all -D_DEBUG
# In test code (_test.cc and libgtest), throw away all debug information.
# We only care about stack frames inside toxcore (which is C). Without this,

View File

@ -133,7 +133,7 @@ jobs:
with:
submodules: recursive
- name: Build, test, and upload coverage
run: .github/scripts/coverage-linux
run: other/docker/coverage/run
build-android:
runs-on: ubuntu-latest

View File

@ -14,8 +14,8 @@
#
################################################################################
cmake_minimum_required(VERSION 3.5)
cmake_policy(VERSION 3.5)
cmake_minimum_required(VERSION 3.16)
cmake_policy(VERSION 3.16)
project(toxcore)
list(APPEND CMAKE_MODULE_PATH ${toxcore_SOURCE_DIR}/cmake)
@ -76,6 +76,7 @@ if(APPLE)
endif()
enable_testing()
find_package(GTest)
set(CMAKE_MACOSX_RPATH ON)
@ -419,23 +420,32 @@ install_module(toxcore DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/tox)
#
################################################################################
include(CompileGTest)
function(unit_test subdir target)
add_executable(unit_${target}_test ${subdir}/${target}_test.cc)
target_link_modules(unit_${target}_test toxcore)
target_link_libraries(unit_${target}_test GTest::GTest GTest::Main)
set_target_properties(unit_${target}_test PROPERTIES COMPILE_FLAGS "${TEST_CXX_FLAGS}")
add_test(NAME ${target} COMMAND ${CROSSCOMPILING_EMULATOR} unit_${target}_test)
set_property(TEST ${target} PROPERTY ENVIRONMENT "LLVM_PROFILE_FILE=${target}.profraw")
endfunction()
# The actual unit tests follow.
#
unit_test(toxav ring_buffer)
unit_test(toxav rtp)
unit_test(toxcore DHT)
unit_test(toxcore bin_pack)
unit_test(toxcore crypto_core)
unit_test(toxcore group_announce)
unit_test(toxcore group_moderation)
unit_test(toxcore list)
unit_test(toxcore mem)
unit_test(toxcore mono_time)
unit_test(toxcore ping_array)
unit_test(toxcore tox)
unit_test(toxcore util)
if(GTEST_FOUND)
unit_test(toxav ring_buffer)
unit_test(toxav rtp)
unit_test(toxcore DHT)
unit_test(toxcore bin_pack)
unit_test(toxcore crypto_core)
unit_test(toxcore group_announce)
unit_test(toxcore group_moderation)
unit_test(toxcore list)
unit_test(toxcore mem)
unit_test(toxcore mono_time)
unit_test(toxcore ping_array)
unit_test(toxcore tox)
unit_test(toxcore util)
endif()
add_subdirectory(testing)

View File

@ -61,9 +61,13 @@ static void test_store_data(void)
ck_assert(log != nullptr);
logger_callback_log(log, print_debug_logger, nullptr, nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
ck_assert(mono_time != nullptr);
Networking_Core *net = new_networking_no_udp(log, mem, ns);
ck_assert(net != nullptr);
DHT *dht = new_dht(log, mem, rng, ns, mono_time, net, true, true);
ck_assert(dht != nullptr);
Forwarding *forwarding = new_forwarding(log, rng, mono_time, dht);
ck_assert(forwarding != nullptr);
Announcements *announce = new_announcements(log, mem, rng, mono_time, forwarding);
ck_assert(announce != nullptr);

View File

@ -7,15 +7,8 @@
#include "auto_test_support.h"
#include "check_compat.h"
static uint8_t const key[] = {
0x15, 0xE9, 0xC3, 0x09, 0xCF, 0xCB, 0x79, 0xFD,
0xDF, 0x0E, 0xBA, 0x05, 0x7D, 0xAB, 0xB4, 0x9F,
0xE1, 0x5F, 0x38, 0x03, 0xB1, 0xBF, 0xF0, 0x65,
0x36, 0xAE, 0x2E, 0x5B, 0xA5, 0xE4, 0x69, 0x0E,
};
// Try to bootstrap for 30 seconds.
#define NUM_ITERATIONS (unsigned)(30.0 / (ITERATION_INTERVAL / 1000.0))
// Try to bootstrap for 20 seconds.
#define NUM_ITERATIONS (unsigned)(20.0 / (ITERATION_INTERVAL / 1000.0))
int main(void)
{
@ -24,13 +17,12 @@ int main(void)
struct Tox_Options *opts = tox_options_new(nullptr);
tox_options_set_udp_enabled(opts, false);
tox_options_set_proxy_type(opts, TOX_PROXY_TYPE_SOCKS5);
tox_options_set_proxy_host(opts, "localhost");
tox_options_set_proxy_host(opts, "127.0.0.1");
tox_options_set_proxy_port(opts, 51724);
Tox *tox = tox_new_log(opts, nullptr, nullptr);
tox_options_free(opts);
tox_add_tcp_relay(tox, "tox.ngc.zone", 33445, key, nullptr);
tox_bootstrap(tox, "tox.ngc.zone", 33445, key, nullptr);
bootstrap_tox_live_network(tox, true);
printf("Waiting for connection...\n");

View File

@ -7,15 +7,8 @@
#include "auto_test_support.h"
#include "check_compat.h"
static uint8_t const key[] = {
0x15, 0xE9, 0xC3, 0x09, 0xCF, 0xCB, 0x79, 0xFD,
0xDF, 0x0E, 0xBA, 0x05, 0x7D, 0xAB, 0xB4, 0x9F,
0xE1, 0x5F, 0x38, 0x03, 0xB1, 0xBF, 0xF0, 0x65,
0x36, 0xAE, 0x2E, 0x5B, 0xA5, 0xE4, 0x69, 0x0E,
};
// Try to bootstrap for 30 seconds.
#define NUM_ITERATIONS (unsigned)(30.0 / (ITERATION_INTERVAL / 1000.0))
// Try to bootstrap for 20 seconds.
#define NUM_ITERATIONS (unsigned)(20.0 / (ITERATION_INTERVAL / 1000.0))
int main(void)
{
@ -24,13 +17,12 @@ int main(void)
struct Tox_Options *opts = tox_options_new(nullptr);
tox_options_set_udp_enabled(opts, true);
tox_options_set_proxy_type(opts, TOX_PROXY_TYPE_SOCKS5);
tox_options_set_proxy_host(opts, "localhost");
tox_options_set_proxy_host(opts, "127.0.0.1");
tox_options_set_proxy_port(opts, 51724);
Tox *tox = tox_new_log(opts, nullptr, nullptr);
tox_options_free(opts);
tox_add_tcp_relay(tox, "tox.ngc.zone", 33445, key, nullptr);
tox_bootstrap(tox, "tox.ngc.zone", 33445, key, nullptr);
bootstrap_tox_live_network(tox, true);
printf("Waiting for connection...");

View File

@ -42,6 +42,7 @@ static void send_message_test(AutoTox *autotoxes)
const size_t msgs_len = tox_max_message_length() + 1;
uint8_t *msgs = (uint8_t *)malloc(msgs_len);
ck_assert(msgs != nullptr);
memset(msgs, MESSAGE_FILLER, msgs_len);
Tox_Err_Friend_Send_Message errm;

View File

@ -1,62 +0,0 @@
# Find and compile the GTest library.
include(CheckCXXCompilerFlag)
include(CheckIncludeFileCXX)
message(STATUS "Checking for gtest")
# Look for the sources.
find_file(GTEST_ALL_CC gtest-all.cc PATHS
${CMAKE_SOURCE_DIR}/third_party/googletest/googletest/src
/usr/src/gtest/src
NO_DEFAULT_PATH
)
if(GTEST_ALL_CC)
# ../.. from the source file is the source root.
get_filename_component(GTEST_SRC_DIR ${GTEST_ALL_CC} DIRECTORY)
get_filename_component(GTEST_SRC_ROOT ${GTEST_SRC_DIR} DIRECTORY)
# Look for the header file.
include(CheckIncludeFileCXX)
include_directories(SYSTEM ${GTEST_SRC_ROOT}/include)
check_include_file_cxx("gtest/gtest.h" HAVE_GTEST_GTEST_H)
if(HAVE_GTEST_GTEST_H)
message(STATUS "Found gtest: ${GTEST_SRC_ROOT}")
add_library(gtest
${GTEST_SRC_DIR}/gtest-all.cc
${GTEST_SRC_DIR}/gtest_main.cc)
target_include_directories(gtest PRIVATE ${GTEST_SRC_ROOT})
# Ignore all warnings for gtest. We don't care about their implementation.
check_cxx_compiler_flag("-w" HAVE_CXX_W QUIET)
if(HAVE_CXX_W)
set_target_properties(gtest PROPERTIES COMPILE_FLAGS "-w")
endif()
set(HAVE_GTEST TRUE)
set(TEST_CXX_FLAGS "")
check_cxx_compiler_flag("-Wno-global-constructors" HAVE_CXX_W_NO_GLOBAL_CONSTRUCTORS QUIET)
if(HAVE_CXX_W_NO_GLOBAL_CONSTRUCTORS)
set(TEST_CXX_FLAGS "${TEST_CXX_FLAGS} -Wno-global-constructors")
endif()
check_cxx_compiler_flag("-Wno-zero-as-null-pointer-constant" HAVE_CXX_W_NO_ZERO_AS_NULL_POINTER_CONSTANT QUIET)
if(HAVE_CXX_W_NO_ZERO_AS_NULL_POINTER_CONSTANT)
set(TEST_CXX_FLAGS "${TEST_CXX_FLAGS} -Wno-zero-as-null-pointer-constant")
endif()
endif()
endif()
function(unit_test subdir target)
if(HAVE_GTEST)
add_executable(unit_${target}_test ${subdir}/${target}_test.cc)
target_link_modules(unit_${target}_test toxcore gtest)
set_target_properties(unit_${target}_test PROPERTIES COMPILE_FLAGS "${TEST_CXX_FLAGS}")
add_test(NAME ${target} COMMAND ${CROSSCOMPILING_EMULATOR} unit_${target}_test)
set_property(TEST ${target} PROPERTY ENVIRONMENT "LLVM_PROFILE_FILE=${target}.profraw")
endif()
endfunction()

View File

@ -1 +1 @@
f117aa0e2cf3f1b42f7e38beec55cb970025692c5753b1159aa22c6e52281393 /usr/local/bin/tox-bootstrapd
7923791feaca748f570f81dd79556c7763fa2f7611e3790129fe44ffa95cf916 /usr/local/bin/tox-bootstrapd

View File

@ -1,13 +1,15 @@
FROM toxchat/c-toxcore:sources AS src
FROM ubuntu:22.04 AS build
FROM ubuntu:20.04 AS build
RUN apt-get update && \
DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends \
ca-certificates \
clang \
cmake \
curl \
gcc \
git \
golang \
golang-1.18 \
libconfig-dev \
libgtest-dev \
libopus-dev \
@ -22,10 +24,16 @@ RUN apt-get update && \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& pip3 install --no-cache-dir gcovr
RUN ["strip", "-g",\
"/usr/lib/x86_64-linux-gnu/libgtest.a",\
"/usr/lib/x86_64-linux-gnu/libgtest_main.a"]
RUN ["curl", "-s", "https://codecov.io/bash", "-o", "/usr/local/bin/codecov"]
RUN ["chmod", "+x", "/usr/local/bin/codecov"]
ENV CC=clang \
CXX=clang++ \
PYTHONUNBUFFERED=1
PYTHONUNBUFFERED=1 \
PATH=$PATH:/usr/lib/go-1.18/bin
SHELL ["/bin/bash", "-c"]
WORKDIR /work
@ -41,26 +49,27 @@ RUN source .github/scripts/flags-coverage.sh \
-DENABLE_SHARED=OFF \
-DMIN_LOGGER_LEVEL=TRACE \
-DMUST_BUILD_TOXAV=ON \
-DNON_HERMETIC_TESTS=ON \
-DNON_HERMETIC_TESTS=OFF \
-DSTRICT_ABI=ON \
-DAUTOTEST=ON \
-DPROXY_TEST=ON \
-DUSE_IPV6=OFF \
-DTEST_TIMEOUT_SECONDS=30 \
-DTEST_TIMEOUT_SECONDS=40 \
&& cmake --build _build --parallel 8 --target install
WORKDIR /work/_build
RUN /work/proxy_server \
& ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6
RUN /work/other/proxy/proxy_server \
& (ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 || \
ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6)
WORKDIR /work/mallocfail
RUN ["git", "clone", "--depth=1", "https://github.com/ralight/mallocfail", "/work/mallocfail"]
COPY run_mallocfail /usr/local/bin/
COPY syscall_funcs.c src/
RUN gcc -fPIC -shared -O2 -g3 -Wall -Ideps/uthash -Ideps/sha3 deps/*/*.c src/*.c -o mallocfail.so -ldl -lbacktrace \
&& install mallocfail.so /usr/local/lib/mallocfail.so
WORKDIR /work/_build
COPY run_mallocfail /usr/local/bin/
RUN ["run_mallocfail", "--ctest=2", "--jobs=8"]
RUN ["gcovr", \
"--sort-percentage", \
@ -74,6 +83,4 @@ RUN ["gcovr", \
"--exclude=(.+/)?other/", \
"--exclude=(.+/)?testing/"]
FROM nginx:alpine
COPY --from=build /work/_build/html/coverage_details.html /usr/share/nginx/html/index.html
COPY --from=build /work/_build/html/ /usr/share/nginx/html/
WORKDIR /work

View File

@ -0,0 +1,5 @@
# vim:ft=dockerfile
FROM toxchat/c-toxcore:coverage AS build
FROM nginx:alpine
COPY --from=build /work/_build/html/coverage_details.html /usr/share/nginx/html/index.html
COPY --from=build /work/_build/html/ /usr/share/nginx/html/

View File

@ -1,7 +1,9 @@
#!/bin/sh
#!/usr/bin/env bash
set -eux
read -a ci_env <<<"$(bash <(curl -s https://codecov.io/env))"
docker build -t toxchat/c-toxcore:sources -f other/docker/sources/Dockerfile .
docker build -t toxchat/c-toxcore:coverage other/docker/coverage
docker run --name toxcore-coverage --rm -it -p "28192:80" toxchat/c-toxcore:coverage
docker run "${ci_env[@]}" -e CI=true --name toxcore-coverage --rm -t toxchat/c-toxcore:coverage /usr/local/bin/codecov -x "llvm-cov gcov"

View File

@ -39,8 +39,8 @@ _ENV = {
}
def run_mallocfail(tmpdir: str, timeout: float, exe: str,
iteration: int) -> bool:
def run_mallocfail(tmpdir: str, timeout: float, exe: str, iteration: int,
keep_going: bool) -> bool:
"""Run a program with mallocfail."""
print(f"\x1b[1;33mmallocfail '{exe}' run #{iteration}\x1b[0m")
hashes = os.path.join(tmpdir, _HASHES)
@ -73,7 +73,8 @@ def run_mallocfail(tmpdir: str, timeout: float, exe: str,
print(
f"\x1b[1;32mProgram '{exe}' failed to handle OOM situation cleanly\x1b[0m"
)
raise Exception("Aborting test")
if not keep_going:
raise Exception("Aborting test")
return True
@ -95,7 +96,8 @@ def find_prog(name: str) -> Tuple[Optional[str], ...]:
return path
return None
return (attempt(f"./unit_{name}_test"), attempt(f"./auto_{name}_test"))
return (attempt(f"./unit_{name}_test"),
attempt(f"auto_tests/auto_{name}_test"))
def parse_flags(args: List[str]) -> Tuple[Dict[str, str], List[str]]:
@ -110,15 +112,19 @@ def parse_flags(args: List[str]) -> Tuple[Dict[str, str], List[str]]:
return flags, exes
def loop_mallocfail(tmpdir: str, timeout: float, exe: str) -> None:
def loop_mallocfail(tmpdir: str,
timeout: float,
exe: str,
keep_going: bool = False) -> None:
i = 1
while run_mallocfail(tmpdir, timeout, exe, i):
while run_mallocfail(tmpdir, timeout, exe, i, keep_going):
i += 1
def isolated_mallocfail(timeout: int, exe: str) -> None:
with tempfile.TemporaryDirectory(prefix="mallocfail") as tmpdir:
print(f"\x1b[1;33mRunning for {exe} in isolated path {tmpdir}\x1b[0m")
os.mkdir(os.path.join(tmpdir, "auto_tests"))
shutil.copy(exe, os.path.join(tmpdir, exe))
shutil.copy(_HASHES, os.path.join(tmpdir, _HASHES))
loop_mallocfail(tmpdir, timeout, exe)
@ -149,7 +155,7 @@ def main(args: List[str]) -> None:
# such as llvm_gcov_init fail.
if os.path.exists(_PRIMER):
print(f"\x1b[1;33mPriming hashes with unit_util_test\x1b[0m")
loop_mallocfail(".", timeout, _PRIMER)
loop_mallocfail(".", timeout, _PRIMER, keep_going=True)
print(f"\x1b[1;33m--------------------------------\x1b[0m")
print(f"\x1b[1;33mStarting mallocfail for {len(exes)} programs:\x1b[0m")

8
other/docker/coverage/serve Executable file
View File

@ -0,0 +1,8 @@
#!/bin/sh
set -eux
docker build -t toxchat/c-toxcore:sources -f other/docker/sources/Dockerfile .
docker build -t toxchat/c-toxcore:coverage other/docker/coverage
docker build -t toxchat/c-toxcore:coverage-nginx -f other/docker/coverage/Dockerfile.nginx other/docker/coverage
docker run --name toxcore-coverage --rm -it -p "28192:80" toxchat/c-toxcore:coverage-nginx

View File

@ -11,7 +11,7 @@ target_link_modules(misc_tools toxcore)
#
################################################################################
if (BUILD_MISC_TESTS)
if(BUILD_MISC_TESTS)
add_executable(Messenger_test Messenger_test.c)
target_link_modules(Messenger_test toxcore misc_tools)
endif()

View File

@ -192,8 +192,11 @@ TEST(AnnounceNodes, SetAndTest)
const Memory *mem = system_memory();
Logger *log = logger_new();
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);
ASSERT_NE(net, nullptr);
DHT *dht = new_dht(log, mem, rng, ns, mono_time, net, true, true);
ASSERT_NE(dht, nullptr);

View File

@ -3595,14 +3595,14 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
if (m->net == nullptr) {
friendreq_kill(m->fr);
logger_kill(m->log);
mem_delete(mem, m);
if (error != nullptr && net_err == 1) {
LOGGER_WARNING(m->log, "network initialisation failed (no ports available)");
*error = MESSENGER_ERROR_PORT;
}
logger_kill(m->log);
mem_delete(mem, m);
return nullptr;
}
@ -3648,7 +3648,11 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
if (options->dht_announcements_enabled) {
m->forwarding = new_forwarding(m->log, m->rng, m->mono_time, m->dht);
m->announce = new_announcements(m->log, m->mem, m->rng, m->mono_time, m->forwarding);
if (m->forwarding != nullptr) {
m->announce = new_announcements(m->log, m->mem, m->rng, m->mono_time, m->forwarding);
} else {
m->announce = nullptr;
}
} else {
m->forwarding = nullptr;
m->announce = nullptr;
@ -3796,11 +3800,11 @@ void kill_messenger(Messenger *m)
clear_receipts(m, i);
}
logger_kill(m->log);
mem_delete(m->mem, m->friendlist);
friendreq_kill(m->fr);
mem_delete(m->mem, m->options.state_plugins);
logger_kill(m->log);
mem_delete(m->mem, m);
}

View File

@ -911,25 +911,27 @@ Friend_Connections *new_friend_connections(
return nullptr;
}
temp->mono_time = mono_time;
temp->logger = logger;
temp->dht = onion_get_dht(onion_c);
temp->net_crypto = onion_get_net_crypto(onion_c);
temp->onion_c = onion_c;
temp->local_discovery_enabled = local_discovery_enabled;
// Don't include default port in port range
temp->next_lan_port = TOX_PORTRANGE_FROM + 1;
new_connection_handler(temp->net_crypto, &handle_new_connections, temp);
if (temp->local_discovery_enabled) {
temp->broadcast = lan_discovery_init(ns);
if (temp->broadcast == nullptr) {
LOGGER_ERROR(logger, "could not initialise LAN discovery");
temp->local_discovery_enabled = false;
}
}
temp->mono_time = mono_time;
temp->logger = logger;
temp->dht = onion_get_dht(onion_c);
temp->net_crypto = onion_get_net_crypto(onion_c);
temp->onion_c = onion_c;
// Don't include default port in port range
temp->next_lan_port = TOX_PORTRANGE_FROM + 1;
new_connection_handler(temp->net_crypto, &handle_new_connections, temp);
return temp;
}

View File

@ -7434,6 +7434,9 @@ static int create_new_group(GC_Session *c, const uint8_t *nick, size_t nick_leng
return -1;
}
init_gc_shared_state(chat, privacy_state);
init_gc_moderation(chat);
if (!init_gc_tcp_connection(c, chat)) {
group_delete(c, chat);
return -1;
@ -7454,9 +7457,6 @@ static int create_new_group(GC_Session *c, const uint8_t *nick, size_t nick_leng
self_gc_set_confirmed(chat, true);
self_gc_set_ext_public_key(chat, chat->self_public_key);
init_gc_shared_state(chat, privacy_state);
init_gc_moderation(chat);
return group_number;
}

View File

@ -1340,8 +1340,8 @@ Networking_Core *new_networking_ex(
Ip_Ntoa ip_str;
int neterror = net_error();
char *strerror = net_new_strerror(neterror);
LOGGER_ERROR(log, "failed to bind socket: %d, %s IP: %s port_from: %u port_to: %u", neterror, strerror,
net_ip_ntoa(ip, &ip_str), port_from, port_to);
LOGGER_ERROR(log, "failed to bind socket: %d, %s IP: %s port_from: %u port_to: %u",
neterror, strerror, net_ip_ntoa(ip, &ip_str), port_from, port_to);
net_kill_strerror(strerror);
kill_networking(temp);
@ -1769,6 +1769,8 @@ bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Por
int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type)
{
assert(node != nullptr);
// Try parsing as IP address first.
IP_Port parsed = {{{0}}};
// Initialise to nullptr. In error paths, at least we initialise the out
@ -2031,7 +2033,7 @@ char *net_new_strerror(int error)
return str;
}
#else
#ifdef _GNU_SOURCE
#if defined(_GNU_SOURCE) && defined(__GLIBC__)
non_null()
static const char *net_strerror_r(int error, char *tmp, size_t tmp_size)
{

View File

@ -540,7 +540,7 @@ char *net_new_strerror(int error);
* It's valid to pass NULL as the argument, the function does nothing in this
* case.
*/
non_null()
nullable(1)
void net_kill_strerror(char *strerror);
/** @brief Initialize networking.

View File

@ -637,6 +637,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
switch (err) {
case TOX_ERR_OPTIONS_NEW_OK: {
assert(default_options != nullptr);
break;
}
@ -660,6 +661,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
if (sys->rng == nullptr || sys->ns == nullptr || sys->mem == nullptr) {
// TODO(iphydf): Not quite right, but similar.
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
tox_options_free(default_options);
return nullptr;
}
@ -717,6 +719,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
if (tox == nullptr) {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
tox_options_free(default_options);
return nullptr;
}
@ -743,8 +746,8 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
default: {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_TYPE);
tox_options_free(default_options);
mem_delete(sys->mem, tox);
tox_options_free(default_options);
return nullptr;
}
}
@ -754,8 +757,8 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
if (m_options.proxy_info.proxy_type != TCP_PROXY_NONE) {
if (tox_options_get_proxy_port(opts) == 0) {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_PORT);
tox_options_free(default_options);
mem_delete(sys->mem, tox);
tox_options_free(default_options);
return nullptr;
}
@ -771,8 +774,8 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
|| !addr_resolve_or_parse_ip(tox->sys.ns, proxy_host, &m_options.proxy_info.ip_port.ip, nullptr)) {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_HOST);
// TODO(irungentoo): TOX_ERR_NEW_PROXY_NOT_FOUND if domain.
tox_options_free(default_options);
mem_delete(sys->mem, tox);
tox_options_free(default_options);
return nullptr;
}
@ -783,8 +786,8 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
if (tox->mono_time == nullptr) {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
tox_options_free(default_options);
mem_delete(sys->mem, tox);
tox_options_free(default_options);
return nullptr;
}
@ -793,8 +796,8 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
if (tox->mutex == nullptr) {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
tox_options_free(default_options);
mem_delete(sys->mem, tox);
tox_options_free(default_options);
return nullptr;
}
@ -828,7 +831,6 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
}
mono_time_free(tox->sys.mem, tox->mono_time);
tox_options_free(default_options);
tox_unlock(tox);
if (tox->mutex != nullptr) {
@ -837,6 +839,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
mem_delete(sys->mem, tox->mutex);
mem_delete(sys->mem, tox);
tox_options_free(default_options);
return nullptr;
}
@ -844,7 +847,6 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
kill_messenger(tox->m);
mono_time_free(tox->sys.mem, tox->mono_time);
tox_options_free(default_options);
tox_unlock(tox);
if (tox->mutex != nullptr) {
@ -855,6 +857,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
mem_delete(sys->mem, tox);
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
tox_options_free(default_options);
return nullptr;
}
@ -864,7 +867,6 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
kill_messenger(tox->m);
mono_time_free(tox->sys.mem, tox->mono_time);
tox_options_free(default_options);
tox_unlock(tox);
if (tox->mutex != nullptr) {
@ -875,6 +877,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
mem_delete(sys->mem, tox);
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT);
tox_options_free(default_options);
return nullptr;
}
@ -926,12 +929,11 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
gc_callback_voice_state(tox->m, tox_group_voice_state_handler);
#endif
tox_options_free(default_options);
tox_unlock(tox);
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_OK);
tox_options_free(default_options);
return tox;
}

View File

@ -82,6 +82,13 @@ TEST(Tox, OneTest)
struct Tox_Options *options = tox_options_new(nullptr);
ASSERT_NE(options, nullptr);
tox_options_set_log_callback(options,
[](Tox *tox, Tox_Log_Level level, const char *file, uint32_t line, const char *func,
const char *message, void *user_data) {
fprintf(stderr, "[%c] %s:%d(%s): %s\n", tox_log_level_to_string(level)[0], file, line,
func, message);
});
// Higher start/end point here to avoid conflict with the LAN discovery test.
tox_options_set_start_port(options, 33545);
tox_options_set_end_port(options, 33545 + 2000);