Merge branch 'nsec-typo' into 'main'

glocalfileinfo: Fix usec/nsec confusion with filetimes on Windows

See merge request GNOME/glib!2182
This commit is contained in:
Philip Withnall 2021-07-14 10:45:47 +00:00
commit bdbe65dd40

View File

@ -2440,7 +2440,7 @@ _g_win32_unix_time_to_filetime (gint64 ut,
{ {
gint64 result; gint64 result;
/* 1 unit of FILETIME is 100ns */ /* 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 /* The difference between January 1, 1601 UTC (FILETIME epoch) and UNIX epoch
* in hundreds of nanoseconds. * in hundreds of nanoseconds.
*/ */
@ -2465,7 +2465,7 @@ _g_win32_unix_time_to_filetime (gint64 ut,
return FALSE; 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_set_error (error, G_IO_ERROR,
G_IO_ERROR_INVALID_DATA, G_IO_ERROR_INVALID_DATA,
@ -2474,8 +2474,8 @@ _g_win32_unix_time_to_filetime (gint64 ut,
return FALSE; return FALSE;
} }
if (ut >= (G_MAXINT64 / hundreds_of_usec_per_sec) || if (ut >= (G_MAXINT64 / hundreds_of_nsec_per_sec) ||
(ut * hundreds_of_usec_per_sec) >= (G_MAXINT64 - filetime_unix_epoch_offset)) (ut * hundreds_of_nsec_per_sec) >= (G_MAXINT64 - filetime_unix_epoch_offset))
{ {
g_set_error (error, G_IO_ERROR, g_set_error (error, G_IO_ERROR,
G_IO_ERROR_INVALID_DATA, G_IO_ERROR_INVALID_DATA,
@ -2484,7 +2484,7 @@ _g_win32_unix_time_to_filetime (gint64 ut,
return FALSE; 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) if (result >= max_systemtime || result < 0)
{ {
@ -2512,6 +2512,7 @@ set_mtime_atime (const char *filename,
BOOL res; BOOL res;
guint64 val = 0; guint64 val = 0;
guint32 val_usec = 0; guint32 val_usec = 0;
guint32 val_nsec = 0;
gunichar2 *filename_utf16; gunichar2 *filename_utf16;
SECURITY_ATTRIBUTES sec = { sizeof (SECURITY_ATTRIBUTES), NULL, FALSE }; SECURITY_ATTRIBUTES sec = { sizeof (SECURITY_ATTRIBUTES), NULL, FALSE };
HANDLE file_handle; HANDLE file_handle;
@ -2530,7 +2531,13 @@ set_mtime_atime (const char *filename,
if (atime_usec_value && if (atime_usec_value &&
!get_uint32 (atime_usec_value, &val_usec, error)) !get_uint32 (atime_usec_value, &val_usec, error))
return FALSE; return FALSE;
if (!_g_win32_unix_time_to_filetime (val, val_usec, &atime, error))
/* Convert to nanoseconds. Clamp the usec value if its 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; return FALSE;
p_atime = &atime; p_atime = &atime;
} }
@ -2544,7 +2551,13 @@ set_mtime_atime (const char *filename,
if (mtime_usec_value && if (mtime_usec_value &&
!get_uint32 (mtime_usec_value, &val_usec, error)) !get_uint32 (mtime_usec_value, &val_usec, error))
return FALSE; return FALSE;
if (!_g_win32_unix_time_to_filetime (val, val_usec, &mtime, error))
/* Convert to nanoseconds. Clamp the usec value if its 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; return FALSE;
p_mtime = &mtime; p_mtime = &mtime;
} }