fix: resolve all bug issues (#158, #163, #164, #165, #166, #167, #168, #169)

This commit is contained in:
2026-07-29 19:02:09 +02:00
parent 269ce0749b
commit 4f383cc5a5
21 changed files with 1498 additions and 385 deletions
+167 -2
View File
@@ -154,8 +154,11 @@ static void test_file_send_receive() {
memcpy(file->data->data, content, len);
file->data->size = len;
Config* cfg = config_create(str_dup(PROTOCOL_VERSION), str_dup("/tmp"), str_dup("/tmp"), false,
false, false, false, false, 0, false, 0);
Config* cfg = config_create();
EXPECT_NOT_NULL(cfg);
cfg->version = str_dup(PROTOCOL_VERSION);
cfg->send_directory = str_dup("/tmp");
cfg->receive_root_directory = str_dup("/tmp");
int p[2];
EXPECT_EQ_INT(pipe(p), 0);
@@ -261,6 +264,164 @@ static void test_file_metadata_create() {
unlink("test_meta_file.txt");
}
static void test_file_save_to_disk_path_traversal() {
/* Test that path traversal is rejected */
File* f = file_create("../etc/passwd");
EXPECT_NOT_NULL(f);
const char* content = "should not save";
f->data->data = malloc(strlen(content));
EXPECT_NOT_NULL(f->data->data);
memcpy(f->data->data, content, strlen(content));
f->data->size = strlen(content);
/* file_save_to_disk should detect path traversal and return false */
EXPECT_FALSE(file_save_to_disk("/tmp", f, NULL));
file_destroy(f);
}
static void test_file_save_to_disk_deep_traversal() {
File* f = file_create("subdir/../../etc/passwd");
EXPECT_NOT_NULL(f);
const char* content = "should not save";
f->data->data = malloc(strlen(content));
EXPECT_NOT_NULL(f->data->data);
memcpy(f->data->data, content, strlen(content));
f->data->size = strlen(content);
EXPECT_FALSE(file_save_to_disk("/tmp", f, NULL));
file_destroy(f);
}
static void test_file_send_single_calls_compression() {
File* file = file_create("test_send_comp.txt");
EXPECT_NOT_NULL(file);
const char* content = "Hello, Compressed File Transfer!";
size_t len = strlen(content);
file->data->data = malloc(len);
EXPECT_NOT_NULL(file->data->data);
memcpy(file->data->data, content, len);
file->data->size = len;
Config* cfg = config_create();
EXPECT_NOT_NULL(cfg);
cfg->version = str_dup(PROTOCOL_VERSION);
cfg->send_directory = str_dup("/tmp");
cfg->receive_root_directory = str_dup("/tmp");
cfg->use_compression = true;
cfg->compression_level = 3;
int p[2];
EXPECT_EQ_INT(pipe(p), 0);
io_set_fds(p[0], p[1]);
io_set_bwlimit(0);
pid_t pid = fork();
if (pid == 0) {
close(p[1]);
File* received = file_receive(cfg, p[0]);
close(p[0]);
bool ok = true;
if (!received)
ok = false;
else {
if (strcmp(received->path, "test_send_comp.txt") != 0)
ok = false;
if (!received->data || received->data->size != len)
ok = false;
else if (memcmp(received->data->data, content, len) != 0)
ok = false;
}
file_destroy(received);
config_delete(cfg);
_exit(ok ? 0 : 1);
} else {
close(p[0]);
bool sent = file_send_single_calls(file, p[1], false, 3, true);
close(p[1]);
int status;
waitpid(pid, &status, 0);
file_destroy(file);
config_delete(cfg);
EXPECT_TRUE(sent);
EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0);
}
}
static void test_file_send_single_calls_metadata_and_path() {
/* Create a real file on disk so we can have metadata */
const char* content = "File with metadata";
size_t len = strlen(content);
EXPECT_TRUE(to_disk("test_meta_send.txt", content, len));
struct stat st;
EXPECT_EQ_INT(stat("test_meta_send.txt", &st), 0);
File* file = file_create("test_meta_send.txt");
EXPECT_NOT_NULL(file);
file->data->size = len;
file->data->data = malloc(len);
EXPECT_NOT_NULL(file->data->data);
memcpy(file->data->data, content, len);
file->metadata = file_metadata_create(&st);
EXPECT_NOT_NULL(file->metadata);
Config* cfg = config_create();
EXPECT_NOT_NULL(cfg);
cfg->version = str_dup(PROTOCOL_VERSION);
cfg->send_directory = str_dup("/tmp");
cfg->receive_root_directory = str_dup("/tmp");
cfg->use_metadata = true;
int p[2];
EXPECT_EQ_INT(pipe(p), 0);
io_set_fds(p[0], p[1]);
io_set_bwlimit(0);
pid_t pid = fork();
if (pid == 0) {
close(p[1]);
File* received = file_receive(cfg, p[0]);
close(p[0]);
bool ok = true;
if (!received)
ok = false;
else {
if (strcmp(received->path, "test_meta_send.txt") != 0)
ok = false;
if (!received->data || received->data->size != len)
ok = false;
else if (memcmp(received->data->data, content, len) != 0)
ok = false;
if (!received->metadata)
ok = false;
}
file_destroy(received);
config_delete(cfg);
_exit(ok ? 0 : 1);
} else {
close(p[0]);
bool sent = file_send_single_calls(file, p[1], true, 0, true);
close(p[1]);
int status;
waitpid(pid, &status, 0);
file_destroy(file);
config_delete(cfg);
unlink("test_meta_send.txt");
EXPECT_TRUE(sent);
EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0);
}
}
void test_file() {
test_file_create();
test_file_destroy_null();
@@ -271,6 +432,8 @@ void test_file() {
test_to_disk_basic();
test_to_disk_creates_dirs();
test_file_content_to_buffer();
test_file_save_to_disk_path_traversal();
test_file_save_to_disk_deep_traversal();
if (!is_running_under_valgrind()) {
// Fork tests are skipped under valgrind because the parent process runs
// orders of magnitude slower than the child (parent is instrumented, child
@@ -279,6 +442,8 @@ void test_file() {
// forked children where inherited allocations are reported as leaks.
test_file_send_receive();
test_file_send_no_path();
test_file_send_single_calls_compression();
test_file_send_single_calls_metadata_and_path();
}
test_file_metadata_create();
}