From a7f2260203befb7e9c70b585219f0f0b5ca57703 Mon Sep 17 00:00:00 2001 From: Cheolhee Lee Date: Tue, 29 Sep 2026 11:18:58 +0900 Subject: [PATCH] fix(clipboard): unix, don't wrap FILETIMEs past 2554 (#16385) --- libs/clipboard/src/platform/unix/filetype.rs | 12 ++++++++++-- libs/clipboard/src/platform/unix/local_file.rs | 9 ++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/libs/clipboard/src/platform/unix/filetype.rs b/libs/clipboard/src/platform/unix/filetype.rs index aa66d331b..2ff48174e 100644 --- a/libs/clipboard/src/platform/unix/filetype.rs +++ b/libs/clipboard/src/platform/unix/filetype.rs @@ -168,8 +168,11 @@ impl FileDescription { let valid_write_time = flags & FLAGS_FD_LAST_WRITE != 0; let last_modified = if valid_write_time && last_write_time >= LDAP_EPOCH_DELTA { - let last_write_time = (last_write_time - LDAP_EPOCH_DELTA) * 100; - let last_write_time = Duration::from_nanos(last_write_time); + let last_write_time = last_write_time - LDAP_EPOCH_DELTA; + let last_write_time = Duration::new( + last_write_time / 10_000_000, + (last_write_time % 10_000_000) as u32 * 100, + ); SystemTime::UNIX_EPOCH + last_write_time } else { SystemTime::UNIX_EPOCH @@ -340,6 +343,11 @@ mod tests { parse_last_write_time(133_444_736_000_000_000), SystemTime::UNIX_EPOCH + Duration::from_secs(1_700_000_000) ); + // 3000-01-01 00:00:00 UTC + assert_eq!( + parse_last_write_time(441_481_536_000_000_000), + SystemTime::UNIX_EPOCH + Duration::from_secs(32_503_680_000) + ); // 1969-12-31 23:59:59 UTC falls back to the Unix epoch. assert_eq!( parse_last_write_time(116_444_736_000_000_000 - 10_000_000), diff --git a/libs/clipboard/src/platform/unix/local_file.rs b/libs/clipboard/src/platform/unix/local_file.rs index 202bd5ac8..1aff129ed 100644 --- a/libs/clipboard/src/platform/unix/local_file.rs +++ b/libs/clipboard/src/platform/unix/local_file.rs @@ -160,12 +160,12 @@ impl LocalFile { | archive_flag | normal_flag; - let win32_time = self + let win32_time = (self .last_write_time .duration_since(std::time::UNIX_EPOCH) .unwrap_or_default() - .as_nanos() as u64 - / 100 + .as_nanos() + / 100) as u64 + LDAP_EPOCH_DELTA; let size_high = (self.size >> 32) as u32; @@ -511,6 +511,9 @@ mod file_list_test { // 2023-11-14 22:13:20 UTC let time = SystemTime::UNIX_EPOCH + Duration::from_secs(1_700_000_000); assert_eq!(encoded_last_write_time(time)?, 133_444_736_000_000_000); + // 3000-01-01 00:00:00 UTC + let time = SystemTime::UNIX_EPOCH + Duration::from_secs(32_503_680_000); + assert_eq!(encoded_last_write_time(time)?, 441_481_536_000_000_000); // Times before 1970 are sent as 1970-01-01 00:00:00 UTC. let time = SystemTime::UNIX_EPOCH - Duration::from_secs(1); assert_eq!(encoded_last_write_time(time)?, 116_444_736_000_000_000);