From dda45b0493d570ae45994c30b6ecae6cbbbda2bf Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Fri, 9 Jul 2021 11:51:41 +0100 Subject: [PATCH 1/2] glocalfileinfo: Fix a typo in a file time utility function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code appears to be dealing with time in units of 100ns, not 100µs, so name the variable accordingly. The rest of the arithmetic in that function appears consistent and correct. Signed-off-by: Philip Withnall --- gio/glocalfileinfo.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c index 33c224186..1b794a7fb 100644 --- a/gio/glocalfileinfo.c +++ b/gio/glocalfileinfo.c @@ -2440,7 +2440,7 @@ _g_win32_unix_time_to_filetime (gint64 ut, { gint64 result; /* 1 unit of FILETIME is 100ns */ - const gint64 hundreds_of_usec_per_sec = 10000000; + const gint64 hundreds_of_nsec_per_sec = 10000000; /* The difference between January 1, 1601 UTC (FILETIME epoch) and UNIX epoch * in hundreds of nanoseconds. */ @@ -2465,7 +2465,7 @@ _g_win32_unix_time_to_filetime (gint64 ut, return FALSE; } - if (nsec >= hundreds_of_usec_per_sec * 100) + if (nsec >= hundreds_of_nsec_per_sec * 100) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, @@ -2474,8 +2474,8 @@ _g_win32_unix_time_to_filetime (gint64 ut, return FALSE; } - if (ut >= (G_MAXINT64 / hundreds_of_usec_per_sec) || - (ut * hundreds_of_usec_per_sec) >= (G_MAXINT64 - filetime_unix_epoch_offset)) + if (ut >= (G_MAXINT64 / hundreds_of_nsec_per_sec) || + (ut * hundreds_of_nsec_per_sec) >= (G_MAXINT64 - filetime_unix_epoch_offset)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, @@ -2484,7 +2484,7 @@ _g_win32_unix_time_to_filetime (gint64 ut, return FALSE; } - result = ut * hundreds_of_usec_per_sec + filetime_unix_epoch_offset + nsec / 100; + result = ut * hundreds_of_nsec_per_sec + filetime_unix_epoch_offset + nsec / 100; if (result >= max_systemtime || result < 0) { From 7e8163b30bd499cf5115a4a785230fa880076edb Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Fri, 9 Jul 2021 12:00:31 +0100 Subject: [PATCH 2/2] glocalfileinfo: Fix usec/nsec confusion with filetimes on Windows The function which calls `SetFileTime()` works with seconds and nanosecond, but the functions which call it are doing so with seconds and microseconds. Fix them so they convert to nanoseconds first. Signed-off-by: Philip Withnall --- gio/glocalfileinfo.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c index 1b794a7fb..6695fc1df 100644 --- a/gio/glocalfileinfo.c +++ b/gio/glocalfileinfo.c @@ -2512,6 +2512,7 @@ set_mtime_atime (const char *filename, BOOL res; guint64 val = 0; guint32 val_usec = 0; + guint32 val_nsec = 0; gunichar2 *filename_utf16; SECURITY_ATTRIBUTES sec = { sizeof (SECURITY_ATTRIBUTES), NULL, FALSE }; HANDLE file_handle; @@ -2529,8 +2530,14 @@ set_mtime_atime (const char *filename, val_usec = 0; if (atime_usec_value && !get_uint32 (atime_usec_value, &val_usec, error)) - return FALSE; - if (!_g_win32_unix_time_to_filetime (val, val_usec, &atime, error)) + return FALSE; + + /* Convert to nanoseconds. Clamp the usec value if it’s going to overflow, + * as %G_MAXINT32 will trigger a ‘too big’ error in + * _g_win32_unix_time_to_filetime() anyway. */ + val_nsec = (val_usec > G_MAXINT32 / 1000) ? G_MAXINT32 : (val_usec * 1000); + + if (!_g_win32_unix_time_to_filetime (val, val_nsec, &atime, error)) return FALSE; p_atime = &atime; } @@ -2543,8 +2550,14 @@ set_mtime_atime (const char *filename, val_usec = 0; if (mtime_usec_value && !get_uint32 (mtime_usec_value, &val_usec, error)) - return FALSE; - if (!_g_win32_unix_time_to_filetime (val, val_usec, &mtime, error)) + return FALSE; + + /* Convert to nanoseconds. Clamp the usec value if it’s going to overflow, + * as %G_MAXINT32 will trigger a ‘too big’ error in + * _g_win32_unix_time_to_filetime() anyway. */ + val_nsec = (val_usec > G_MAXINT32 / 1000) ? G_MAXINT32 : (val_usec * 1000); + + if (!_g_win32_unix_time_to_filetime (val, val_nsec, &mtime, error)) return FALSE; p_mtime = &mtime; }