Merge remaining 4 PRs: memory safety, refactoring, test coverage, integration cleanup #93

Merged
TapTap merged 37 commits from merge-all into main 2026-07-21 16:08:39 +02:00
9 changed files with 57 additions and 19 deletions
Showing only changes of commit 60ab410a8c - Show all commits
+6 -2
View File
@@ -70,10 +70,14 @@ int main(int argc, char* argv[]) {
save_to_disk = true; save_to_disk = true;
} }
Config* config = config_create(str_dup(PROTOCOL_VERSION), NULL, NULL, save_to_disk, false, false,
false, false, 5, false, 0);
int exit_code = 0; int exit_code = 0;
bool config_owned_by_pipeline = false; bool config_owned_by_pipeline = false;
Config* config = config_create(str_dup(PROTOCOL_VERSION), NULL, NULL, save_to_disk, false, false,
false, false, 5, false, 0);
if (config == NULL) {
exit_code = 1;
goto cleanup;
}
int positional_args[2]; int positional_args[2];
int positional_count = 0; int positional_count = 0;
+13 -1
View File
@@ -91,7 +91,19 @@ DirectoryScanner* directory_scanner_create_full(char* root_directory, bool use_m
scanner->max_size = max_size; scanner->max_size = max_size;
scanner->min_size = min_size; scanner->min_size = min_size;
scanner->follow_symlinks = follow_symlinks; scanner->follow_symlinks = follow_symlinks;
queue_enqueue(scanner->directories, str_dup(root_directory)); char* root_copy = str_dup(root_directory);
if (root_copy == NULL) {
for (int i = 0; i < scanner->include_count; i++)
free(scanner->include_patterns[i]);
free(scanner->include_patterns);
for (int i = 0; i < scanner->exclude_count; i++)
free(scanner->exclude_patterns[i]);
free(scanner->exclude_patterns);
queue_destroy(scanner->directories);
free(scanner);
return NULL;
}
queue_enqueue(scanner->directories, root_copy);
return scanner; return scanner;
} }
+2 -3
View File
@@ -247,10 +247,9 @@ int main(int argc, char* argv[]) {
server_listen(g_server, handler); server_listen(g_server, handler);
} }
/* Graceful shutdown: if a signal requested cleanup, delete the server */ /* Graceful shutdown: delete the server */
if (g_server_cleanup_requested) { if (g_server_cleanup_requested)
log_message(LOG_LEVEL_INFO, "Shutdown requested, cleaning up"); log_message(LOG_LEVEL_INFO, "Shutdown requested, cleaning up");
server_delete(&g_server); server_delete(&g_server);
}
return 0; return 0;
} }
+12 -8
View File
@@ -82,6 +82,8 @@ void config_parse_ssh_dest(Config* config) {
} }
void config_delete(Config* config) { void config_delete(Config* config) {
if (config == NULL)
return;
free(config->version); free(config->version);
free(config->send_directory); free(config->send_directory);
free(config->receive_root_directory); free(config->receive_root_directory);
@@ -260,10 +262,6 @@ Config* config_receive(int file_descriptor) {
MAX_PATTERN_COUNT); MAX_PATTERN_COUNT);
goto error; goto error;
} }
if ((size_t)ec > SIZE_MAX / sizeof(char*)) {
log_message(LOG_LEVEL_ERROR, "Exclude pattern count %d would cause integer overflow", ec);
goto error;
}
config->exclude_count = ec; config->exclude_count = ec;
if (ec > 0) { if (ec > 0) {
config->exclude_patterns = malloc((size_t)ec * sizeof(char*)); config->exclude_patterns = malloc((size_t)ec * sizeof(char*));
@@ -293,10 +291,6 @@ Config* config_receive(int file_descriptor) {
MAX_PATTERN_COUNT); MAX_PATTERN_COUNT);
goto error; goto error;
} }
if ((size_t)ic > SIZE_MAX / sizeof(char*)) {
log_message(LOG_LEVEL_ERROR, "Include pattern count %d would cause integer overflow", ic);
goto error;
}
config->include_count = ic; config->include_count = ic;
if (ic > 0) { if (ic > 0) {
config->include_patterns = malloc((size_t)ic * sizeof(char*)); config->include_patterns = malloc((size_t)ic * sizeof(char*));
@@ -340,6 +334,16 @@ error:
free(config->version); free(config->version);
free(config->send_directory); free(config->send_directory);
free(config->receive_root_directory); free(config->receive_root_directory);
for (int i = 0; i < config->exclude_count; i++)
free(config->exclude_patterns[i]);
free(config->exclude_patterns);
for (int i = 0; i < config->include_count; i++)
free(config->include_patterns[i]);
free(config->include_patterns);
free(config->tls_cert);
free(config->tls_key);
free(config->tls_ca);
free(config->ssh_destination);
free(config->server_host); free(config->server_host);
free(config); free(config);
return NULL; return NULL;
+12 -1
View File
@@ -3,6 +3,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <libgen.h> #include <libgen.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -109,6 +110,9 @@ bool file_load_data(File* file) {
size_t bytes_read = file_content_to_buffer(file); size_t bytes_read = file_content_to_buffer(file);
if (bytes_read != file->data->size) { if (bytes_read != file->data->size) {
log_message(LOG_LEVEL_ERROR, "Did not read expected amount of bytes from file"); log_message(LOG_LEVEL_ERROR, "Did not read expected amount of bytes from file");
free(file->data->data);
file->data->data = NULL;
file->data->size = 0;
return false; return false;
} }
return true; return true;
@@ -140,11 +144,13 @@ static bool file_send_streaming(File* file, int file_descriptor) {
if (ferror(fp)) { if (ferror(fp)) {
perror("Read error during streaming"); perror("Read error during streaming");
} }
send_status(file_descriptor, STATUS_ERROR);
free(buf); free(buf);
fclose(fp); fclose(fp);
return false; return false;
} }
if (!send_n_data(file_descriptor, buf, nread)) { if (!send_n_data(file_descriptor, buf, nread)) {
send_status(file_descriptor, STATUS_ERROR);
free(buf); free(buf);
fclose(fp); fclose(fp);
return false; return false;
@@ -626,8 +632,13 @@ bool file_send_sendfile(File* file, int file_descriptor, bool use_metadata, int
off_t offset = 0; off_t offset = 0;
while ((unsigned long long)offset < file_size) { while ((unsigned long long)offset < file_size) {
ssize_t sent = sendfile(file_descriptor, fd, &offset, file_size - offset); size_t send_count = (size_t)(file_size - (unsigned long long)offset);
if ((unsigned long long)send_count != file_size - (unsigned long long)offset)
send_count = SIZE_MAX;
ssize_t sent = sendfile(file_descriptor, fd, &offset, send_count);
if (sent == -1) { if (sent == -1) {
if (errno == EINTR)
continue;
perror("sendfile failed"); perror("sendfile failed");
close(fd); close(fd);
return false; return false;
+2
View File
@@ -16,6 +16,8 @@ void log_message(LogLevel log_level, const char* format, ...) {
time_t now = time(NULL); time_t now = time(NULL);
struct tm result_buf; struct tm result_buf;
const struct tm* t = localtime_r(&now, &result_buf); const struct tm* t = localtime_r(&now, &result_buf);
if (t == NULL)
return;
fprintf(stderr, "%04d-%02d-%02d %02d:%02d:%02d [%s]: ", t->tm_year + 1900, t->tm_mon + 1, fprintf(stderr, "%04d-%02d-%02d %02d:%02d:%02d [%s]: ", t->tm_year + 1900, t->tm_mon + 1,
t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, log_level_strings[log_level]); t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, log_level_strings[log_level]);
+3
View File
@@ -20,6 +20,9 @@
* serialized as fixed-width integers. * serialized as fixed-width integers.
*/ */
/* Size of metadata fields on wire, excluding the int32_t `present` field that
* is always sent first. The total wire size for present metadata is
* sizeof(int32_t) + FILE_METADATA_WIRE_SIZE (32 bytes on most platforms). */
#define FILE_METADATA_WIRE_SIZE (sizeof(int32_t) * 3 + sizeof(int64_t) * 2) #define FILE_METADATA_WIRE_SIZE (sizeof(int32_t) * 3 + sizeof(int64_t) * 2)
void metadata_to_buf(char** buf, const FileMetadata* m); void metadata_to_buf(char** buf, const FileMetadata* m);
+1 -1
View File
@@ -10,7 +10,7 @@
static __thread int io_read_fd = -1; static __thread int io_read_fd = -1;
static __thread int io_write_fd = -1; static __thread int io_write_fd = -1;
static SSL* io_ssl = NULL; static __thread SSL* io_ssl = NULL;
static unsigned long long io_bwlimit = 0; static unsigned long long io_bwlimit = 0;
static long long bw_tokens = 0; static long long bw_tokens = 0;
+5 -2
View File
@@ -119,10 +119,13 @@ Client* client_connect_ssh(const char* destination, int port) {
close(sv[1]); close(sv[1]);
char ssh_user[512]; char ssh_user[512];
int needed;
if (r.user && r.user[0] != '\0') if (r.user && r.user[0] != '\0')
snprintf(ssh_user, sizeof(ssh_user), "%s@%s", r.user, r.host); needed = snprintf(ssh_user, sizeof(ssh_user), "%s@%s", r.user, r.host);
else else
snprintf(ssh_user, sizeof(ssh_user), "%s", r.host); needed = snprintf(ssh_user, sizeof(ssh_user), "%s", r.host);
if ((size_t)needed >= sizeof(ssh_user))
fprintf(stderr, "Warning: ssh_user string truncated\n");
size_t ssh_argv_max = 32; size_t ssh_argv_max = 32;
char** ssh_argv = calloc(ssh_argv_max, sizeof(char*)); char** ssh_argv = calloc(ssh_argv_max, sizeof(char*));