[glib: 2/3] glocalfileinfo: Fix usec/nsec confusion with filetimes on Windows




commit 7e8163b30bd499cf5115a4a785230fa880076edb
Author: Philip Withnall <pwithnall endlessos org>
Date:   Fri Jul 9 12:00:31 2021 +0100

    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 <pwithnall endlessos org>

 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;
     }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]