fix: address modify-window review findings
CI / lint (pull_request) Successful in 13s
CI / sanitizers (undefined) (pull_request) Successful in 38s
CI / sanitizers (address) (pull_request) Successful in 39s
CI / fuzz-build (pull_request) Successful in 14s
CI / coverage (pull_request) Successful in 31s
CI / build-and-test (pull_request) Successful in 1m16s
CI / valgrind (pull_request) Successful in 33s

This commit is contained in:
2026-09-03 21:54:46 +02:00
parent 0b5b1a8643
commit e37d5b9438
5 changed files with 43 additions and 2 deletions
+3 -1
View File
@@ -66,9 +66,11 @@ static bool receiver_process_batch(Config* config, int file_descriptor) {
struct stat st; struct stat st;
bool has_old = file_stat_secure(full_path, &st); bool has_old = file_stat_secure(full_path, &st);
long long old_mtime_nsec = 0; long long old_mtime_nsec = 0;
if (has_old) {
#ifdef __linux__ #ifdef __linux__
old_mtime_nsec = st.st_mtim.tv_nsec; old_mtime_nsec = st.st_mtim.tv_nsec;
#endif #endif
}
bool match = has_old && (unsigned long long)st.st_size == check_size && bool match = has_old && (unsigned long long)st.st_size == check_size &&
metadata_mtime_matches(st.st_mtime, old_mtime_nsec, (time_t)check_mtime, metadata_mtime_matches(st.st_mtime, old_mtime_nsec, (time_t)check_mtime,
(long)check_mtime_nsec, config->modify_window); (long)check_mtime_nsec, config->modify_window);
+3 -1
View File
@@ -183,9 +183,11 @@ int receive_files(Config* config, int fd) {
} }
bool has_old = full_path && file_stat_secure(full_path, &st); bool has_old = full_path && file_stat_secure(full_path, &st);
long long old_mtime_nsec = 0; long long old_mtime_nsec = 0;
if (has_old) {
#ifdef __linux__ #ifdef __linux__
old_mtime_nsec = st.st_mtim.tv_nsec; old_mtime_nsec = st.st_mtim.tv_nsec;
#endif #endif
}
bool match = has_old && (unsigned long long)st.st_size == check_size && bool match = has_old && (unsigned long long)st.st_size == check_size &&
metadata_mtime_matches(st.st_mtime, old_mtime_nsec, (time_t)check_mtime, metadata_mtime_matches(st.st_mtime, old_mtime_nsec, (time_t)check_mtime,
(long)check_mtime_nsec, config->modify_window); (long)check_mtime_nsec, config->modify_window);
+4
View File
@@ -38,6 +38,10 @@ bool metadata_mtime_matches(time_t left_sec, long left_nsec, time_t right_sec, l
seconds = right - left; seconds = right - left;
nanoseconds = (int64_t)right_nsec - (int64_t)left_nsec; nanoseconds = (int64_t)right_nsec - (int64_t)left_nsec;
} }
if (nanoseconds < 0) {
seconds--;
nanoseconds += 1000000000LL;
}
return seconds < modify_window || (seconds == modify_window && nanoseconds == 0); return seconds < modify_window || (seconds == modify_window && nanoseconds == 0);
} }
+4
View File
@@ -126,6 +126,10 @@ static void test_metadata_mtime_window() {
EXPECT_TRUE(metadata_mtime_matches(100, 100000000, 101, 600000000, 2)); EXPECT_TRUE(metadata_mtime_matches(100, 100000000, 101, 600000000, 2));
EXPECT_FALSE(metadata_mtime_matches(100, 100000000, 102, 600000000, 2)); EXPECT_FALSE(metadata_mtime_matches(100, 100000000, 102, 600000000, 2));
EXPECT_TRUE(metadata_mtime_matches(100, 100000000, 102, 100000000, 2)); EXPECT_TRUE(metadata_mtime_matches(100, 100000000, 102, 100000000, 2));
EXPECT_TRUE(metadata_mtime_matches(100, 900000000, 102, 100000000, 2));
EXPECT_FALSE(metadata_mtime_matches(100, 100000000, 102, 900000000, 2));
EXPECT_TRUE(metadata_mtime_matches(100, 900000000, 102, 900000000, 2));
EXPECT_FALSE(metadata_mtime_matches(100, 900000000, 101, 100000001, 0));
EXPECT_FALSE(metadata_mtime_matches(100, 100000000, 100, 100000001, 0)); EXPECT_FALSE(metadata_mtime_matches(100, 100000000, 100, 100000001, 0));
EXPECT_TRUE(metadata_mtime_matches(100, 100000000, 100, 100000000, 0)); EXPECT_TRUE(metadata_mtime_matches(100, 100000000, 100, 100000000, 0));
} }
+29
View File
@@ -182,11 +182,40 @@ static void test_receive_manifest_rejects_traversal() {
config_delete(cfg); config_delete(cfg);
} }
static void test_receive_incremental_check_rejects_invalid_nanoseconds() {
Config* cfg = config_create();
EXPECT_NOT_NULL(cfg);
cfg->receive_root_directory = str_dup("/tmp/dst");
int p[2];
EXPECT_EQ_INT(socketpair(AF_UNIX, SOCK_STREAM, 0, p), 0);
io_set_fds(p[0], p[1]);
EXPECT_TRUE(send_str(p[1], "file.txt"));
unsigned long long size = 0;
long long mtime = 100;
long long mtime_nsec = 1000000000LL;
EXPECT_TRUE(send_n_data(p[1], &size, sizeof(size)));
EXPECT_TRUE(send_n_data(p[1], &mtime, sizeof(mtime)));
EXPECT_TRUE(send_n_data(p[1], &mtime_nsec, sizeof(mtime_nsec)));
bool skipped = false;
EXPECT_NULL(receive_incremental_check(p[0], cfg, &skipped));
Status status;
EXPECT_TRUE(receive_status(p[1], &status));
EXPECT_EQ_INT(status, STATUS_ERROR);
EXPECT_FALSE(skipped);
close(p[0]);
close(p[1]);
config_delete(cfg);
}
void test_server() { void test_server() {
if (!is_running_under_valgrind()) { if (!is_running_under_valgrind()) {
test_receive_files_finished(); test_receive_files_finished();
test_receive_files_single_file(); test_receive_files_single_file();
test_receive_files_abort(); test_receive_files_abort();
test_receive_manifest_rejects_traversal(); test_receive_manifest_rejects_traversal();
test_receive_incremental_check_rejects_invalid_nanoseconds();
} }
} }