1
0
mirror of https://github.com/libuv/libuv synced 2025-03-28 21:13:16 +00:00

win: fix fs.c ubsan failure (#4491)

Refactor / cleanup arithmetic for unix -> win filetime conversion
in order to avoid multiplication overflow.

Fixes:
```
src/win/fs.c:106:48: runtime error: signed integer overflow: 1702781567 * 10 cannot be represented in type 'long'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/win/fs.c:106:48 in
```

Co-authored-by: Jameson Nash <vtjnash@gmail.com>
This commit is contained in:
Matheus Izvekov 2024-08-07 12:01:07 -03:00 committed by GitHub
parent e78e29c231
commit 5537d6a689
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -108,13 +108,14 @@
return; \ return; \
} }
#define MILLION ((int64_t) 1000 * 1000) #define NSEC_PER_TICK 100
#define BILLION ((int64_t) 1000 * 1000 * 1000) #define TICKS_PER_SEC ((int64_t) 1e9 / NSEC_PER_TICK)
static const int64_t WIN_TO_UNIX_TICK_OFFSET = 11644473600 * TICKS_PER_SEC;
static void uv__filetime_to_timespec(uv_timespec_t *ts, int64_t filetime) { static void uv__filetime_to_timespec(uv_timespec_t *ts, int64_t filetime) {
filetime -= 116444736 * BILLION; filetime -= WIN_TO_UNIX_TICK_OFFSET;
ts->tv_sec = (long) (filetime / (10 * MILLION)); ts->tv_sec = filetime / TICKS_PER_SEC;
ts->tv_nsec = (long) ((filetime - ts->tv_sec * 10 * MILLION) * 100U); ts->tv_nsec = (filetime % TICKS_PER_SEC) * NSEC_PER_TICK;
if (ts->tv_nsec < 0) { if (ts->tv_nsec < 0) {
ts->tv_sec -= 1; ts->tv_sec -= 1;
ts->tv_nsec += 1e9; ts->tv_nsec += 1e9;
@ -123,7 +124,7 @@ static void uv__filetime_to_timespec(uv_timespec_t *ts, int64_t filetime) {
#define TIME_T_TO_FILETIME(time, filetime_ptr) \ #define TIME_T_TO_FILETIME(time, filetime_ptr) \
do { \ do { \
int64_t bigtime = ((time) * 10 * MILLION + 116444736 * BILLION); \ int64_t bigtime = ((time) * TICKS_PER_SEC + WIN_TO_UNIX_TICK_OFFSET); \
(filetime_ptr)->dwLowDateTime = (uint64_t) bigtime & 0xFFFFFFFF; \ (filetime_ptr)->dwLowDateTime = (uint64_t) bigtime & 0xFFFFFFFF; \
(filetime_ptr)->dwHighDateTime = (uint64_t) bigtime >> 32; \ (filetime_ptr)->dwHighDateTime = (uint64_t) bigtime >> 32; \
} while(0) } while(0)