mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-10-31 16:32:18 +01:00 
			
		
		
		
	glocalfileinfo: Fix incorrect use of struct statx.st_mtimensec on Android
`GLocalFileStat` is a platform-specific abstraction around `struct stat` or `struct statx`. If `struct statx` is available, it will use that by preference as it has more features. `glocalfileinfo.c` was, in some places, incorrectly accessing the fields of `GLocalFileStat` directly rather than through its `_g_stat_*()` getters. While it correctly accounted for the platform-specific differences between `st_mtimensec` and `st_mtim.tv_nsec`, it hadn’t been updated to deal with `stx_mtime`. On Android, `st_mtimensec` is defined as a fallback for `st_mtim.tv_nsec` (even though it doesn’t need to be). This caused GLib to take the `st_mtimensec` code path rather than the `stx_mtime` code path, and hence try to dereference `st_mtim` in a `struct statx`. Fix that by correctly using the `_g_stat_*()` getters consistently. Signed-off-by: Philip Withnall <pwithnall@endlessos.org> Fixes: #3039
This commit is contained in:
		| @@ -131,23 +131,9 @@ _g_local_file_info_create_etag (GLocalFileStat *statbuf) | ||||
|  | ||||
|   g_return_val_if_fail (_g_stat_has_field (statbuf, G_LOCAL_FILE_STAT_FIELD_MTIME), NULL); | ||||
|  | ||||
| #if defined (G_OS_WIN32) | ||||
|   sec = statbuf->st_mtim.tv_sec; | ||||
|   usec = statbuf->st_mtim.tv_nsec / 1000; | ||||
|   nsec = statbuf->st_mtim.tv_nsec; | ||||
| #else | ||||
|   sec = _g_stat_mtime (statbuf); | ||||
| #if defined (HAVE_STRUCT_STAT_ST_MTIMENSEC) | ||||
|   usec = statbuf->st_mtimensec / 1000; | ||||
|   nsec = statbuf->st_mtimensec; | ||||
| #elif defined (HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) | ||||
|   usec = _g_stat_mtim_nsec (statbuf) / 1000; | ||||
|   nsec = _g_stat_mtim_nsec (statbuf); | ||||
| #else | ||||
|   usec = 0; | ||||
|   nsec = 0; | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
|   return g_strdup_printf ("%lu:%lu:%lu", sec, usec, nsec); | ||||
| } | ||||
| @@ -1036,33 +1022,21 @@ set_info_from_stat (GFileInfo             *info, | ||||
|  | ||||
| #endif | ||||
|  | ||||
|   _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_MODIFIED, _g_stat_mtime (statbuf)); | ||||
|   _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_MODIFIED_USEC, _g_stat_mtim_nsec (statbuf) / 1000); | ||||
|   _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_MODIFIED_NSEC, _g_stat_mtim_nsec (statbuf)); | ||||
|  | ||||
| #if defined (G_OS_WIN32) | ||||
|   _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_MODIFIED, statbuf->st_mtim.tv_sec); | ||||
|   _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_MODIFIED_USEC, statbuf->st_mtim.tv_nsec / 1000); | ||||
|   _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_MODIFIED_NSEC, statbuf->st_mtim.tv_nsec); | ||||
|   _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_ACCESS, statbuf->st_atim.tv_sec); | ||||
|   _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_ACCESS_USEC, statbuf->st_atim.tv_nsec / 1000); | ||||
|   _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_ACCESS_NSEC, statbuf->st_atim.tv_nsec); | ||||
| #else | ||||
|   _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_MODIFIED, _g_stat_mtime (statbuf)); | ||||
| #if defined (HAVE_STRUCT_STAT_ST_MTIMENSEC) | ||||
|   _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_MODIFIED_USEC, statbuf->st_mtimensec / 1000); | ||||
|   _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_MODIFIED_NSEC, statbuf->st_mtimensec); | ||||
| #elif defined (HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) | ||||
|   _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_MODIFIED_USEC, _g_stat_mtim_nsec (statbuf) / 1000); | ||||
|   _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_MODIFIED_NSEC, _g_stat_mtim_nsec (statbuf)); | ||||
| #endif | ||||
|  | ||||
|   if (_g_stat_has_field (statbuf, G_LOCAL_FILE_STAT_FIELD_ATIME)) | ||||
|     { | ||||
|       _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_ACCESS, _g_stat_atime (statbuf)); | ||||
| #if defined (HAVE_STRUCT_STAT_ST_ATIMENSEC) | ||||
|       _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_ACCESS_USEC, statbuf->st_atimensec / 1000); | ||||
|       _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_ACCESS_NSEC, statbuf->st_atimensec); | ||||
| #elif defined (HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC) | ||||
|       _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_ACCESS_USEC, _g_stat_atim_nsec (statbuf) / 1000); | ||||
|       _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_ACCESS_NSEC, _g_stat_atim_nsec (statbuf)); | ||||
| #endif | ||||
|     } | ||||
| #endif | ||||
|  | ||||
| @@ -1073,14 +1047,9 @@ set_info_from_stat (GFileInfo             *info, | ||||
|    * Thank you, Microsoft! | ||||
|    */ | ||||
|   _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CHANGED, _g_stat_ctime (statbuf)); | ||||
| #if defined (HAVE_STRUCT_STAT_ST_CTIMENSEC) | ||||
|   _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CHANGED_USEC, statbuf->st_ctimensec / 1000); | ||||
|   _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CHANGED_NSEC, statbuf->st_ctimensec); | ||||
| #elif defined (HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC) | ||||
|   _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CHANGED_USEC, _g_stat_ctim_nsec (statbuf) / 1000); | ||||
|   _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CHANGED_NSEC, _g_stat_ctim_nsec (statbuf)); | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| #if defined (HAVE_STATX) | ||||
|   if (_g_stat_has_field (statbuf, G_LOCAL_FILE_STAT_FIELD_BTIME)) | ||||
|   | ||||
| @@ -328,6 +328,10 @@ inline static time_t    _g_stat_mtime     (const GLocalFileStat *buf) { return b | ||||
| inline static guint32   _g_stat_atim_nsec (const GLocalFileStat *buf) { return buf->st_atim.tv_nsec; } | ||||
| inline static guint32   _g_stat_ctim_nsec (const GLocalFileStat *buf) { return buf->st_ctim.tv_nsec; } | ||||
| inline static guint32   _g_stat_mtim_nsec (const GLocalFileStat *buf) { return buf->st_mtim.tv_nsec; } | ||||
| #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) | ||||
| inline static guint32   _g_stat_atim_nsec (const GLocalFileStat *buf) { return buf->st_atimensec; } | ||||
| inline static guint32   _g_stat_ctim_nsec (const GLocalFileStat *buf) { return buf->st_ctimensec; } | ||||
| inline static guint32   _g_stat_mtim_nsec (const GLocalFileStat *buf) { return buf->st_mtimensec; } | ||||
| #else | ||||
| inline static guint32   _g_stat_atim_nsec (const GLocalFileStat *buf) { return 0; } | ||||
| inline static guint32   _g_stat_ctim_nsec (const GLocalFileStat *buf) { return 0; } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user