From 937c6f15cd8a0b22c6ea644638ae06df5dff60d5 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Wed, 8 Feb 2023 09:54:54 +0000 Subject: [PATCH 1/6] gfileinfo: Document required attributes for helper getters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It doesn’t make sense to (for example) call `g_file_info_get_name()` if the `GFileInfo` doesn’t contain `G_FILE_ATTRIBUTE_STANDARD_NAME`, given that building the `GFileInfo` is typically a static process and entirely under the control of the programmer. By being this restrictive, we avoid having to return ‘unknown’ values for some of these standard APIs, particularly the numeric ones such as `g_file_info_get_size()`. If APIs like that were to work correctly in the face of a `GFileInfo` without `G_FILE_ATTRIBUTE_STANDARD_SIZE` specified, they’d have to be able to return a value to indicate the attribute is missing. Returning `0` or `G_MAXSIZE` to indicate that would be ambiguous. Signed-off-by: Philip Withnall Fixes: #2907 --- gio/gfileinfo.c | 76 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 11 deletions(-) diff --git a/gio/gfileinfo.c b/gio/gfileinfo.c index 43a73ee38..4ba4503a6 100644 --- a/gio/gfileinfo.c +++ b/gio/gfileinfo.c @@ -53,6 +53,11 @@ * g_file_info_get_attribute_byte_string().This optimization will matter * only if calling the API in a tight loop. * + * It is an error to call these accessors without specifying their required file + * attributes when creating the #GFileInfo. Use g_file_info_has_attribute() or + * g_file_info_list_attributes() to check what attributes are specified for a + * #GFileInfo. + * * #GFileAttributeMatcher allows for searching through a #GFileInfo for * attributes. **/ @@ -1490,8 +1495,8 @@ g_file_info_set_attribute_int64 (GFileInfo *info, * @info: a #GFileInfo. * * Returns the #GDateTime representing the deletion date of the file, as - * available in G_FILE_ATTRIBUTE_TRASH_DELETION_DATE. If the - * G_FILE_ATTRIBUTE_TRASH_DELETION_DATE attribute is unset, %NULL is returned. + * available in %G_FILE_ATTRIBUTE_TRASH_DELETION_DATE. If the + * %G_FILE_ATTRIBUTE_TRASH_DELETION_DATE attribute is unset, %NULL is returned. * * Returns: (nullable): a #GDateTime, or %NULL. * @@ -1530,6 +1535,9 @@ g_file_info_get_deletion_date (GFileInfo *info) * Gets a file's type (whether it is a regular file, symlink, etc). * This is different from the file's content type, see g_file_info_get_content_type(). * + * It is an error to call this if the #GFileInfo does not contain + * %G_FILE_ATTRIBUTE_STANDARD_TYPE. + * * Returns: a #GFileType for the given file. **/ GFileType @@ -1553,6 +1561,9 @@ g_file_info_get_file_type (GFileInfo *info) * * Checks if a file is hidden. * + * It is an error to call this if the #GFileInfo does not contain + * %G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN. + * * Returns: %TRUE if the file is a hidden file, %FALSE otherwise. **/ gboolean @@ -1576,6 +1587,9 @@ g_file_info_get_is_hidden (GFileInfo *info) * * Checks if a file is a backup file. * + * It is an error to call this if the #GFileInfo does not contain + * %G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP. + * * Returns: %TRUE if file is a backup file, %FALSE otherwise. **/ gboolean @@ -1599,6 +1613,9 @@ g_file_info_get_is_backup (GFileInfo *info) * * Checks if a file is a symlink. * + * It is an error to call this if the #GFileInfo does not contain + * %G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK. + * * Returns: %TRUE if the given @info is a symlink. **/ gboolean @@ -1622,6 +1639,9 @@ g_file_info_get_is_symlink (GFileInfo *info) * * Gets the name for a file. This is guaranteed to always be set. * + * It is an error to call this if the #GFileInfo does not contain + * %G_FILE_ATTRIBUTE_STANDARD_NAME. + * * Returns: (type filename) (not nullable): a string containing the file name. **/ const char * @@ -1645,6 +1665,9 @@ g_file_info_get_name (GFileInfo *info) * * Gets a display name for a file. This is guaranteed to always be set. * + * It is an error to call this if the #GFileInfo does not contain + * %G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME. + * * Returns: (not nullable): a string containing the display name. **/ const char * @@ -1668,6 +1691,9 @@ g_file_info_get_display_name (GFileInfo *info) * * Gets the edit name for a file. * + * It is an error to call this if the #GFileInfo does not contain + * %G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME. + * * Returns: a string containing the edit name. **/ const char * @@ -1691,6 +1717,9 @@ g_file_info_get_edit_name (GFileInfo *info) * * Gets the icon for a file. * + * It is an error to call this if the #GFileInfo does not contain + * %G_FILE_ATTRIBUTE_STANDARD_ICON. + * * Returns: (nullable) (transfer none): #GIcon for the given @info. **/ GIcon * @@ -1718,6 +1747,9 @@ g_file_info_get_icon (GFileInfo *info) * * Gets the symbolic icon for a file. * + * It is an error to call this if the #GFileInfo does not contain + * %G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON. + * * Returns: (nullable) (transfer none): #GIcon for the given @info. * * Since: 2.34 @@ -1747,6 +1779,9 @@ g_file_info_get_symbolic_icon (GFileInfo *info) * * Gets the file's content type. * + * It is an error to call this if the #GFileInfo does not contain + * %G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE. + * * Returns: (nullable): a string containing the file's content type, * or %NULL if unknown. **/ @@ -1773,6 +1808,9 @@ g_file_info_get_content_type (GFileInfo *info) * the %G_FILE_ATTRIBUTE_STANDARD_SIZE attribute and is converted * from #guint64 to #goffset before returning the result. * + * It is an error to call this if the #GFileInfo does not contain + * %G_FILE_ATTRIBUTE_STANDARD_SIZE. + * * Returns: a #goffset containing the file's size (in bytes). **/ goffset @@ -1798,6 +1836,10 @@ g_file_info_get_size (GFileInfo *info) * Gets the modification time of the current @info and sets it * in @result. * + * It is an error to call this if the #GFileInfo does not contain + * %G_FILE_ATTRIBUTE_TIME_MODIFIED. If %G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC is + * provided it will be used too. + * * Deprecated: 2.62: Use g_file_info_get_modification_date_time() instead, as * #GTimeVal is deprecated due to the year 2038 problem. **/ @@ -1832,9 +1874,10 @@ G_GNUC_END_IGNORE_DEPRECATIONS * Gets the modification time of the current @info and returns it as a * #GDateTime. * - * This requires the %G_FILE_ATTRIBUTE_TIME_MODIFIED attribute. If - * %G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC is provided, the resulting #GDateTime - * will have microsecond precision. + * It is an error to call this if the #GFileInfo does not contain + * %G_FILE_ATTRIBUTE_TIME_MODIFIED. If %G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC is + * provided, the resulting #GDateTime will additionally have microsecond + * precision. * * If nanosecond precision is needed, %G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC must * be queried separately using g_file_info_get_attribute_uint32(). @@ -1880,9 +1923,10 @@ g_file_info_get_modification_date_time (GFileInfo *info) * Gets the access time of the current @info and returns it as a * #GDateTime. * - * This requires the %G_FILE_ATTRIBUTE_TIME_ACCESS attribute. If - * %G_FILE_ATTRIBUTE_TIME_ACCESS_USEC is provided, the resulting #GDateTime - * will have microsecond precision. + * It is an error to call this if the #GFileInfo does not contain + * %G_FILE_ATTRIBUTE_TIME_ACCESS. If %G_FILE_ATTRIBUTE_TIME_ACCESS_USEC is + * provided, the resulting #GDateTime will additionally have microsecond + * precision. * * If nanosecond precision is needed, %G_FILE_ATTRIBUTE_TIME_ACCESS_NSEC must * be queried separately using g_file_info_get_attribute_uint32(). @@ -1928,9 +1972,10 @@ g_file_info_get_access_date_time (GFileInfo *info) * Gets the creation time of the current @info and returns it as a * #GDateTime. * - * This requires the %G_FILE_ATTRIBUTE_TIME_CREATED attribute. If - * %G_FILE_ATTRIBUTE_TIME_CREATED_USEC is provided, the resulting #GDateTime - * will have microsecond precision. + * It is an error to call this if the #GFileInfo does not contain + * %G_FILE_ATTRIBUTE_TIME_CREATED. If %G_FILE_ATTRIBUTE_TIME_CREATED_USEC is + * provided, the resulting #GDateTime will additionally have microsecond + * precision. * * If nanosecond precision is needed, %G_FILE_ATTRIBUTE_TIME_CREATED_NSEC must * be queried separately using g_file_info_get_attribute_uint32(). @@ -1975,6 +2020,9 @@ g_file_info_get_creation_date_time (GFileInfo *info) * * Gets the symlink target for a given #GFileInfo. * + * It is an error to call this if the #GFileInfo does not contain + * %G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET. + * * Returns: (nullable): a string containing the symlink target. **/ const char * @@ -1999,6 +2047,9 @@ g_file_info_get_symlink_target (GFileInfo *info) * Gets the [entity tag][gfile-etag] for a given * #GFileInfo. See %G_FILE_ATTRIBUTE_ETAG_VALUE. * + * It is an error to call this if the #GFileInfo does not contain + * %G_FILE_ATTRIBUTE_ETAG_VALUE. + * * Returns: (nullable): a string containing the value of the "etag:value" attribute. **/ const char * @@ -2023,6 +2074,9 @@ g_file_info_get_etag (GFileInfo *info) * Gets the value of the sort_order attribute from the #GFileInfo. * See %G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER. * + * It is an error to call this if the #GFileInfo does not contain + * %G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER. + * * Returns: a #gint32 containing the value of the "standard::sort_order" attribute. **/ gint32 From 2f862993cc8b43816c7353d1ebc177e137deee26 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Wed, 8 Feb 2023 09:57:51 +0000 Subject: [PATCH 2/6] gfileinfo: Fix some minor documentation typos Signed-off-by: Philip Withnall --- gio/gfileinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gio/gfileinfo.c b/gio/gfileinfo.c index 4ba4503a6..1c932bb2f 100644 --- a/gio/gfileinfo.c +++ b/gio/gfileinfo.c @@ -874,7 +874,7 @@ _g_file_info_get_attribute_value (GFileInfo *info, * @info: a #GFileInfo. * @attribute: a file attribute key. * - * Gets the value of a attribute, formatted as a string. + * Gets the value of an attribute, formatted as a string. * This escapes things as needed to make the string valid * UTF-8. * @@ -2870,7 +2870,7 @@ g_file_attribute_matcher_unref (GFileAttributeMatcher *matcher) * @matcher: a #GFileAttributeMatcher. * @attribute: a file attribute key. * - * Checks if a attribute matcher only matches a given attribute. Always + * Checks if an attribute matcher only matches a given attribute. Always * returns %FALSE if "*" was used when creating the matcher. * * Returns: %TRUE if the matcher only matches @attribute. %FALSE otherwise. From 8cee721df8e7160abc5f788ec1e286be712d1c5f Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Wed, 8 Feb 2023 10:00:43 +0000 Subject: [PATCH 3/6] gfileinfo: Remove erroneous GFileType casts from returns Looks like copy/paste errors. Signed-off-by: Philip Withnall --- gio/gfileinfo.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gio/gfileinfo.c b/gio/gfileinfo.c index 1c932bb2f..316baccf1 100644 --- a/gio/gfileinfo.c +++ b/gio/gfileinfo.c @@ -1578,7 +1578,7 @@ g_file_info_get_is_hidden (GFileInfo *info) attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN); value = g_file_info_find_value (info, attr); - return (GFileType)_g_file_attribute_value_get_boolean (value); + return _g_file_attribute_value_get_boolean (value); } /** @@ -1604,7 +1604,7 @@ g_file_info_get_is_backup (GFileInfo *info) attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP); value = g_file_info_find_value (info, attr); - return (GFileType)_g_file_attribute_value_get_boolean (value); + return _g_file_attribute_value_get_boolean (value); } /** @@ -1630,7 +1630,7 @@ g_file_info_get_is_symlink (GFileInfo *info) attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK); value = g_file_info_find_value (info, attr); - return (GFileType)_g_file_attribute_value_get_boolean (value); + return _g_file_attribute_value_get_boolean (value); } /** From ed8e86a7d41a0900d8fa57edc64264d04cf8135b Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Wed, 8 Feb 2023 10:22:27 +0000 Subject: [PATCH 4/6] gfileinfo: Add critical warnings for helper getters As documented in a previous commit, these functions should not be called without the right attributes being present in the `GFileInfo`. Add critical warnings to make this more obvious. Signed-off-by: Philip Withnall Fixes: #2907 --- gio/gfileinfo.c | 104 +++++++++++++++++------------------------------- 1 file changed, 36 insertions(+), 68 deletions(-) diff --git a/gio/gfileinfo.c b/gio/gfileinfo.c index 316baccf1..ad196d0ec 100644 --- a/gio/gfileinfo.c +++ b/gio/gfileinfo.c @@ -1490,6 +1490,21 @@ g_file_info_set_attribute_int64 (GFileInfo *info, } /* Helper getters */ +#define get_required_attribute(value_ptr, info, attribute_name, error_value) \ + G_STMT_START { \ + static guint32 attr = 0; \ +\ + if (attr == 0) \ + attr = lookup_attribute (attribute_name); \ +\ + *value_ptr = g_file_info_find_value (info, attr); \ + if (G_UNLIKELY (*value_ptr == NULL)) \ + { \ + g_critical ("GFileInfo created without " attribute_name); \ + g_return_val_if_reached (error_value); \ + } \ + } G_STMT_END + /** * g_file_info_get_deletion_date: * @info: a #GFileInfo. @@ -1543,15 +1558,11 @@ g_file_info_get_deletion_date (GFileInfo *info) GFileType g_file_info_get_file_type (GFileInfo *info) { - static guint32 attr = 0; GFileAttributeValue *value; g_return_val_if_fail (G_IS_FILE_INFO (info), G_FILE_TYPE_UNKNOWN); - if (attr == 0) - attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_TYPE); - - value = g_file_info_find_value (info, attr); + get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_TYPE_UNKNOWN); return (GFileType)_g_file_attribute_value_get_uint32 (value); } @@ -1569,15 +1580,11 @@ g_file_info_get_file_type (GFileInfo *info) gboolean g_file_info_get_is_hidden (GFileInfo *info) { - static guint32 attr = 0; GFileAttributeValue *value; g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE); - if (attr == 0) - attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN); - - value = g_file_info_find_value (info, attr); + get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN, FALSE); return _g_file_attribute_value_get_boolean (value); } @@ -1595,15 +1602,11 @@ g_file_info_get_is_hidden (GFileInfo *info) gboolean g_file_info_get_is_backup (GFileInfo *info) { - static guint32 attr = 0; GFileAttributeValue *value; g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE); - if (attr == 0) - attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP); - - value = g_file_info_find_value (info, attr); + get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP, FALSE); return _g_file_attribute_value_get_boolean (value); } @@ -1621,15 +1624,11 @@ g_file_info_get_is_backup (GFileInfo *info) gboolean g_file_info_get_is_symlink (GFileInfo *info) { - static guint32 attr = 0; GFileAttributeValue *value; g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE); - if (attr == 0) - attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK); - - value = g_file_info_find_value (info, attr); + get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK, FALSE); return _g_file_attribute_value_get_boolean (value); } @@ -1647,15 +1646,11 @@ g_file_info_get_is_symlink (GFileInfo *info) const char * g_file_info_get_name (GFileInfo *info) { - static guint32 attr = 0; GFileAttributeValue *value; g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); - if (attr == 0) - attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_NAME); - - value = g_file_info_find_value (info, attr); + get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_NAME, NULL); return _g_file_attribute_value_get_byte_string (value); } @@ -1673,15 +1668,11 @@ g_file_info_get_name (GFileInfo *info) const char * g_file_info_get_display_name (GFileInfo *info) { - static guint32 attr = 0; GFileAttributeValue *value; g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); - if (attr == 0) - attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME); - - value = g_file_info_find_value (info, attr); + get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, NULL); return _g_file_attribute_value_get_string (value); } @@ -1699,15 +1690,11 @@ g_file_info_get_display_name (GFileInfo *info) const char * g_file_info_get_edit_name (GFileInfo *info) { - static guint32 attr = 0; GFileAttributeValue *value; g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); - if (attr == 0) - attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME); - - value = g_file_info_find_value (info, attr); + get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME, NULL); return _g_file_attribute_value_get_string (value); } @@ -1725,16 +1712,13 @@ g_file_info_get_edit_name (GFileInfo *info) GIcon * g_file_info_get_icon (GFileInfo *info) { - static guint32 attr = 0; GFileAttributeValue *value; GObject *obj; g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); - if (attr == 0) - attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_ICON); + get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_ICON, NULL); - value = g_file_info_find_value (info, attr); obj = _g_file_attribute_value_get_object (value); if (G_IS_ICON (obj)) return G_ICON (obj); @@ -1757,16 +1741,13 @@ g_file_info_get_icon (GFileInfo *info) GIcon * g_file_info_get_symbolic_icon (GFileInfo *info) { - static guint32 attr = 0; GFileAttributeValue *value; GObject *obj; g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); - if (attr == 0) - attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON); + get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON, NULL); - value = g_file_info_find_value (info, attr); obj = _g_file_attribute_value_get_object (value); if (G_IS_ICON (obj)) return G_ICON (obj); @@ -1788,15 +1769,11 @@ g_file_info_get_symbolic_icon (GFileInfo *info) const char * g_file_info_get_content_type (GFileInfo *info) { - static guint32 attr = 0; GFileAttributeValue *value; g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); - if (attr == 0) - attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE); - - value = g_file_info_find_value (info, attr); + get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, NULL); return _g_file_attribute_value_get_string (value); } @@ -1816,15 +1793,11 @@ g_file_info_get_content_type (GFileInfo *info) goffset g_file_info_get_size (GFileInfo *info) { - static guint32 attr = 0; GFileAttributeValue *value; g_return_val_if_fail (G_IS_FILE_INFO (info), (goffset) 0); - if (attr == 0) - attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SIZE); - - value = g_file_info_find_value (info, attr); + get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_SIZE, (goffset) 0); return (goffset) _g_file_attribute_value_get_uint64 (value); } @@ -1861,6 +1834,13 @@ g_file_info_get_modification_time (GFileInfo *info, } value = g_file_info_find_value (info, attr_mtime); + + if (G_UNLIKELY (value == NULL)) + { + g_critical ("GFileInfo created without " G_FILE_ATTRIBUTE_TIME_MODIFIED); + g_return_if_reached (); + } + result->tv_sec = _g_file_attribute_value_get_uint64 (value); value = g_file_info_find_value (info, attr_mtime_usec); result->tv_usec = _g_file_attribute_value_get_uint32 (value); @@ -2028,15 +2008,11 @@ g_file_info_get_creation_date_time (GFileInfo *info) const char * g_file_info_get_symlink_target (GFileInfo *info) { - static guint32 attr = 0; GFileAttributeValue *value; g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); - if (attr == 0) - attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET); - - value = g_file_info_find_value (info, attr); + get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET, NULL); return _g_file_attribute_value_get_byte_string (value); } @@ -2055,15 +2031,11 @@ g_file_info_get_symlink_target (GFileInfo *info) const char * g_file_info_get_etag (GFileInfo *info) { - static guint32 attr = 0; GFileAttributeValue *value; g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); - if (attr == 0) - attr = lookup_attribute (G_FILE_ATTRIBUTE_ETAG_VALUE); - - value = g_file_info_find_value (info, attr); + get_required_attribute (&value, info, G_FILE_ATTRIBUTE_ETAG_VALUE, NULL); return _g_file_attribute_value_get_string (value); } @@ -2082,15 +2054,11 @@ g_file_info_get_etag (GFileInfo *info) gint32 g_file_info_get_sort_order (GFileInfo *info) { - static guint32 attr = 0; GFileAttributeValue *value; g_return_val_if_fail (G_IS_FILE_INFO (info), 0); - if (attr == 0) - attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER); - - value = g_file_info_find_value (info, attr); + get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER, 0); return _g_file_attribute_value_get_int32 (value); } From 7082f03dbf31ba190d061d154d683c57d91db3ce Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Wed, 8 Feb 2023 10:28:35 +0000 Subject: [PATCH 5/6] gio-tool-info: Add missing attribute check `g_file_info_get_is_hidden()` should not be called without checking the attribute is set first, just as with the calls higher up in this code. Signed-off-by: Philip Withnall Helps: #2907 --- gio/gio-tool-info.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gio/gio-tool-info.c b/gio/gio-tool-info.c index c992a6f02..d51edb47b 100644 --- a/gio/gio-tool-info.c +++ b/gio/gio-tool-info.c @@ -196,7 +196,8 @@ show_info (GFile *file, GFileInfo *info) g_print (" %"G_GUINT64_FORMAT"\n", (guint64)size); } - if (g_file_info_get_is_hidden (info)) + if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN) && + g_file_info_get_is_hidden (info)) g_print (_("hidden\n")); uri = g_file_get_uri (file); From 728ad64b449f6fc2f67042a35288d73dcd97ece9 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Wed, 8 Feb 2023 11:13:05 +0000 Subject: [PATCH 6/6] glocalfileinfo: Ensure boolean file attributes are set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don’t just set them when they’re true and rely on their non-presence being evaluated to `FALSE`. That means that they erroneously don’t get returned in `g_file_info_list_attributes()`. Signed-off-by: Philip Withnall Helps: #2907 --- gio/glocalfileinfo.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c index 420e9d4b2..2b87f692a 100644 --- a/gio/glocalfileinfo.c +++ b/gio/glocalfileinfo.c @@ -2024,6 +2024,8 @@ _g_local_file_info_get (const char *basename, symlink_broken = TRUE; } } + else + g_file_info_set_is_symlink (info, FALSE); if (stat_ok) set_info_from_stat (info, &statbuf, attribute_matcher); @@ -2037,10 +2039,10 @@ _g_local_file_info_get (const char *basename, if (_g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_STANDARD_IS_HIDDEN)) { - if (basename != NULL && - (basename[0] == '.' || - file_is_hidden (path, basename))) - g_file_info_set_is_hidden (info, TRUE); + g_file_info_set_is_hidden (info, + (basename != NULL && + (basename[0] == '.' || + file_is_hidden (path, basename)))); } if (basename != NULL && basename[strlen (basename) -1] == '~' &&