summaryrefslogtreecommitdiff
path: root/gio
diff options
context:
space:
mode:
authorHyunjee Kim <hj0426.kim@samsung.com>2019-12-03 10:37:40 +0900
committerHyunjee Kim <hj0426.kim@samsung.com>2019-12-03 10:37:40 +0900
commit245e1f302c8a605f79125d38557e70992fa57bc9 (patch)
tree69c07ff7bb85a482225636853da37bc4dae4b2f7 /gio
parent9d4dc80d1464c073554d6816992036babadad25a (diff)
downloadglib-245e1f302c8a605f79125d38557e70992fa57bc9.tar.gz
glib-245e1f302c8a605f79125d38557e70992fa57bc9.tar.bz2
glib-245e1f302c8a605f79125d38557e70992fa57bc9.zip
Imported Upstream version 2.57.3
Diffstat (limited to 'gio')
-rw-r--r--gio/gapplicationimpl-dbus.c6
-rw-r--r--gio/gdbusmessage.c2
-rw-r--r--gio/gio-tool-mount.c29
-rw-r--r--gio/glib-compile-schemas.c1
-rw-r--r--gio/glocalfile.c64
-rw-r--r--gio/glocalfileinfo.c30
-rw-r--r--gio/gnetworkmonitorportal.c21
-rw-r--r--gio/gresource-tool.c23
-rw-r--r--gio/gresource.c44
-rw-r--r--gio/gschema.dtd4
-rw-r--r--gio/gsettingsschema.c11
-rw-r--r--gio/gtask.c2
-rw-r--r--gio/gtestdbus.c2
-rw-r--r--gio/gthemedicon.c233
-rw-r--r--gio/gtlsclientconnection.c30
-rw-r--r--gio/gtlsconnection.c6
-rw-r--r--gio/gunixvolume.c9
-rw-r--r--gio/gunixvolumemonitor.c19
-rw-r--r--gio/gunixvolumemonitor.h1
-rw-r--r--gio/gvdb/gvdb-builder.c7
-rw-r--r--gio/gvdb/gvdb-reader.c485
-rw-r--r--gio/gvdb/gvdb-reader.h37
-rw-r--r--gio/gvdb/gvdb.doap31
-rw-r--r--gio/meson.build6
-rw-r--r--gio/tests/Makefile.am5
-rw-r--r--gio/tests/g-icon.c31
-rw-r--r--gio/tests/gdbus-unix-addresses.c1
-rw-r--r--gio/tests/gnotification.c3
-rw-r--r--gio/tests/gsettings.c33
-rw-r--r--gio/tests/meson.build536
-rw-r--r--gio/tests/resources.c41
-rw-r--r--gio/tests/trash.c16
32 files changed, 1004 insertions, 765 deletions
diff --git a/gio/gapplicationimpl-dbus.c b/gio/gapplicationimpl-dbus.c
index ac029a9f3..f9e5e710d 100644
--- a/gio/gapplicationimpl-dbus.c
+++ b/gio/gapplicationimpl-dbus.c
@@ -426,10 +426,12 @@ g_application_impl_attempt_primary (GApplicationImpl *impl,
* the well-known name and fall back to remote mode (!is_primary)
* in the case that we can't do that.
*/
- /* DBUS_NAME_FLAG_DO_NOT_QUEUE: 0x4 */
reply = g_dbus_connection_call_sync (impl->session_bus, "org.freedesktop.DBus", "/org/freedesktop/DBus",
"org.freedesktop.DBus", "RequestName",
- g_variant_new ("(su)", impl->bus_name, 0x4), G_VARIANT_TYPE ("(u)"),
+ g_variant_new ("(su)",
+ impl->bus_name,
+ G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE),
+ G_VARIANT_TYPE ("(u)"),
0, -1, cancellable, error);
if (reply == NULL)
diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c
index 68122387b..8de836bf6 100644
--- a/gio/gdbusmessage.c
+++ b/gio/gdbusmessage.c
@@ -1994,7 +1994,7 @@ g_dbus_message_bytes_needed (guchar *blob,
/**
* g_dbus_message_new_from_blob:
- * @blob: (array length=blob_len) (element-type guint8): A blob represent a binary D-Bus message.
+ * @blob: (array length=blob_len) (element-type guint8): A blob representing a binary D-Bus message.
* @blob_len: The length of @blob.
* @capabilities: A #GDBusCapabilityFlags describing what protocol features are supported.
* @error: Return location for error or %NULL.
diff --git a/gio/gio-tool-mount.c b/gio/gio-tool-mount.c
index b5aaa1af2..05647d91e 100644
--- a/gio/gio-tool-mount.c
+++ b/gio/gio-tool-mount.c
@@ -39,6 +39,7 @@ typedef enum {
static int outstanding_mounts = 0;
static GMainLoop *main_loop;
+static GVolumeMonitor *volume_monitor;
static gboolean mount_mountable = FALSE;
static gboolean mount_unmount = FALSE;
@@ -484,12 +485,9 @@ stop_with_device_file_cb (GObject *object,
static void
stop_with_device_file (const char *device_file)
{
- GVolumeMonitor *volume_monitor;
GList *drives;
GList *l;
- volume_monitor = g_volume_monitor_get ();
-
drives = g_volume_monitor_get_connected_drives (volume_monitor);
for (l = drives; l != NULL; l = l->next)
{
@@ -524,8 +522,6 @@ stop_with_device_file (const char *device_file)
print_error ("%s: %s", device_file, _("No drive for device file"));
success = FALSE;
}
-
- g_object_unref (volume_monitor);
}
static gboolean
@@ -905,11 +901,8 @@ list_drives (GList *drives,
static void
list_monitor_items (void)
{
- GVolumeMonitor *volume_monitor;
GList *drives, *volumes, *mounts;
- volume_monitor = g_volume_monitor_get();
-
/* populate gvfs network mounts */
iterate_gmain();
@@ -924,19 +917,14 @@ list_monitor_items (void)
mounts = g_volume_monitor_get_mounts (volume_monitor);
list_mounts (mounts, 0, TRUE);
g_list_free_full (mounts, g_object_unref);
-
- g_object_unref (volume_monitor);
}
static void
unmount_all_with_scheme (const char *scheme)
{
- GVolumeMonitor *volume_monitor;
GList *mounts;
GList *l;
- volume_monitor = g_volume_monitor_get();
-
/* populate gvfs network mounts */
iterate_gmain();
@@ -952,8 +940,6 @@ unmount_all_with_scheme (const char *scheme)
g_object_unref (root);
}
g_list_free_full (mounts, g_object_unref);
-
- g_object_unref (volume_monitor);
}
static void
@@ -1004,12 +990,9 @@ mount_with_device_file_cb (GObject *object,
static void
mount_with_device_file (const char *device_file)
{
- GVolumeMonitor *volume_monitor;
GList *volumes;
GList *l;
- volume_monitor = g_volume_monitor_get();
-
volumes = g_volume_monitor_get_volumes (volume_monitor);
for (l = volumes; l != NULL; l = l->next)
{
@@ -1044,8 +1027,6 @@ mount_with_device_file (const char *device_file)
print_error ("%s: %s", device_file, _("No volume for device file"));
success = FALSE;
}
-
- g_object_unref (volume_monitor);
}
static void
@@ -1199,10 +1180,6 @@ monitor_drive_eject_button (GVolumeMonitor *volume_monitor, GDrive *drive)
static void
monitor (void)
{
- GVolumeMonitor *volume_monitor;
-
- volume_monitor = g_volume_monitor_get ();
-
g_signal_connect (volume_monitor, "mount-added", (GCallback) monitor_mount_added, NULL);
g_signal_connect (volume_monitor, "mount-removed", (GCallback) monitor_mount_removed, NULL);
g_signal_connect (volume_monitor, "mount-changed", (GCallback) monitor_mount_changed, NULL);
@@ -1255,6 +1232,7 @@ handle_mount (int argc, char *argv[], gboolean do_help)
}
main_loop = g_main_loop_new (NULL, FALSE);
+ volume_monitor = g_volume_monitor_get ();
if (mount_list)
list_monitor_items ();
@@ -1284,6 +1262,7 @@ handle_mount (int argc, char *argv[], gboolean do_help)
{
show_help (context, _("No locations given"));
g_option_context_free (context);
+ g_object_unref (volume_monitor);
return 1;
}
@@ -1292,5 +1271,7 @@ handle_mount (int argc, char *argv[], gboolean do_help)
if (outstanding_mounts > 0)
g_main_loop_run (main_loop);
+ g_object_unref (volume_monitor);
+
return success ? 0 : 2;
}
diff --git a/gio/glib-compile-schemas.c b/gio/glib-compile-schemas.c
index d4340d463..5e1bebbba 100644
--- a/gio/glib-compile-schemas.c
+++ b/gio/glib-compile-schemas.c
@@ -2112,6 +2112,7 @@ set_overrides (GHashTable *schema_table,
}
g_strfreev (groups);
+ g_key_file_free (key_file);
}
return TRUE;
diff --git a/gio/glocalfile.c b/gio/glocalfile.c
index 354ac7c8c..30fa2281c 100644
--- a/gio/glocalfile.c
+++ b/gio/glocalfile.c
@@ -983,15 +983,20 @@ g_local_file_query_filesystem_info (GFile *file,
block_size = statfs_buffer.f_bsize;
/* Many backends can't report free size (for instance the gvfs fuse
- backend for backend not supporting this), and set f_bfree to 0,
- but it can be 0 for real too. We treat the available == 0 and
- free == 0 case as "both of these are invalid".
- */
-#ifndef G_OS_WIN32
+ * backend for backend not supporting this), and set f_bfree to 0,
+ * but it can be 0 for real too. We treat the available == 0 and
+ * free == 0 case as "both of these are invalid", but only on file systems
+ * which are known to not support this (otherwise we can omit metadata for
+ * systems which are legitimately full). */
+#if defined(__linux__)
if (statfs_result == 0 &&
- statfs_buffer.f_bavail == 0 && statfs_buffer.f_bfree == 0)
+ statfs_buffer.f_bavail == 0 && statfs_buffer.f_bfree == 0 &&
+ (/* linux/ncp_fs.h: NCP_SUPER_MAGIC == 0x564c */
+ statfs_buffer.f_type == 0x564c ||
+ /* man statfs: FUSE_SUPER_MAGIC == 0x65735546 */
+ statfs_buffer.f_type == 0x65735546))
no_size = TRUE;
-#endif /* G_OS_WIN32 */
+#endif /* __linux__ */
#elif defined(USE_STATVFS)
statfs_result = statvfs (local->filename, &statfs_buffer);
@@ -1677,20 +1682,16 @@ find_mountpoint_for (const char *file,
}
}
-static char *
-_g_local_file_find_topdir_for_internal (const char *file, dev_t file_dev)
+char *
+_g_local_file_find_topdir_for (const char *file)
{
char *dir;
char *mountpoint = NULL;
dev_t dir_dev;
dir = get_parent (file, &dir_dev);
- if (dir == NULL || dir_dev != file_dev)
- {
- g_free (dir);
-
- return NULL;
- }
+ if (dir == NULL)
+ return NULL;
mountpoint = find_mountpoint_for (dir, dir_dev);
g_free (dir);
@@ -1698,17 +1699,6 @@ _g_local_file_find_topdir_for_internal (const char *file, dev_t file_dev)
return mountpoint;
}
-char *
-_g_local_file_find_topdir_for (const char *file)
-{
- GStatBuf file_stat;
-
- if (g_lstat (file, &file_stat) != 0)
- return NULL;
-
- return _g_local_file_find_topdir_for_internal (file, file_stat.st_dev);
-}
-
static char *
get_unique_filename (const char *basename,
int id)
@@ -1908,6 +1898,7 @@ g_local_file_trash (GFile *file,
char *original_name, *original_name_escaped;
int i;
char *data;
+ char *path;
gboolean is_homedir_trash;
char *delete_time = NULL;
int fd;
@@ -1932,6 +1923,24 @@ g_local_file_trash (GFile *file,
is_homedir_trash = FALSE;
trashdir = NULL;
+
+ /* On overlayfs, a file's st_dev will be different to the home directory's.
+ * We still want to create our trash directory under the home directory, so
+ * instead we should stat the directory that the file we're deleting is in as
+ * this will have the same st_dev.
+ */
+ if (!S_ISDIR (file_stat.st_mode))
+ {
+ path = g_path_get_dirname (local->filename);
+ /* If the parent is a symlink to a different device then it might have
+ * st_dev equal to the home directory's, in which case we will end up
+ * trying to rename across a filesystem boundary, which doesn't work. So
+ * we use g_stat here instead of g_lstat, to know where the symlink
+ * points to. */
+ g_stat (path, &file_stat);
+ g_free (path);
+ }
+
if (file_stat.st_dev == home_stat.st_dev)
{
is_homedir_trash = TRUE;
@@ -1962,8 +1971,7 @@ g_local_file_trash (GFile *file,
uid = geteuid ();
g_snprintf (uid_str, sizeof (uid_str), "%lu", (unsigned long)uid);
- topdir = _g_local_file_find_topdir_for_internal (local->filename,
- file_stat.st_dev);
+ topdir = _g_local_file_find_topdir_for (local->filename);
if (topdir == NULL)
{
g_set_io_error (error,
diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c
index b3e29374a..58802fd43 100644
--- a/gio/glocalfileinfo.c
+++ b/gio/glocalfileinfo.c
@@ -924,13 +924,9 @@ get_access_rights (GFileAttributeMatcher *attribute_matcher,
_g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_DELETE,
writable);
- /* Trashing is supported only if the parent device is the same */
if (_g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_TRASH))
- _g_file_info_set_attribute_boolean_by_id (info,
- G_FILE_ATTRIBUTE_ID_ACCESS_CAN_TRASH,
- writable &&
- parent_info->has_trash_dir &&
- parent_info->device == statbuf->st_dev);
+ _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_ACCESS_CAN_TRASH,
+ writable && parent_info->has_trash_dir);
}
}
@@ -961,7 +957,8 @@ set_info_from_stat (GFileInfo *info,
else if (S_ISLNK (statbuf->st_mode))
file_type = G_FILE_TYPE_SYMBOLIC_LINK;
#elif defined (G_OS_WIN32)
- if (statbuf->reparse_tag == IO_REPARSE_TAG_SYMLINK)
+ if (statbuf->reparse_tag == IO_REPARSE_TAG_SYMLINK ||
+ statbuf->reparse_tag == IO_REPARSE_TAG_MOUNT_POINT)
file_type = G_FILE_TYPE_SYMBOLIC_LINK;
#endif
@@ -1005,13 +1002,20 @@ set_info_from_stat (GFileInfo *info,
#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, statbuf->st_atim.tv_nsec / 1000);
#endif
-
+
+#ifndef G_OS_WIN32
+ /* Microsoft uses st_ctime for file creation time,
+ * instead of file change time:
+ * https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/stat-functions#generic-text-routine-mappings
+ * Thank you, Microsoft!
+ */
_g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CHANGED, statbuf->st_ctime);
#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);
#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, statbuf->st_ctim.tv_nsec / 1000);
#endif
+#endif
#if defined (HAVE_STRUCT_STAT_ST_BIRTHTIME) && defined (HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC)
_g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED, statbuf->st_birthtime);
@@ -1023,6 +1027,8 @@ set_info_from_stat (GFileInfo *info,
_g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED, statbuf->st_birthtime);
#elif defined (HAVE_STRUCT_STAT_ST_BIRTHTIM)
_g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED, statbuf->st_birthtim);
+#elif defined (G_OS_WIN32)
+ _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED, statbuf->st_ctime);
#endif
if (_g_file_attribute_matcher_matches_id (attribute_matcher,
@@ -1799,7 +1805,9 @@ _g_local_file_info_get (const char *basename,
is_symlink = stat_ok && S_ISLNK (statbuf.st_mode);
#elif defined (G_OS_WIN32)
/* glib already checked the FILE_ATTRIBUTE_REPARSE_POINT for us */
- is_symlink = stat_ok && statbuf.reparse_tag == IO_REPARSE_TAG_SYMLINK;
+ is_symlink = stat_ok &&
+ (statbuf.reparse_tag == IO_REPARSE_TAG_SYMLINK ||
+ statbuf.reparse_tag == IO_REPARSE_TAG_MOUNT_POINT);
#else
is_symlink = FALSE;
#endif
@@ -2182,7 +2190,9 @@ set_unix_mode (char *filename,
GWin32PrivateStat statbuf;
res = GLIB_PRIVATE_CALL (g_win32_lstat_utf8) (filename, &statbuf);
- is_symlink = (res == 0 && statbuf.reparse_tag == IO_REPARSE_TAG_SYMLINK);
+ is_symlink = (res == 0 &&
+ (statbuf.reparse_tag == IO_REPARSE_TAG_SYMLINK ||
+ statbuf.reparse_tag == IO_REPARSE_TAG_MOUNT_POINT));
#endif
if (is_symlink)
{
diff --git a/gio/gnetworkmonitorportal.c b/gio/gnetworkmonitorportal.c
index 16249ac55..bce8a338a 100644
--- a/gio/gnetworkmonitorportal.c
+++ b/gio/gnetworkmonitorportal.c
@@ -182,6 +182,15 @@ got_connectivity (GObject *source,
}
static void
+update_properties (GDBusProxy *proxy,
+ GNetworkMonitorPortal *nm)
+{
+ g_dbus_proxy_call (proxy, "GetConnectivity", NULL, 0, -1, NULL, got_connectivity, nm);
+ g_dbus_proxy_call (proxy, "GetMetered", NULL, 0, -1, NULL, got_metered, nm);
+ g_dbus_proxy_call (proxy, "GetAvailable", NULL, 0, -1, NULL, got_available, nm);
+}
+
+static void
proxy_signal (GDBusProxy *proxy,
const char *sender,
const char *signal,
@@ -200,9 +209,7 @@ proxy_signal (GDBusProxy *proxy,
}
else if (nm->priv->version == 2)
{
- g_dbus_proxy_call (proxy, "GetConnectivity", NULL, 0, -1, NULL, got_connectivity, nm);
- g_dbus_proxy_call (proxy, "GetMetered", NULL, 0, -1, NULL, got_metered, nm);
- g_dbus_proxy_call (proxy, "GetAvailable", NULL, 0, -1, NULL, got_available, nm);
+ update_properties (proxy, nm);
}
}
@@ -326,7 +333,13 @@ g_network_monitor_portal_initable_init (GInitable *initable,
nm->priv->has_network = glib_network_available_in_sandbox ();
nm->priv->version = version;
- return initable_parent_iface->init (initable, cancellable, error);
+ if (!initable_parent_iface->init (initable, cancellable, error))
+ return FALSE;
+
+ if (nm->priv->has_network && nm->priv->version == 2)
+ update_properties (proxy, nm);
+
+ return TRUE;
}
static void
diff --git a/gio/gresource-tool.c b/gio/gresource-tool.c
index b25eebf3d..d1de02631 100644
--- a/gio/gresource-tool.c
+++ b/gio/gresource-tool.c
@@ -31,6 +31,9 @@
#ifdef HAVE_LIBELF
#include <libelf.h>
#include <gelf.h>
+#endif
+
+#ifdef HAVE_MMAP
#include <sys/mman.h>
#endif
@@ -42,6 +45,10 @@
#include "glib/glib-private.h"
#endif
+#if defined(HAVE_LIBELF) && defined(HAVE_MMAP)
+#define USE_LIBELF
+#endif
+
/* GResource functions {{{1 */
static GResource *
get_resource (const gchar *file)
@@ -133,7 +140,7 @@ extract_resource (GResource *resource,
/* Elf functions {{{1 */
-#ifdef HAVE_LIBELF
+#ifdef USE_LIBELF
static Elf *
get_elf (const gchar *file,
@@ -353,7 +360,7 @@ print_section_name (GElf_Shdr *shdr,
return TRUE;
}
-#endif /* HAVE_LIBELF */
+#endif /* USE_LIBELF */
/* Toplevel commands {{{1 */
@@ -365,7 +372,7 @@ cmd_sections (const gchar *file,
{
GResource *resource;
-#ifdef HAVE_LIBELF
+#ifdef USE_LIBELF
Elf *elf;
gint fd;
@@ -388,7 +395,7 @@ cmd_sections (const gchar *file,
else
{
g_printerr ("Don't know how to handle %s\n", file);
-#ifndef HAVE_LIBELF
+#ifndef USE_LIBELF
g_printerr ("gresource is built without elf support\n");
#endif
}
@@ -402,7 +409,7 @@ cmd_list (const gchar *file,
{
GResource *resource;
-#ifdef HAVE_LIBELF
+#ifdef USE_LIBELF
Elf *elf;
int fd;
@@ -424,7 +431,7 @@ cmd_list (const gchar *file,
else
{
g_printerr ("Don't know how to handle %s\n", file);
-#ifndef HAVE_LIBELF
+#ifndef USE_LIBELF
g_printerr ("gresource is built without elf support\n");
#endif
}
@@ -438,7 +445,7 @@ cmd_extract (const gchar *file,
{
GResource *resource;
-#ifdef HAVE_LIBELF
+#ifdef USE_LIBELF
Elf *elf;
int fd;
@@ -461,7 +468,7 @@ cmd_extract (const gchar *file,
else
{
g_printerr ("Don't know how to handle %s\n", file);
-#ifndef HAVE_LIBELF
+#ifndef USE_LIBELF
g_printerr ("gresource is built without elf support\n");
#endif
}
diff --git a/gio/gresource.c b/gio/gresource.c
index bf54f1d78..2844f4808 100644
--- a/gio/gresource.c
+++ b/gio/gresource.c
@@ -489,7 +489,7 @@ g_resource_unref (GResource *resource)
{
if (g_atomic_int_dec_and_test (&resource->ref_count))
{
- gvdb_table_unref (resource->table);
+ gvdb_table_free (resource->table);
g_free (resource);
}
}
@@ -512,6 +512,19 @@ g_resource_new_from_table (GvdbTable *table)
return resource;
}
+static void
+g_resource_error_from_gvdb_table_error (GError **g_resource_error,
+ GError *gvdb_table_error /* (transfer full) */)
+{
+ if (g_error_matches (gvdb_table_error, G_FILE_ERROR, G_FILE_ERROR_INVAL))
+ g_set_error_literal (g_resource_error,
+ G_RESOURCE_ERROR, G_RESOURCE_ERROR_INTERNAL,
+ gvdb_table_error->message);
+ else
+ g_propagate_error (g_resource_error, g_steal_pointer (&gvdb_table_error));
+ g_clear_error (&gvdb_table_error);
+}
+
/**
* g_resource_new_from_data:
* @data: A #GBytes
@@ -528,6 +541,8 @@ g_resource_new_from_table (GvdbTable *table)
* Otherwise this function will internally create a copy of the memory since
* GLib 2.56, or in older versions fail and exit the process.
*
+ * If @data is empty or corrupt, %G_RESOURCE_ERROR_INTERNAL will be returned.
+ *
* Returns: (transfer full): a new #GResource, or %NULL on error
*
* Since: 2.32
@@ -538,6 +553,7 @@ g_resource_new_from_data (GBytes *data,
{
GvdbTable *table;
gboolean unref_data = FALSE;
+ GError *local_error = NULL;
if (((guintptr) g_bytes_get_data (data, NULL)) % sizeof (gpointer) != 0)
{
@@ -546,19 +562,16 @@ g_resource_new_from_data (GBytes *data,
unref_data = TRUE;
}
- table = gvdb_table_new_from_data (g_bytes_get_data (data, NULL),
- g_bytes_get_size (data),
- TRUE,
- g_bytes_ref (data),
- (GvdbRefFunc)g_bytes_ref,
- (GDestroyNotify)g_bytes_unref,
- error);
+ table = gvdb_table_new_from_bytes (data, TRUE, &local_error);
if (unref_data)
g_bytes_unref (data);
if (table == NULL)
- return NULL;
+ {
+ g_resource_error_from_gvdb_table_error (error, g_steal_pointer (&local_error));
+ return NULL;
+ }
return g_resource_new_from_table (table);
}
@@ -574,6 +587,11 @@ g_resource_new_from_data (GBytes *data,
* If you want to use this resource in the global resource namespace you need
* to register it with g_resources_register().
*
+ * If @filename is empty or the data in it is corrupt,
+ * %G_RESOURCE_ERROR_INTERNAL will be returned. If @filename doesn’t exist, or
+ * there is an error in reading it, an error from g_mapped_file_new() will be
+ * returned.
+ *
* Returns: (transfer full): a new #GResource, or %NULL on error
*
* Since: 2.32
@@ -583,10 +601,14 @@ g_resource_load (const gchar *filename,
GError **error)
{
GvdbTable *table;
+ GError *local_error = NULL;
- table = gvdb_table_new (filename, FALSE, error);
+ table = gvdb_table_new (filename, FALSE, &local_error);
if (table == NULL)
- return NULL;
+ {
+ g_resource_error_from_gvdb_table_error (error, g_steal_pointer (&local_error));
+ return NULL;
+ }
return g_resource_new_from_table (table);
}
diff --git a/gio/gschema.dtd b/gio/gschema.dtd
index 8cd552d4a..1599f8de7 100644
--- a/gio/gschema.dtd
+++ b/gio/gschema.dtd
@@ -49,8 +49,8 @@
<!ELEMENT range EMPTY >
<!-- min and max must be parseable as values of the key type and
min must be less than or equal to max -->
-<!ATTLIST range min CDATA #REQUIRED
- max CDATA #REQUIRED >
+<!ATTLIST range min CDATA #IMPLIED
+ max CDATA #IMPLIED >
<!-- choices is only allowed for keys with string or string array type -->
<!ELEMENT choices (choice+) >
diff --git a/gio/gsettingsschema.c b/gio/gsettingsschema.c
index 17b7e3b01..38c9d78b9 100644
--- a/gio/gsettingsschema.c
+++ b/gio/gsettingsschema.c
@@ -231,7 +231,7 @@ g_settings_schema_source_unref (GSettingsSchemaSource *source)
if (source->parent)
g_settings_schema_source_unref (source->parent);
- gvdb_table_unref (source->table);
+ gvdb_table_free (source->table);
g_free (source->directory);
if (source->text_tables)
@@ -267,6 +267,9 @@ g_settings_schema_source_unref (GSettingsSchemaSource *source)
* Generally, you should set @trusted to %TRUE for files installed by the
* system and to %FALSE for files in the home directory.
*
+ * In either case, an empty file or some types of corruption in the file will
+ * result in %G_FILE_ERROR_INVAL being returned.
+ *
* If @parent is non-%NULL then there are two effects.
*
* First, if g_settings_schema_source_lookup() is called with the
@@ -802,7 +805,7 @@ g_settings_schema_source_list_schemas (GSettingsSchemaSource *source,
else
g_hash_table_add (reloc, schema);
- gvdb_table_unref (table);
+ gvdb_table_free (table);
}
}
@@ -928,7 +931,7 @@ g_settings_schema_unref (GSettingsSchema *schema)
g_settings_schema_unref (schema->extends);
g_settings_schema_source_unref (schema->source);
- gvdb_table_unref (schema->table);
+ gvdb_table_free (schema->table);
g_free (schema->items);
g_free (schema->id);
@@ -1188,7 +1191,7 @@ g_settings_schema_list (GSettingsSchema *schema,
g_hash_table_iter_remove (&iter);
}
- gvdb_table_unref (child_table);
+ gvdb_table_free (child_table);
}
/* Now create the list */
diff --git a/gio/gtask.c b/gio/gtask.c
index df40357dd..4087543e6 100644
--- a/gio/gtask.c
+++ b/gio/gtask.c
@@ -52,7 +52,7 @@
* where it was created (waiting until the next iteration of the main
* loop first, if necessary). The caller will pass the #GTask back to
* the operation's finish function (as a #GAsyncResult), and you can
- * can use g_task_propagate_pointer() or the like to extract the
+ * use g_task_propagate_pointer() or the like to extract the
* return value.
*
* Here is an example for using GTask as a GAsyncResult:
diff --git a/gio/gtestdbus.c b/gio/gtestdbus.c
index 685503c5e..2fc2d51f5 100644
--- a/gio/gtestdbus.c
+++ b/gio/gtestdbus.c
@@ -179,7 +179,7 @@ watch_parent (gint fd)
if (num_events == 0)
continue;
- if (fds[0].revents == G_IO_HUP)
+ if (fds[0].revents & G_IO_HUP)
{
/* Parent quit, cleanup the mess and exit */
for (n = 0; n < pids_to_kill->len; n++)
diff --git a/gio/gthemedicon.c b/gio/gthemedicon.c
index 3ada77b6c..35970deff 100644
--- a/gio/gthemedicon.c
+++ b/gio/gthemedicon.c
@@ -49,6 +49,7 @@ struct _GThemedIcon
{
GObject parent_instance;
+ char **init_names;
char **names;
gboolean use_default_fallbacks;
};
@@ -66,6 +67,8 @@ enum
PROP_USE_DEFAULT_FALLBACKS
};
+static void g_themed_icon_update_names (GThemedIcon *themed);
+
G_DEFINE_TYPE_WITH_CODE (GThemedIcon, g_themed_icon, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_ICON,
g_themed_icon_icon_iface_init))
@@ -81,7 +84,7 @@ g_themed_icon_get_property (GObject *object,
switch (prop_id)
{
case PROP_NAMES:
- g_value_set_boxed (value, icon->names);
+ g_value_set_boxed (value, icon->init_names);
break;
case PROP_USE_DEFAULT_FALLBACKS:
@@ -111,12 +114,12 @@ g_themed_icon_set_property (GObject *object,
if (!name)
break;
- if (icon->names)
- g_strfreev (icon->names);
+ if (icon->init_names)
+ g_strfreev (icon->init_names);
- icon->names = g_new (char *, 2);
- icon->names[0] = g_strdup (name);
- icon->names[1] = NULL;
+ icon->init_names = g_new (char *, 2);
+ icon->init_names[0] = g_strdup (name);
+ icon->init_names[1] = NULL;
break;
case PROP_NAMES:
@@ -125,10 +128,10 @@ g_themed_icon_set_property (GObject *object,
if (!names)
break;
- if (icon->names)
- g_strfreev (icon->names);
+ if (icon->init_names)
+ g_strfreev (icon->init_names);
- icon->names = names;
+ icon->init_names = names;
break;
case PROP_USE_DEFAULT_FALLBACKS:
@@ -143,63 +146,7 @@ g_themed_icon_set_property (GObject *object,
static void
g_themed_icon_constructed (GObject *object)
{
- GThemedIcon *themed = G_THEMED_ICON (object);
-
- g_return_if_fail (themed->names != NULL && themed->names[0] != NULL);
-
- if (themed->use_default_fallbacks)
- {
- int i = 0, dashes = 0;
- const char *p;
- char *dashp;
- char *last;
- gboolean is_symbolic;
- char *name;
- char **names;
-
- is_symbolic = g_str_has_suffix (themed->names[0], "-symbolic");
- if (is_symbolic)
- name = g_strndup (themed->names[0], strlen (themed->names[0]) - 9);
- else
- name = g_strdup (themed->names[0]);
-
- p = name;
- while (*p)
- {
- if (*p == '-')
- dashes++;
- p++;
- }
-
- last = name;
-
- g_strfreev (themed->names);
-
- names = g_new (char *, dashes + 1 + 1);
- names[i++] = last;
-
- while ((dashp = strrchr (last, '-')) != NULL)
- names[i++] = last = g_strndup (last, dashp - last);
-
- names[i++] = NULL;
-
- if (is_symbolic)
- {
- themed->names = g_new (char *, 2 * dashes + 3);
- for (i = 0; names[i] != NULL; i++)
- {
- themed->names[i] = g_strconcat (names[i], "-symbolic", NULL);
- themed->names[dashes + 1 + i] = names[i];
- }
-
- themed->names[dashes + 1 + i] = NULL;
- g_free (names);
- }
- else
- {
- themed->names = names;
- }
- }
+ g_themed_icon_update_names (G_THEMED_ICON (object));
}
static void
@@ -209,6 +156,7 @@ g_themed_icon_finalize (GObject *object)
themed = G_THEMED_ICON (object);
+ g_strfreev (themed->init_names);
g_strfreev (themed->names);
G_OBJECT_CLASS (g_themed_icon_parent_class)->finalize (object);
@@ -278,7 +226,136 @@ g_themed_icon_class_init (GThemedIconClass *klass)
static void
g_themed_icon_init (GThemedIcon *themed)
{
- themed->names = NULL;
+ themed->init_names = NULL;
+ themed->names = NULL;
+}
+
+/**
+ * g_themed_icon_update_names:
+ * @themed: a #GThemedIcon.
+ *
+ * Update the actual icon name list, based on the requested names (from
+ * construction, or later added with g_themed_icon_prepend_name() and
+ * g_themed_icon_append_name()).
+ * The order of the list matters, indicating priority:
+ * - The first requested icon is first in priority.
+ * - If "use-default-fallbacks" is #TRUE, then it is followed by all its
+ * fallbacks (starting from top to lower context levels).
+ * - Then next requested icons, and optionally their fallbacks, follow.
+ * - Finally all the style variants (symbolic or regular, opposite to whatever
+ * is the requested style) follow in the same order.
+ *
+ * An icon is not added twice in the list if it was previously added.
+ *
+ * For instance, if requested names are:
+ * [ "some-icon-symbolic", "some-other-icon" ]
+ * and use-default-fallbacks is TRUE, the final name list shall be:
+ * [ "some-icon-symbolic", "some-symbolic", "some-other-icon",
+ * "some-other", "some", "some-icon", "some-other-icon-symbolic",
+ * "some-other-symbolic" ]
+ *
+ * Returns: (transfer full) (type GThemedIcon): a new #GThemedIcon
+ **/
+static void
+g_themed_icon_update_names (GThemedIcon *themed)
+{
+ GList *names = NULL;
+ GList *variants = NULL;
+ GList *iter;
+ guint i;
+
+ g_return_if_fail (themed->init_names != NULL && themed->init_names[0] != NULL);
+
+ for (i = 0; themed->init_names[i]; i++)
+ {
+ gchar *name;
+ gboolean is_symbolic;
+
+ is_symbolic = g_str_has_suffix (themed->init_names[i], "-symbolic");
+ if (is_symbolic)
+ name = g_strndup (themed->init_names[i], strlen (themed->init_names[i]) - 9);
+ else
+ name = g_strdup (themed->init_names[i]);
+
+ if (g_list_find_custom (names, name, (GCompareFunc) g_strcmp0))
+ {
+ g_free (name);
+ continue;
+ }
+
+ if (is_symbolic)
+ names = g_list_prepend (names, g_strdup (themed->init_names[i]));
+ else
+ names = g_list_prepend (names, name);
+
+ if (themed->use_default_fallbacks)
+ {
+ char *dashp;
+ char *last;
+
+ last = name;
+
+ while ((dashp = strrchr (last, '-')) != NULL)
+ {
+ gchar *tmp = last;
+ gchar *fallback;
+
+ last = g_strndup (last, dashp - last);
+ if (is_symbolic)
+ {
+ g_free (tmp);
+ fallback = g_strdup_printf ("%s-symbolic", last);
+ }
+ else
+ fallback = last;
+ if (g_list_find_custom (names, fallback, (GCompareFunc) g_strcmp0))
+ {
+ g_free (fallback);
+ break;
+ }
+ names = g_list_prepend (names, fallback);
+ }
+ if (is_symbolic)
+ g_free (last);
+ }
+ else if (is_symbolic)
+ g_free (name);
+ }
+ for (iter = names; iter; iter = iter->next)
+ {
+ gchar *name = (gchar *) iter->data;
+ gchar *variant;
+ gboolean is_symbolic;
+
+ is_symbolic = g_str_has_suffix (name, "-symbolic");
+ if (is_symbolic)
+ variant = g_strndup (name, strlen (name) - 9);
+ else
+ variant = g_strdup_printf ("%s-symbolic", name);
+ if (g_list_find_custom (names, variant, (GCompareFunc) g_strcmp0) ||
+ g_list_find_custom (variants, variant, (GCompareFunc) g_strcmp0))
+ {
+ g_free (variant);
+ continue;
+ }
+
+ variants = g_list_prepend (variants, variant);
+ }
+ names = g_list_reverse (names);
+
+ g_strfreev (themed->names);
+ themed->names = g_new (char *, g_list_length (names) + g_list_length (variants) + 1);
+
+ for (iter = names, i = 0; iter; iter = iter->next, i++)
+ themed->names[i] = iter->data;
+ for (iter = variants; iter; iter = iter->next, i++)
+ themed->names[i] = iter->data;
+ themed->names[i] = NULL;
+
+ g_list_free (names);
+ g_list_free (variants);
+
+ g_object_notify (G_OBJECT (themed), "names");
}
/**
@@ -402,12 +479,12 @@ g_themed_icon_append_name (GThemedIcon *icon,
g_return_if_fail (G_IS_THEMED_ICON (icon));
g_return_if_fail (iconname != NULL);
- num_names = g_strv_length (icon->names);
- icon->names = g_realloc (icon->names, sizeof (char*) * (num_names + 2));
- icon->names[num_names] = g_strdup (iconname);
- icon->names[num_names + 1] = NULL;
+ num_names = g_strv_length (icon->init_names);
+ icon->init_names = g_realloc (icon->init_names, sizeof (char*) * (num_names + 2));
+ icon->init_names[num_names] = g_strdup (iconname);
+ icon->init_names[num_names + 1] = NULL;
- g_object_notify (G_OBJECT (icon), "names");
+ g_themed_icon_update_names (icon);
}
/**
@@ -433,17 +510,17 @@ g_themed_icon_prepend_name (GThemedIcon *icon,
g_return_if_fail (G_IS_THEMED_ICON (icon));
g_return_if_fail (iconname != NULL);
- num_names = g_strv_length (icon->names);
+ num_names = g_strv_length (icon->init_names);
names = g_new (char*, num_names + 2);
- for (i = 0; icon->names[i]; i++)
- names[i + 1] = icon->names[i];
+ for (i = 0; icon->init_names[i]; i++)
+ names[i + 1] = icon->init_names[i];
names[0] = g_strdup (iconname);
names[num_names + 1] = NULL;
- g_free (icon->names);
- icon->names = names;
+ g_free (icon->init_names);
+ icon->init_names = names;
- g_object_notify (G_OBJECT (icon), "names");
+ g_themed_icon_update_names (icon);
}
static guint
diff --git a/gio/gtlsclientconnection.c b/gio/gtlsclientconnection.c
index f80c62572..b38fad630 100644
--- a/gio/gtlsclientconnection.c
+++ b/gio/gtlsclientconnection.c
@@ -105,14 +105,7 @@ g_tls_client_connection_default_init (GTlsClientConnectionInterface *iface)
*
* If %TRUE, forces the connection to use a fallback version of TLS
* or SSL, rather than trying to negotiate the best version of TLS
- * to use. This can be used when talking to servers that don't
- * implement version negotiation correctly and therefore refuse to
- * handshake at all with a modern TLS handshake.
- *
- * Despite the property name, the fallback version is usually not
- * SSL 3.0, because SSL 3.0 is generally disabled by the #GTlsBackend.
- * #GTlsClientConnection will use the next-highest available version
- * as the fallback version.
+ * to use. See g_tls_client_connection_set_use_ssl3().
*
* Since: 2.28
*
@@ -304,14 +297,19 @@ g_tls_client_connection_get_use_ssl3 (GTlsClientConnection *conn)
* @conn: the #GTlsClientConnection
* @use_ssl3: whether to use the lowest-supported protocol version
*
- * If @use_ssl3 is %TRUE, this forces @conn to use the lowest-supported
- * TLS protocol version rather than trying to properly negotiate the
- * highest mutually-supported protocol version with the peer. This can
- * be used when talking to broken TLS servers that exhibit protocol
- * version intolerance.
- *
- * Be aware that SSL 3.0 is generally disabled by the #GTlsBackend, so
- * the lowest-supported protocol version is probably not SSL 3.0.
+ * Since 2.42.1, if @use_ssl3 is %TRUE, this forces @conn to use the
+ * lowest-supported TLS protocol version rather than trying to properly
+ * negotiate the highest mutually-supported protocol version with the
+ * peer. Be aware that SSL 3.0 is generally disabled by the
+ * #GTlsBackend, so the lowest-supported protocol version is probably
+ * not SSL 3.0.
+ *
+ * Since 2.58, this may additionally cause an RFC 7507 fallback SCSV to
+ * be sent to the server, causing modern TLS servers to immediately
+ * terminate the connection. You should generally only use this function
+ * if you need to connect to broken servers that exhibit TLS protocol
+ * version intolerance, and when an initial attempt to connect to a
+ * server normally has already failed.
*
* Since: 2.28
*
diff --git a/gio/gtlsconnection.c b/gio/gtlsconnection.c
index e13d98614..b0353af9d 100644
--- a/gio/gtlsconnection.c
+++ b/gio/gtlsconnection.c
@@ -674,7 +674,8 @@ g_tls_connection_get_require_close_notify (GTlsConnection *conn)
* @conn: a #GTlsConnection
* @mode: the rehandshaking mode
*
- * Sets how @conn behaves with respect to rehandshaking requests.
+ * Sets how @conn behaves with respect to rehandshaking requests, when
+ * TLS 1.2 or older is in use.
*
* %G_TLS_REHANDSHAKE_NEVER means that it will never agree to
* rehandshake after the initial handshake is complete. (For a client,
@@ -756,7 +757,8 @@ g_tls_connection_get_rehandshake_mode (GTlsConnection *conn)
* the beginning of the communication, you do not need to call this
* function explicitly unless you want clearer error reporting.
* However, you may call g_tls_connection_handshake() later on to
- * renegotiate parameters (encryption methods, etc) with the client.
+ * rehandshake, if TLS 1.2 or older is in use. With TLS 1.3, this will
+ * instead perform a rekey.
*
* #GTlsConnection::accept_certificate may be emitted during the
* handshake.
diff --git a/gio/gunixvolume.c b/gio/gunixvolume.c
index b54d1fd6e..a3768e11d 100644
--- a/gio/gunixvolume.c
+++ b/gio/gunixvolume.c
@@ -274,6 +274,7 @@ eject_mount_done (GObject *source,
GTask *task = user_data;
GError *error = NULL;
gchar *stderr_str;
+ GUnixVolume *unix_volume;
if (!g_subprocess_communicate_utf8_finish (subprocess, result, NULL, &stderr_str, &error))
{
@@ -286,8 +287,12 @@ eject_mount_done (GObject *source,
/* ...but bad exit code */
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "%s", stderr_str);
else
- /* ...and successful exit code */
- g_task_return_boolean (task, TRUE);
+ {
+ /* ...and successful exit code */
+ unix_volume = G_UNIX_VOLUME (g_task_get_source_object (task));
+ _g_unix_volume_monitor_update (G_UNIX_VOLUME_MONITOR (unix_volume->volume_monitor));
+ g_task_return_boolean (task, TRUE);
+ }
g_free (stderr_str);
}
diff --git a/gio/gunixvolumemonitor.c b/gio/gunixvolumemonitor.c
index b7711ff52..4b99423d7 100644
--- a/gio/gunixvolumemonitor.c
+++ b/gio/gunixvolumemonitor.c
@@ -183,15 +183,21 @@ g_unix_volume_monitor_class_init (GUnixVolumeMonitorClass *klass)
native_class->get_mount_for_mount_path = get_mount_for_mount_path;
}
+void
+_g_unix_volume_monitor_update (GUnixVolumeMonitor *unix_monitor)
+{
+ /* Update both to make sure volumes are created before mounts */
+ update_volumes (unix_monitor);
+ update_mounts (unix_monitor);
+}
+
static void
mountpoints_changed (GUnixMountMonitor *mount_monitor,
gpointer user_data)
{
GUnixVolumeMonitor *unix_monitor = user_data;
- /* Update both to make sure volumes are created before mounts */
- update_volumes (unix_monitor);
- update_mounts (unix_monitor);
+ _g_unix_volume_monitor_update (unix_monitor);
}
static void
@@ -200,9 +206,7 @@ mounts_changed (GUnixMountMonitor *mount_monitor,
{
GUnixVolumeMonitor *unix_monitor = user_data;
- /* Update both to make sure volumes are created before mounts */
- update_volumes (unix_monitor);
- update_mounts (unix_monitor);
+ _g_unix_volume_monitor_update (unix_monitor);
}
static void
@@ -219,8 +223,7 @@ g_unix_volume_monitor_init (GUnixVolumeMonitor *unix_monitor)
"mountpoints-changed", G_CALLBACK (mountpoints_changed),
unix_monitor);
- update_volumes (unix_monitor);
- update_mounts (unix_monitor);
+ _g_unix_volume_monitor_update (unix_monitor);
}
GVolumeMonitor *
diff --git a/gio/gunixvolumemonitor.h b/gio/gunixvolumemonitor.h
index 4f54fc23c..14e07fb9f 100644
--- a/gio/gunixvolumemonitor.h
+++ b/gio/gunixvolumemonitor.h
@@ -55,6 +55,7 @@ GType _g_unix_volume_monitor_get_type (void) G_GN
GVolumeMonitor * _g_unix_volume_monitor_new (void);
GUnixVolume * _g_unix_volume_monitor_lookup_volume_for_mount_path (GUnixVolumeMonitor *monitor,
const char *mount_path);
+void _g_unix_volume_monitor_update (GUnixVolumeMonitor *monitor);
G_END_DECLS
diff --git a/gio/gvdb/gvdb-builder.c b/gio/gvdb/gvdb-builder.c
index 8b9baa007..2383e6002 100644
--- a/gio/gvdb/gvdb-builder.c
+++ b/gio/gvdb/gvdb-builder.c
@@ -339,6 +339,13 @@ file_builder_allocate_for_hash (FileBuilder *fb,
#undef chunk
memset (*bloom_filter, 0, n_bloom_words * sizeof (guint32_le));
+
+ /* NOTE - the code to actually fill in the bloom filter here is missing.
+ * Patches welcome!
+ *
+ * http://en.wikipedia.org/wiki/Bloom_filter
+ * http://0pointer.de/blog/projects/bloom.html
+ */
}
static void
diff --git a/gio/gvdb/gvdb-reader.c b/gio/gvdb/gvdb-reader.c
index 510eba205..aa3154feb 100644
--- a/gio/gvdb/gvdb-reader.c
+++ b/gio/gvdb/gvdb-reader.c
@@ -23,15 +23,11 @@
#include <string.h>
struct _GvdbTable {
- gint ref_count;
+ GBytes *bytes;
const gchar *data;
gsize size;
- gpointer user_data;
- GvdbRefFunc ref_user_data;
- GDestroyNotify unref_user_data;
-
gboolean byteswapped;
gboolean trusted;
@@ -124,80 +120,81 @@ gvdb_table_setup_root (GvdbTable *file,
file->n_hash_items = size / sizeof (struct gvdb_hash_item);
}
-static GvdbTable *
-new_from_data (const void *data,
- gsize data_len,
- gboolean trusted,
- gpointer user_data,
- GvdbRefFunc ref,
- GDestroyNotify unref,
- const char *filename,
- GError **error)
+/**
+ * gvdb_table_new_from_bytes:
+ * @bytes: the #GBytes with the data
+ * @trusted: if the contents of @bytes are trusted
+ * @error: %NULL, or a pointer to a %NULL #GError
+ *
+ * Creates a new #GvdbTable from the contents of @bytes.
+ *
+ * This call can fail if the header contained in @bytes is invalid or if @bytes
+ * is empty; if so, %G_FILE_ERROR_INVAL will be returned.
+ *
+ * You should call gvdb_table_free() on the return result when you no
+ * longer require it.
+ *
+ * Returns: a new #GvdbTable
+ **/
+GvdbTable *
+gvdb_table_new_from_bytes (GBytes *bytes,
+ gboolean trusted,
+ GError **error)
{
+ const struct gvdb_header *header;
GvdbTable *file;
file = g_slice_new0 (GvdbTable);
- file->data = data;
- file->size = data_len;
+ file->bytes = g_bytes_ref (bytes);
+ file->data = g_bytes_get_data (bytes, &file->size);
file->trusted = trusted;
- file->ref_count = 1;
- file->ref_user_data = ref;
- file->unref_user_data = unref;
- file->user_data = user_data;
- if (sizeof (struct gvdb_header) <= file->size)
- {
- const struct gvdb_header *header = (gpointer) file->data;
+ if (file->size < sizeof (struct gvdb_header))
+ goto invalid;
- if (header->signature[0] == GVDB_SIGNATURE0 &&
- header->signature[1] == GVDB_SIGNATURE1 &&
- guint32_from_le (header->version) == 0)
- file->byteswapped = FALSE;
+ header = (gpointer) file->data;
- else if (header->signature[0] == GVDB_SWAPPED_SIGNATURE0 &&
- header->signature[1] == GVDB_SWAPPED_SIGNATURE1 &&
- guint32_from_le (header->version) == 0)
- file->byteswapped = TRUE;
+ if (header->signature[0] == GVDB_SIGNATURE0 &&
+ header->signature[1] == GVDB_SIGNATURE1 &&
+ guint32_from_le (header->version) == 0)
+ file->byteswapped = FALSE;
- else
- {
- if (filename)
- g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL,
- "%s: invalid header", filename);
- else
- g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL,
- "invalid gvdb header");
- g_slice_free (GvdbTable, file);
- if (unref)
- unref (user_data);
-
- return NULL;
- }
+ else if (header->signature[0] == GVDB_SWAPPED_SIGNATURE0 &&
+ header->signature[1] == GVDB_SWAPPED_SIGNATURE1 &&
+ guint32_from_le (header->version) == 0)
+ file->byteswapped = TRUE;
- gvdb_table_setup_root (file, &header->root);
- }
+ else
+ goto invalid;
+
+ gvdb_table_setup_root (file, &header->root);
return file;
+
+invalid:
+ g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, "invalid gvdb header");
+
+ g_bytes_unref (file->bytes);
+
+ g_slice_free (GvdbTable, file);
+
+ return NULL;
}
/**
* gvdb_table_new:
- * @filename: the path to the hash file
- * @trusted: if the contents of @filename are trusted
+ * @filename: a filename
+ * @trusted: if the contents of @bytes are trusted
* @error: %NULL, or a pointer to a %NULL #GError
*
- * Creates a new #GvdbTable from the contents of the file found at
- * @filename.
+ * Creates a new #GvdbTable using the #GMappedFile for @filename as the
+ * #GBytes.
*
- * The only time this function fails is if the file cannot be opened.
+ * This function will fail if the file cannot be opened.
* In that case, the #GError that is returned will be an error from
* g_mapped_file_new().
*
- * An empty or otherwise corrupted file is considered to be a valid
- * #GvdbTable with no entries.
- *
- * You should call gvdb_table_unref() on the return result when you no
- * longer require it.
+ * An empty or corrupt file will result in %G_FILE_ERROR_INVAL.
*
* Returns: a new #GvdbTable
**/
@@ -207,53 +204,21 @@ gvdb_table_new (const gchar *filename,
GError **error)
{
GMappedFile *mapped;
+ GvdbTable *table;
+ GBytes *bytes;
- if ((mapped = g_mapped_file_new (filename, FALSE, error)) == NULL)
+ mapped = g_mapped_file_new (filename, FALSE, error);
+ if (!mapped)
return NULL;
- return new_from_data (g_mapped_file_get_contents (mapped),
- g_mapped_file_get_length (mapped),
- trusted,
- mapped,
- (GvdbRefFunc)g_mapped_file_ref,
- (GDestroyNotify)g_mapped_file_unref,
- filename,
- error);
-}
+ bytes = g_mapped_file_get_bytes (mapped);
+ table = gvdb_table_new_from_bytes (bytes, trusted, error);
+ g_mapped_file_unref (mapped);
+ g_bytes_unref (bytes);
-/**
- * gvdb_table_new_from_data:
- * @data: the data
- * @data_len: the length of @data in bytes
- * @trusted: if the contents of @data are trusted
- * @user_data: User supplied data that owns @data
- * @ref: Ref function for @user_data
- * @unref: Unref function for @user_data
- *
- * Creates a new #GvdbTable from the data in @data.
- *
- * An empty or otherwise corrupted data is considered to be a valid
- * #GvdbTable with no entries.
- *
- * You should call gvdb_table_unref() on the return result when you no
- * longer require it.
- *
- * Returns: a new #GvdbTable
- **/
-GvdbTable *
-gvdb_table_new_from_data (const void *data,
- gsize data_len,
- gboolean trusted,
- gpointer user_data,
- GvdbRefFunc ref,
- GDestroyNotify unref,
- GError **error)
-{
- return new_from_data (data, data_len,
- trusted,
- user_data, ref, unref,
- NULL,
- error);
+ g_prefix_error (error, "%s: ", filename);
+
+ return table;
}
static gboolean
@@ -346,18 +311,6 @@ gvdb_table_lookup (GvdbTable *file,
return NULL;
}
-static const struct gvdb_hash_item *
-gvdb_table_get_item (GvdbTable *table,
- guint32_le item_no)
-{
- guint32 item_no_native = guint32_from_le (item_no);
-
- if G_LIKELY (item_no_native < table->n_hash_items)
- return table->hash_items + item_no_native;
-
- return NULL;
-}
-
static gboolean
gvdb_table_list_from_item (GvdbTable *table,
const struct gvdb_hash_item *item,
@@ -376,6 +329,155 @@ gvdb_table_list_from_item (GvdbTable *table,
return TRUE;
}
+/**
+ * gvdb_table_get_names:
+ * @table: a #GvdbTable
+ * @length: the number of items returned, or %NULL
+ *
+ * Gets a list of all names contained in @table.
+ *
+ * No call to gvdb_table_get_table(), gvdb_table_list() or
+ * gvdb_table_get_value() will succeed unless it is for one of the
+ * names returned by this function.
+ *
+ * Note that some names that are returned may still fail for all of the
+ * above calls in the case of the corrupted file. Note also that the
+ * returned strings may not be utf8.
+ *
+ * Returns: a %NULL-terminated list of strings, of length @length
+ **/
+gchar **
+gvdb_table_get_names (GvdbTable *table,
+ gint *length)
+{
+ gchar **names;
+ gint n_names;
+ gint filled;
+ gint total;
+ gint i;
+
+ /* We generally proceed by iterating over the list of items in the
+ * hash table (in order of appearance) recording them into an array.
+ *
+ * Each item has a parent item (except root items). The parent item
+ * forms part of the name of the item. We could go fetching the
+ * parent item chain at the point that we encounter each item but then
+ * we would need to implement some sort of recursion along with checks
+ * for self-referential items.
+ *
+ * Instead, we do a number of passes. Each pass will build up one
+ * level of names (starting from the root). We continue to do passes
+ * until no more items are left. The first pass will only add root
+ * items and each further pass will only add items whose direct parent
+ * is an item added in the immediately previous pass. It's also
+ * possible that items get filled if they follow their parent within a
+ * particular pass.
+ *
+ * At most we will have a number of passes equal to the depth of the
+ * tree. Self-referential items will never be filled in (since their
+ * parent will have never been filled in). We continue until we have
+ * a pass that fills in no additional items.
+ *
+ * This takes an O(n) algorithm and turns it into O(n*m) where m is
+ * the depth of the tree, but in all sane cases the tree won't be very
+ * deep and the constant factor of this algorithm is lower (and the
+ * complexity of coding it, as well).
+ */
+
+ n_names = table->n_hash_items;
+ names = g_new0 (gchar *, n_names + 1);
+
+ /* 'names' starts out all-NULL. On each pass we record the number
+ * of items changed from NULL to non-NULL in 'filled' so we know if we
+ * should repeat the loop. 'total' counts the total number of items
+ * filled. If 'total' ends up equal to 'n_names' then we know that
+ * 'names' has been completely filled.
+ */
+
+ total = 0;
+ do
+ {
+ /* Loop until we have filled no more entries */
+ filled = 0;
+
+ for (i = 0; i < n_names; i++)
+ {
+ const struct gvdb_hash_item *item = &table->hash_items[i];
+ const gchar *name;
+ gsize name_length;
+ guint32 parent;
+
+ /* already got it on a previous pass */
+ if (names[i] != NULL)
+ continue;
+
+ parent = guint32_from_le (item->parent);
+
+ if (parent == 0xffffffffu)
+ {
+ /* it's a root item */
+ name = gvdb_table_item_get_key (table, item, &name_length);
+
+ if (name != NULL)
+ {
+ names[i] = g_strndup (name, name_length);
+ filled++;
+ }
+ }
+
+ else if (parent < n_names && names[parent] != NULL)
+ {
+ /* It's a non-root item whose parent was filled in already.
+ *
+ * Calculate the name of this item by combining it with
+ * its parent name.
+ */
+ name = gvdb_table_item_get_key (table, item, &name_length);
+
+ if (name != NULL)
+ {
+ const gchar *parent_name = names[parent];
+ gsize parent_length;
+ gchar *fullname;
+
+ parent_length = strlen (parent_name);
+ fullname = g_malloc (parent_length + name_length + 1);
+ memcpy (fullname, parent_name, parent_length);
+ memcpy (fullname + parent_length, name, name_length);
+ fullname[parent_length + name_length] = '\0';
+ names[i] = fullname;
+ filled++;
+ }
+ }
+ }
+
+ total += filled;
+ }
+ while (filled && total < n_names);
+
+ /* If the table was corrupted then 'names' may have holes in it.
+ * Collapse those.
+ */
+ if G_UNLIKELY (total != n_names)
+ {
+ GPtrArray *fixed_names;
+
+ fixed_names = g_ptr_array_new ();
+ for (i = 0; i < n_names; i++)
+ if (names[i] != NULL)
+ g_ptr_array_add (fixed_names, names[i]);
+
+ g_free (names);
+ n_names = fixed_names->len;
+ g_ptr_array_add (fixed_names, NULL);
+ names = (gchar **) g_ptr_array_free (fixed_names, FALSE);
+ }
+
+ if (length)
+ *length = n_names;
+
+ return names;
+}
/**
* gvdb_table_list:
@@ -457,7 +559,15 @@ gboolean
gvdb_table_has_value (GvdbTable *file,
const gchar *key)
{
- return gvdb_table_lookup (file, key, 'v') != NULL;
+ static const struct gvdb_hash_item *item;
+ gsize size;
+
+ item = gvdb_table_lookup (file, key, 'v');
+
+ if (item == NULL)
+ return FALSE;
+
+ return gvdb_table_dereference (file, &item->value.pointer, 8, &size) != NULL;
}
static GVariant *
@@ -466,6 +576,7 @@ gvdb_table_value_from_item (GvdbTable *table,
{
GVariant *variant, *value;
gconstpointer data;
+ GBytes *bytes;
gsize size;
data = gvdb_table_dereference (table, &item->value.pointer, 8, &size);
@@ -473,12 +584,11 @@ gvdb_table_value_from_item (GvdbTable *table,
if G_UNLIKELY (data == NULL)
return NULL;
- variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT,
- data, size, table->trusted,
- table->unref_user_data,
- table->ref_user_data ? table->ref_user_data (table->user_data) : table->user_data);
+ bytes = g_bytes_new_from_bytes (table->bytes, ((gchar *) data) - table->data, size);
+ variant = g_variant_new_from_bytes (G_VARIANT_TYPE_VARIANT, bytes, table->trusted);
value = g_variant_get_variant (variant);
g_variant_unref (variant);
+ g_bytes_unref (bytes);
return value;
}
@@ -562,7 +672,7 @@ gvdb_table_get_raw_value (GvdbTable *table,
* contained in the file. This newly-created #GvdbTable does not depend
* on the continued existence of @file.
*
- * You should call gvdb_table_unref() on the return result when you no
+ * You should call gvdb_table_free() on the return result when you no
* longer require it.
*
* Returns: a new #GvdbTable, or %NULL
@@ -580,14 +690,11 @@ gvdb_table_get_table (GvdbTable *file,
return NULL;
new = g_slice_new0 (GvdbTable);
- new->user_data = file->ref_user_data ? file->ref_user_data (file->user_data) : file->user_data;
- new->ref_user_data = file->ref_user_data;
- new->unref_user_data = file->unref_user_data;
+ new->bytes = g_bytes_ref (file->bytes);
new->byteswapped = file->byteswapped;
new->trusted = file->trusted;
new->data = file->data;
new->size = file->size;
- new->ref_count = 1;
gvdb_table_setup_root (new, &item->value.pointer);
@@ -595,38 +702,16 @@ gvdb_table_get_table (GvdbTable *file,
}
/**
- * gvdb_table_ref:
+ * gvdb_table_free:
* @file: a #GvdbTable
*
- * Increases the reference count on @file.
- *
- * Returns: a new reference on @file
- **/
-GvdbTable *
-gvdb_table_ref (GvdbTable *file)
-{
- g_atomic_int_inc (&file->ref_count);
-
- return file;
-}
-
-/**
- * gvdb_table_unref:
- * @file: a #GvdbTable
- *
- * Decreases the reference count on @file, possibly freeing it.
- *
- * Since: 2.26
+ * Frees @file.
**/
void
-gvdb_table_unref (GvdbTable *file)
+gvdb_table_free (GvdbTable *file)
{
- if (g_atomic_int_dec_and_test (&file->ref_count))
- {
- if (file->unref_user_data)
- file->unref_user_data (file->user_data);
- g_slice_free (GvdbTable, file);
- }
+ g_bytes_unref (file->bytes);
+ g_slice_free (GvdbTable, file);
}
/**
@@ -646,105 +731,3 @@ gvdb_table_is_valid (GvdbTable *table)
{
return !!*table->data;
}
-
-/**
- * gvdb_table_walk:
- * @table: a #GvdbTable
- * @key: a key corresponding to a list
- * @open_func: the #GvdbWalkOpenFunc
- * @value_func: the #GvdbWalkValueFunc
- * @close_func: the #GvdbWalkCloseFunc
- * @user_data: data to pass to the callbacks
- *
- * Looks up the list at @key and iterate over the items in it.
- *
- * First, @open_func is called to signal that we are starting to iterate over
- * the list. Then the list is iterated. When all items in the list have been
- * iterated over, the @close_func is called.
- *
- * When iterating, if a given item in the list is a value then @value_func is
- * called.
- *
- * If a given item in the list is itself a list then @open_func is called. If
- * that function returns %TRUE then the walk begins iterating the items in the
- * sublist, until there are no more items, at which point a matching
- * @close_func call is made. If @open_func returns %FALSE then no iteration of
- * the sublist occurs and no corresponding @close_func call is made.
- **/
-void
-gvdb_table_walk (GvdbTable *table,
- const gchar *key,
- GvdbWalkOpenFunc open_func,
- GvdbWalkValueFunc value_func,
- GvdbWalkCloseFunc close_func,
- gpointer user_data)
-{
- const struct gvdb_hash_item *item;
- const guint32_le *pointers[64];
- const guint32_le *enders[64];
- gsize name_lengths[64];
- gint index = 0;
-
- item = gvdb_table_lookup (table, key, 'L');
- name_lengths[0] = 0;
- pointers[0] = NULL;
- enders[0] = NULL;
- goto start_here;
-
- while (index)
- {
- close_func (name_lengths[index], user_data);
- index--;
-
- while (pointers[index] < enders[index])
- {
- const gchar *name;
- gsize name_len;
-
- item = gvdb_table_get_item (table, *pointers[index]++);
- start_here:
-
- if (item != NULL &&
- (name = gvdb_table_item_get_key (table, item, &name_len)))
- {
- if (item->type == 'L')
- {
- if (open_func (name, name_len, user_data))
- {
- guint length = 0;
-
- index++;
- g_assert (index < 64);
-
- gvdb_table_list_from_item (table, item,
- &pointers[index],
- &length);
- enders[index] = pointers[index] + length;
- name_lengths[index] = name_len;
- }
- }
- else if (item->type == 'v')
- {
- GVariant *value;
-
- value = gvdb_table_value_from_item (table, item);
-
- if (value != NULL)
- {
- if (table->byteswapped)
- {
- GVariant *tmp;
-
- tmp = g_variant_byteswap (value);
- g_variant_unref (value);
- value = tmp;
- }
-
- value_func (name, name_len, value, user_data);
- g_variant_unref (value);
- }
- }
- }
- }
- }
-}
diff --git a/gio/gvdb/gvdb-reader.h b/gio/gvdb/gvdb-reader.h
index 449241eaa..39827737d 100644
--- a/gio/gvdb/gvdb-reader.h
+++ b/gio/gvdb/gvdb-reader.h
@@ -24,27 +24,21 @@
typedef struct _GvdbTable GvdbTable;
-typedef gpointer (*GvdbRefFunc) (gpointer data);
-
G_BEGIN_DECLS
G_GNUC_INTERNAL
-GvdbTable * gvdb_table_new (const gchar *filename,
+GvdbTable * gvdb_table_new_from_bytes (GBytes *bytes,
gboolean trusted,
GError **error);
G_GNUC_INTERNAL
-GvdbTable * gvdb_table_new_from_data (const void *data,
- gsize data_len,
+GvdbTable * gvdb_table_new (const gchar *filename,
gboolean trusted,
- gpointer user_data,
- GvdbRefFunc ref,
- GDestroyNotify unref,
- GError **error);
+ GError **error);
G_GNUC_INTERNAL
-GvdbTable * gvdb_table_ref (GvdbTable *table);
+void gvdb_table_free (GvdbTable *table);
G_GNUC_INTERNAL
-void gvdb_table_unref (GvdbTable *table);
-
+gchar ** gvdb_table_get_names (GvdbTable *table,
+ gint *length);
G_GNUC_INTERNAL
gchar ** gvdb_table_list (GvdbTable *table,
const gchar *key);
@@ -61,28 +55,9 @@ GVariant * gvdb_table_get_value (GvdbTab
G_GNUC_INTERNAL
gboolean gvdb_table_has_value (GvdbTable *table,
const gchar *key);
-
G_GNUC_INTERNAL
gboolean gvdb_table_is_valid (GvdbTable *table);
-typedef void (*GvdbWalkValueFunc) (const gchar *name,
- gsize name_len,
- GVariant *value,
- gpointer user_data);
-typedef gboolean (*GvdbWalkOpenFunc) (const gchar *name,
- gsize name_len,
- gpointer user_data);
-typedef void (*GvdbWalkCloseFunc) (gsize name_len,
- gpointer user_data);
-
-G_GNUC_INTERNAL
-void gvdb_table_walk (GvdbTable *table,
- const gchar *key,
- GvdbWalkOpenFunc open_func,
- GvdbWalkValueFunc value_func,
- GvdbWalkCloseFunc close_func,
- gpointer user_data);
-
G_END_DECLS
#endif /* __gvdb_reader_h__ */
diff --git a/gio/gvdb/gvdb.doap b/gio/gvdb/gvdb.doap
index b4ae60c8c..8c5f3e802 100644
--- a/gio/gvdb/gvdb.doap
+++ b/gio/gvdb/gvdb.doap
@@ -23,9 +23,34 @@
<maintainer>
<foaf:Person>
- <foaf:name>Ryan Lortie</foaf:name>
- <foaf:mbox rdf:resource='mailto:desrt@desrt.ca'/>
- <gnome:userid>ryanl</gnome:userid>
+ <foaf:name>Matthias Clasen</foaf:name>
+ <foaf:mbox rdf:resource="mailto:mclasen@redhat.com"/>
+ <gnome:userid>matthiasc</gnome:userid>
+ </foaf:Person>
+ </maintainer>
+
+ <maintainer>
+ <foaf:Person>
+ <foaf:name>Allison Ryan Lortie</foaf:name>
+ <foaf:mbox rdf:resource="mailto:desrt@desrt.ca"/>
+ <gnome:userid>desrt</gnome:userid>
+ </foaf:Person>
+ </maintainer>
+
+ <maintainer>
+ <foaf:Person>
+ <foaf:name>Philip Withnall</foaf:name>
+ <foaf:mbox rdf:resource="mailto:philip@tecnocode.co.uk"/>
+ <foaf:mbox rdf:resource="mailto:withnall@endlessm.com"/>
+ <gnome:userid>pwithnall</gnome:userid>
+ </foaf:Person>
+ </maintainer>
+
+ <maintainer>
+ <foaf:Person>
+ <foaf:name>Emmanuele Bassi</foaf:name>
+ <foaf:mbox rdf:resource="mailto:ebassi@gnome.org"/>
+ <gnome:userid>ebassi</gnome:userid>
</foaf:Person>
</maintainer>
diff --git a/gio/meson.build b/gio/meson.build
index a6af822b5..4b2c8f2ca 100644
--- a/gio/meson.build
+++ b/gio/meson.build
@@ -152,6 +152,11 @@ if host_system != 'windows'
glib_conf.set('HAVE_SIOCGIFADDR', '/**/')
endif
+endif
+
+if host_system.contains('android')
+ # struct ip_mreq_source definition is broken on Android NDK <= r16
+ # See https://bugzilla.gnome.org/show_bug.cgi?id=740791
if not cc.compiles('''#include <netinet/in.h>
int main(int argc, char ** argv) {
struct ip_mreq_source mc_req_src;
@@ -161,7 +166,6 @@ if host_system != 'windows'
name : 'ip_mreq_source.imr_interface has s_addr member')
glib_conf.set('BROKEN_IP_MREQ_SOURCE_STRUCT', 1)
endif
-
endif
gnetworking_h_conf.set('WSPIAPI_INCLUDE', gnetworking_h_wspiapi_include)
diff --git a/gio/tests/Makefile.am b/gio/tests/Makefile.am
index e3e8da05a..1f0bed7b6 100644
--- a/gio/tests/Makefile.am
+++ b/gio/tests/Makefile.am
@@ -383,7 +383,10 @@ CLEANFILES += \
org.gtk.test.enums.xml \
gsettings.store \
gschemas.compiled \
- schema-source/gschemas.compiled
+ schema-source/gschemas.compiled \
+ schema-source-corrupt/gschemas.compiled \
+ schema-source-empty/gschemas.compiled \
+ $(NULL)
test_programs += gdbus-connection-flush
gdbus_connection_flush_SOURCES = \
diff --git a/gio/tests/g-icon.c b/gio/tests/g-icon.c
index 598ae94b8..7f87e4952 100644
--- a/gio/tests/g-icon.c
+++ b/gio/tests/g-icon.c
@@ -108,9 +108,18 @@ test_g_icon_to_string (void)
g_object_unref (location);
#endif
+ icon = g_themed_icon_new_with_default_fallbacks ("some-icon-symbolic");
+ g_themed_icon_append_name (G_THEMED_ICON (icon), "some-other-icon");
+ data = g_icon_to_string (icon);
+ g_assert_cmpstr (data, ==, ". GThemedIcon "
+ "some-icon-symbolic some-symbolic some-other-icon some-other some "
+ "some-icon some-other-icon-symbolic some-other-symbolic");
+ g_free (data);
+ g_object_unref (icon);
+
icon = g_themed_icon_new ("network-server");
data = g_icon_to_string (icon);
- g_assert_cmpstr (data, ==, "network-server");
+ g_assert_cmpstr (data, ==, ". GThemedIcon network-server network-server-symbolic");
icon2 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon, icon2));
@@ -371,7 +380,7 @@ test_themed_icon (void)
{
GIcon *icon1, *icon2, *icon3, *icon4;
const gchar *const *names;
- const gchar *names2[] = { "first", "testicon", "last", NULL };
+ const gchar *names2[] = { "first-symbolic", "testicon", "last", NULL };
gchar *str;
gboolean fallbacks;
GVariant *variant;
@@ -382,17 +391,21 @@ test_themed_icon (void)
g_assert (!fallbacks);
names = g_themed_icon_get_names (G_THEMED_ICON (icon1));
- g_assert_cmpint (g_strv_length ((gchar **)names), ==, 1);
+ g_assert_cmpint (g_strv_length ((gchar **)names), ==, 2);
g_assert_cmpstr (names[0], ==, "testicon");
+ g_assert_cmpstr (names[1], ==, "testicon-symbolic");
- g_themed_icon_prepend_name (G_THEMED_ICON (icon1), "first");
+ g_themed_icon_prepend_name (G_THEMED_ICON (icon1), "first-symbolic");
g_themed_icon_append_name (G_THEMED_ICON (icon1), "last");
names = g_themed_icon_get_names (G_THEMED_ICON (icon1));
- g_assert_cmpint (g_strv_length ((gchar **)names), ==, 3);
- g_assert_cmpstr (names[0], ==, "first");
+ g_assert_cmpint (g_strv_length ((gchar **)names), ==, 6);
+ g_assert_cmpstr (names[0], ==, "first-symbolic");
g_assert_cmpstr (names[1], ==, "testicon");
g_assert_cmpstr (names[2], ==, "last");
- g_assert_cmpuint (g_icon_hash (icon1), ==, 2400773466U);
+ g_assert_cmpstr (names[3], ==, "first");
+ g_assert_cmpstr (names[4], ==, "testicon-symbolic");
+ g_assert_cmpstr (names[5], ==, "last-symbolic");
+ g_assert_cmpuint (g_icon_hash (icon1), ==, 1812785139);
icon2 = g_themed_icon_new_from_names ((gchar**)names2, -1);
g_assert (g_icon_equal (icon1, icon2));
@@ -448,11 +461,11 @@ test_emblemed_icon (void)
emblem = emblems->data;
g_assert (g_emblem_get_icon (emblem) == icon2);
- g_assert (g_emblem_get_origin (emblem) == G_EMBLEM_ORIGIN_TAG);
+ g_assert (g_emblem_get_origin (emblem) == G_EMBLEM_ORIGIN_UNKNOWN);
emblem = emblems->next->data;
g_assert (g_emblem_get_icon (emblem) == icon2);
- g_assert (g_emblem_get_origin (emblem) == G_EMBLEM_ORIGIN_UNKNOWN);
+ g_assert (g_emblem_get_origin (emblem) == G_EMBLEM_ORIGIN_TAG);
g_emblemed_icon_clear_emblems (G_EMBLEMED_ICON (icon4));
g_assert (g_emblemed_icon_get_emblems (G_EMBLEMED_ICON (icon4)) == NULL);
diff --git a/gio/tests/gdbus-unix-addresses.c b/gio/tests/gdbus-unix-addresses.c
index 746a7c2a7..531ce7a85 100644
--- a/gio/tests/gdbus-unix-addresses.c
+++ b/gio/tests/gdbus-unix-addresses.c
@@ -128,6 +128,7 @@ test_x11_autolaunch (void)
g_unsetenv ("DISPLAY");
g_unsetenv ("DBUS_SESSION_BUS_ADDRESS");
g_unsetenv ("XDG_RUNTIME_DIR");
+ g_unsetenv ("G_MESSAGES_DEBUG");
set_up_mock_dbus_launch ();
print_address ();
diff --git a/gio/tests/gnotification.c b/gio/tests/gnotification.c
index c896af684..80d476d5a 100644
--- a/gio/tests/gnotification.c
+++ b/gio/tests/gnotification.c
@@ -219,7 +219,8 @@ test_properties (void)
g_assert (G_IS_THEMED_ICON (rn->icon));
names = g_themed_icon_get_names (G_THEMED_ICON (rn->icon));
g_assert_cmpstr (names[0], ==, "i-c-o-n");
- g_assert (names[1] == NULL);
+ g_assert_cmpstr (names[1], ==, "i-c-o-n-symbolic");
+ g_assert_null (names[2]);
g_assert (rn->priority == G_NOTIFICATION_PRIORITY_HIGH);
g_assert_cmpint (rn->buttons->len, ==, 1);
diff --git a/gio/tests/gsettings.c b/gio/tests/gsettings.c
index 2d18d4dd2..852a8b710 100644
--- a/gio/tests/gsettings.c
+++ b/gio/tests/gsettings.c
@@ -2353,6 +2353,18 @@ test_schema_source (void)
g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT);
g_clear_error (&error);
+ /* Test error handling of corrupt compiled files. */
+ source = g_settings_schema_source_new_from_directory ("schema-source-corrupt", parent, TRUE, &error);
+ g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
+ g_assert_null (source);
+ g_clear_error (&error);
+
+ /* Test error handling of empty compiled files. */
+ source = g_settings_schema_source_new_from_directory ("schema-source-empty", parent, TRUE, &error);
+ g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
+ g_assert_null (source);
+ g_clear_error (&error);
+
/* create a source with the parent */
source = g_settings_schema_source_new_from_directory ("schema-source", parent, TRUE, &error);
g_assert_no_error (error);
@@ -2770,6 +2782,12 @@ main (int argc, char *argv[])
if (!g_test_subprocess ())
{
+ GError *local_error = NULL;
+ /* A GVDB header is 6 guint32s, and requires a magic number in the first
+ * two guint32s. A set of zero bytes of a greater length is considered
+ * corrupt. */
+ const guint8 gschemas_compiled_corrupt[sizeof (guint32) * 7] = { 0, };
+
backend_set = g_getenv ("GSETTINGS_BACKEND") != NULL;
g_setenv ("XDG_DATA_DIRS", ".", TRUE);
@@ -2821,6 +2839,21 @@ main (int argc, char *argv[])
"--schema-file=" SRCDIR "/org.gtk.schemasourcecheck.gschema.xml",
NULL, NULL, &result, NULL));
g_assert (result == 0);
+
+ g_remove ("schema-source-corrupt/gschemas.compiled");
+ g_mkdir ("schema-source-corrupt", 0777);
+ g_file_set_contents ("schema-source-corrupt/gschemas.compiled",
+ (const gchar *) gschemas_compiled_corrupt,
+ sizeof (gschemas_compiled_corrupt),
+ &local_error);
+ g_assert_no_error (local_error);
+
+ g_remove ("schema-source-empty/gschemas.compiled");
+ g_mkdir ("schema-source-empty", 0777);
+ g_file_set_contents ("schema-source-empty/gschemas.compiled",
+ "", 0,
+ &local_error);
+ g_assert_no_error (local_error);
}
g_test_add_func ("/gsettings/basic", test_basic);
diff --git a/gio/tests/meson.build b/gio/tests/meson.build
index 85d31d622..4e5ad25df 100644
--- a/gio/tests/meson.build
+++ b/gio/tests/meson.build
@@ -15,69 +15,67 @@ giotypefuncs_inc = custom_target(
command: [gengiotypefuncs_prog, '@OUTPUT@', '@INPUT@'])
# Test programs buildable on all platforms
-gio_tests = [
- 'appmonitor',
- 'async-close-output-stream',
- 'async-splice-output-stream',
- 'buffered-input-stream',
- 'buffered-output-stream',
- 'cancellable',
- 'contexts',
- 'contenttype',
- 'converter-stream',
- 'credentials',
- 'data-input-stream',
- 'data-output-stream',
- 'defaultvalue',
- 'fileattributematcher',
- 'filter-streams',
- 'giomodule',
- 'gsubprocess',
- 'g-file',
- 'g-file-info',
- 'g-icon',
- 'gdbus-addresses',
- 'gdbus-message',
- 'inet-address',
- 'io-stream',
- 'memory-input-stream',
- 'memory-output-stream',
- 'monitor',
- 'mount-operation',
- 'network-address',
- 'network-monitor',
- 'network-monitor-race',
- 'permission',
- 'pollable',
- 'proxy-test',
- 'readwrite',
- 'simple-async-result',
- 'simple-proxy',
- 'sleepy-stream',
- 'socket',
- 'socket-listener',
- 'socket-service',
- 'srvtarget',
- 'task',
- 'vfs',
- 'volumemonitor',
- 'glistmodel',
- 'testfilemonitor',
- 'thumbnail-verification',
- 'tls-certificate',
- 'tls-interaction',
-]
-slow_tests = [
- 'actions',
- 'gdbus-export',
- 'gdbus-threading',
- 'testfilemonitor',
-]
-
-test_extra_programs = [
- ['gdbus-connection-flush-helper'],
- ['gdbus-testserver'],
-]
+# FIXME: We are using list of dictionnaries until we can depend on Meson 0.48.0
+# that supports '+=' operator on dictionnaries.
+gio_tests = [{
+ 'appmonitor' : {},
+ 'async-close-output-stream' : {},
+ 'async-splice-output-stream' : {},
+ 'buffered-input-stream' : {},
+ 'buffered-output-stream' : {},
+ 'cancellable' : {},
+ 'contexts' : {},
+ 'contenttype' : {},
+ 'converter-stream' : {},
+ 'credentials' : {},
+ 'data-input-stream' : {},
+ 'data-output-stream' : {},
+ 'defaultvalue' : {'extra_sources' : [giotypefuncs_inc]},
+ 'fileattributematcher' : {},
+ 'filter-streams' : {},
+ 'giomodule' : {},
+ 'gsubprocess' : {},
+ 'g-file' : {},
+ 'g-file-info' : {},
+ 'g-icon' : {},
+ 'gdbus-addresses' : {},
+ 'gdbus-message' : {},
+ 'inet-address' : {},
+ 'io-stream' : {},
+ 'memory-input-stream' : {},
+ 'memory-output-stream' : {},
+ 'monitor' : {},
+ 'mount-operation' : {},
+ 'network-address' : {},
+ 'network-monitor' : {},
+ 'network-monitor-race' : {},
+ 'permission' : {},
+ 'pollable' : {},
+ 'proxy-test' : {},
+ 'readwrite' : {},
+ 'simple-async-result' : {},
+ 'simple-proxy' : {},
+ 'sleepy-stream' : {},
+ 'socket' : {},
+ 'socket-listener' : {},
+ 'socket-service' : {},
+ 'srvtarget' : {},
+ 'task' : {},
+ 'vfs' : {},
+ 'volumemonitor' : {},
+ 'glistmodel' : {},
+ 'testfilemonitor' : {'suite' : ['slow']},
+ 'thumbnail-verification' : {},
+ 'tls-certificate' : {'extra_sources' : ['gtesttlsbackend.c']},
+ 'tls-interaction' : {'extra_sources' : ['gtesttlsbackend.c']},
+}]
+
+# FIXME: We are using list of dictionnaries until we can depend on Meson 0.48.0
+# that supports '+=' operator on dictionnaries.
+test_extra_programs = [{
+ 'gdbus-connection-flush-helper' : {},
+ 'gdbus-testserver' : {},
+}]
test_env = environment()
test_env.set('G_TEST_SRCDIR', meson.current_source_dir())
@@ -110,49 +108,57 @@ endif
if dbus1_dep.found()
glib_conf.set('HAVE_DBUS1', 1)
- exe = executable('gdbus-serialization',
- 'gdbus-serialization.c', 'gdbus-tests.c',
- install : false,
- c_args : test_c_args,
- dependencies : common_gio_tests_deps + [dbus1_dep])
- test('gdbus-serialization', exe, env : test_env, suite : ['gio'])
+ gio_tests += [{
+ 'gdbus-serialization' : {
+ 'extra_sources' : ['gdbus-tests.c'],
+ 'dependencies' : [dbus1_dep],
+ }
+ }]
endif
# Test programs buildable on UNIX only
if host_machine.system() != 'windows'
- gio_tests += [
- 'file',
- 'gdbus-peer',
- 'gdbus-peer-object-manager',
- 'live-g-file',
- 'socket-address',
- 'stream-rw_all',
- 'unix-fd',
- 'unix-mounts',
- 'unix-streams',
- 'g-file-info-filesystem-readonly',
- 'gschema-compile',
- 'trash',
- ]
+ gio_tests += [{
+ 'file' : {},
+ 'gdbus-peer' : {'dependencies' : [libgdbus_example_objectmanager_dep]},
+ 'gdbus-peer-object-manager' : {},
+ 'live-g-file' : {},
+ 'socket-address' : {},
+ 'stream-rw_all' : {},
+ 'unix-fd' : {},
+ 'unix-mounts' : {},
+ 'unix-streams' : {},
+ 'g-file-info-filesystem-readonly' : {},
+ 'gschema-compile' : {'install' : false},
+ 'trash' : {},
+ }]
# Uninstalled because of the check-for-executable logic in DesktopAppInfo
# unable to find the installed executable
if not glib_have_cocoa
- gio_tests += [
- 'appinfo',
- 'desktop-app-info',
- ]
+ gio_tests += [{
+ 'appinfo' : {
+ 'install' : false,
+ },
+ 'desktop-app-info' : {
+ 'install' : false,
+ },
+ }]
endif
- test_extra_programs += [
- ['basic-application'],
- ['dbus-launch'],
- ['appinfo-test'],
- ]
+ test_extra_programs += [{
+ 'basic-application' : {},
+ 'dbus-launch' : {},
+ 'appinfo-test' : {},
+ }]
if not glib_have_cocoa
- test_extra_programs += [['apps']]
- gio_tests += ['mimeapps']
+ test_extra_programs += [{
+ 'apps' : {},
+ }]
+ gio_tests += [{
+ 'mimeapps' : {},
+ }]
endif
# Test programs that need to bring up a session bus (requires dbus-daemon)
@@ -181,71 +187,61 @@ if host_machine.system() != 'windows'
'--annotate', 'org.project.Bar::TestSignal[array_of_strings]', 'Key8', 'Value8',
'@INPUT@'])
- gio_dbus_tests = [
- ['actions', [], []],
- ['gdbus-auth', [], []],
- ['gdbus-bz627724', [], []],
- ['gdbus-close-pending', [], []],
- ['gdbus-connection', [], []],
- ['gdbus-connection-loss', [], []],
- ['gdbus-connection-slow', [], []],
- ['gdbus-error', [], []],
- ['gdbus-exit-on-close', [], []],
- ['gdbus-export', [], []],
- ['gdbus-introspection', [], []],
- ['gdbus-names', [], []],
- ['gdbus-proxy', [], []],
- ['gdbus-proxy-threads', [], [dbus1_dep]],
- ['gdbus-proxy-well-known-name', [], []],
- ['gdbus-test-codegen', [gdbus_test_codegen_generated], []],
- ['gdbus-threading', [], []],
- ['gmenumodel', [], []],
- ['gnotification', ['gnotification-server.c'], []],
- ]
+ extra_sources = ['gdbus-sessionbus.c', 'gdbus-tests.c']
+
+ gio_tests += [{
+ 'actions' : {
+ 'extra_sources' : extra_sources,
+ 'suite' : ['slow'],
+ },
+ 'gdbus-auth' : {'extra_sources' : extra_sources},
+ 'gdbus-bz627724' : {'extra_sources' : extra_sources},
+ 'gdbus-close-pending' : {'extra_sources' : extra_sources},
+ 'gdbus-connection' : {'extra_sources' : extra_sources},
+ 'gdbus-connection-loss' : {'extra_sources' : extra_sources},
+ 'gdbus-connection-slow' : {'extra_sources' : extra_sources},
+ 'gdbus-error' : {'extra_sources' : extra_sources},
+ 'gdbus-exit-on-close' : {'extra_sources' : extra_sources},
+ 'gdbus-export' : {
+ 'extra_sources' : extra_sources,
+ 'suite' : ['slow'],
+ },
+ 'gdbus-introspection' : {'extra_sources' : extra_sources},
+ 'gdbus-names' : {'extra_sources' : extra_sources},
+ 'gdbus-proxy' : {'extra_sources' : extra_sources},
+ 'gdbus-proxy-threads' : {
+ 'extra_sources' : extra_sources,
+ 'dependencies' : [dbus1_dep],
+ },
+ 'gdbus-proxy-well-known-name' : {'extra_sources' : extra_sources},
+ 'gdbus-test-codegen' : {
+ 'extra_sources' : [extra_sources, gdbus_test_codegen_generated],
+ },
+ 'gdbus-threading' : {
+ 'extra_sources' : extra_sources,
+ 'suite' : ['slow'],
+ },
+ 'gmenumodel' : {'extra_sources' : extra_sources},
+ 'gnotification' : {
+ 'extra_sources' : [extra_sources, 'gnotification-server.c'],
+ },
+ 'gdbus-test-codegen-old' : {
+ 'source' : 'gdbus-test-codegen.c',
+ 'extra_sources' : [extra_sources, gdbus_test_codegen_generated],
+ 'c_args' : ['-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_36',
+ '-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_36'],
+ },
+ 'gapplication' : {'extra_sources' : extra_sources},
+ 'gdbus-unix-addresses' : {},
+ }]
if not glib_have_cocoa
- gio_dbus_tests += [['dbus-appinfo', [], []]]
+ gio_tests += [{
+ 'dbus-appinfo' : {
+ 'extra_sources' : extra_sources,
+ },
+ }]
endif
-
- # separate loop because extra source files for each test
- foreach dbus_test : gio_dbus_tests
- test_name = dbus_test[0]
- extra_src = dbus_test[1]
- extra_deps = dbus_test[2]
- exe = executable(test_name, '@0@.c'.format(test_name),
- 'gdbus-sessionbus.c', 'gdbus-tests.c', extra_src,
- install : false,
- c_args : test_c_args,
- dependencies : common_gio_tests_deps + extra_deps)
- # These tests may take more than 30 seconds to run on the CI infrastructure
- if slow_tests.contains(test_name)
- test(test_name, exe, env : test_env, timeout : 120, suite : ['gio', 'slow'])
- else
- test(test_name, exe, env : test_env, suite : ['gio'])
- endif
- endforeach
-
- exe = executable('gdbus-test-codegen-old', 'gdbus-test-codegen.c',
- 'gdbus-sessionbus.c', 'gdbus-tests.c', gdbus_test_codegen_generated,
- install : false,
- c_args : test_c_args + ['-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_36', '-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_36'],
- dependencies : common_gio_tests_deps)
- test('gdbus-test-codegen-old', exe, env : test_env, suite : ['gio'])
-
- # There is already a gapplication exe target in gio so need to use a
- # different name for the unit test executable, since we can't have two
- # targets of the same name even if in different directories
- # (FIXME: just rename source file to gapplication-test.c)
- if not glib_have_cocoa
- exe = executable('gapplication-test', 'gapplication.c',
- 'gdbus-sessionbus.c', 'gdbus-tests.c',
- install : false,
- c_args : test_c_args,
- dependencies : common_gio_tests_deps)
- endif
- test('gapplication', exe, env : test_env, suite : ['gio'])
-
- gio_tests += ['gdbus-unix-addresses']
endif # have_dbus_daemon
# This test is currently unreliable
@@ -254,125 +250,100 @@ if host_machine.system() != 'windows'
c_args : test_c_args,
dependencies : common_gio_tests_deps)
- exe = executable('gdbus-connection-flush', 'gdbus-connection-flush.c',
- 'test-io-stream.c', 'test-pipe-unix.c',
- install : false,
- c_args : test_c_args,
- dependencies : common_gio_tests_deps)
- test('gdbus-connection-flush', exe, env : test_env, suite : ['gio'])
-
- exe = executable('gdbus-non-socket', 'gdbus-non-socket.c',
- 'gdbus-tests.c', 'test-io-stream.c', 'test-pipe-unix.c',
- install : false,
- c_args : test_c_args,
- dependencies : common_gio_tests_deps)
- test('gdbus-non-socket', exe, env : test_env, suite : ['gio'])
+ gio_tests += [{
+ 'gdbus-connection-flush' : {
+ 'extra_sources' : ['test-io-stream.c', 'test-pipe-unix.c'],
+ },
+ 'gdbus-non-socket' : {
+ 'extra_sources' : ['gdbus-tests.c', 'test-io-stream.c', 'test-pipe-unix.c'],
+ },
+ }]
# Generate test.mo from de.po using msgfmt
msgfmt = find_program('msgfmt', required : false)
if msgfmt.found()
subdir('de/LC_MESSAGES')
- # gsettings target exe already exists in gio directory
- exe = executable('gsettings-test', 'gsettings.c', test_mo,
- install : false,
- c_args : test_c_args + [
- '-DSRCDIR="@0@"'.format(meson.current_source_dir()),
- '-DTEST_LOCALE_PATH="@0@"'.format(test_mo_dir),
- ],
- dependencies : common_gio_tests_deps)
- test('gsettings', exe, env : test_env, suite : ['gio'])
+ gio_tests += [{
+ 'gsettings' : {
+ 'extra_sources' : [test_mo],
+ 'c_args' : ['-DSRCDIR="@0@"'.format(meson.current_source_dir()),
+ '-DTEST_LOCALE_PATH="@0@"'.format(test_mo_dir)],
+ 'install' : false,
+ },
+ }]
endif
endif # unix
# Test programs buildable on Windows only
if host_machine.system() == 'windows'
- gio_tests += ['win32-streams']
+ gio_tests += [{'win32-streams' : {}}]
endif
if cc.get_id() != 'msvc'
- gio_tests += [ 'autoptr' ]
+ gio_tests += [{
+ 'autoptr-gio' : {
+ 'source' : 'autoptr.c',
+ },
+ }]
endif
-foreach test_name : gio_tests
- extra_deps = []
- srcs = ['@0@.c'.format(test_name)]
- # conflicts with glib/tests/autoptr, can't have two targets with same name
- if test_name == 'autoptr'
- test_name = 'autoptr-gio'
- elif test_name == 'defaultvalue'
- srcs += [giotypefuncs_inc]
- elif test_name == 'gdbus-peer'
- # This is peer to peer so it doesn't need a session bus, so we can run
- # it automatically as a test by default
- extra_deps = [libgdbus_example_objectmanager_dep]
- elif test_name == 'tls-certificate' or test_name == 'tls-interaction'
- srcs += ['gtesttlsbackend.c']
- endif
- exe = executable(test_name, srcs,
- install : false,
- c_args : test_c_args,
- dependencies : common_gio_tests_deps + extra_deps)
- # These tests may take more than 30 seconds to run on the CI infrastructure
- if slow_tests.contains(test_name)
- test(test_name, exe, env : test_env, timeout : 120, suite : ['gio', 'slow'])
- else
- test(test_name, exe, env : test_env, suite : ['gio'])
- endif
-endforeach
-
-uninstalled_test_extra_programs = [
- ['gio-du'],
- ['echo-server'],
- ['filter-cat'],
- ['gapplication-example-actions'],
- ['gapplication-example-cmdline'],
- ['gapplication-example-cmdline2'],
- ['gapplication-example-cmdline3'],
- ['gapplication-example-cmdline4'],
- ['gapplication-example-dbushooks'],
- ['gapplication-example-open'],
- ['gdbus-daemon', gdbus_daemon_sources],
- ['gdbus-example-export'],
- ['gdbus-example-own-name'],
- ['gdbus-example-peer'],
- ['gdbus-example-proxy-subclass'],
- ['gdbus-example-server'],
- ['gdbus-example-subtree'],
- ['gdbus-example-watch-name'],
- ['gdbus-example-watch-proxy'],
- ['gsubprocess-testprog'],
- ['httpd'],
- ['proxy'],
- ['resolver'],
- ['send-data'],
- ['socket-server'],
- ['socket-client', ['gtlsconsoleinteraction.c']],
+test_extra_programs += [{
+ 'gio-du' : {'install' : false},
+ 'echo-server' : {'install' : false},
+ 'filter-cat' : {'install' : false},
+ 'gapplication-example-actions' : {'install' : false},
+ 'gapplication-example-cmdline' : {'install' : false},
+ 'gapplication-example-cmdline2' : {'install' : false},
+ 'gapplication-example-cmdline3' : {'install' : false},
+ 'gapplication-example-cmdline4' : {'install' : false},
+ 'gapplication-example-dbushooks' : {'install' : false},
+ 'gapplication-example-open' : {'install' : false},
+ 'gdbus-daemon' : {
+ 'extra_sources' : gdbus_daemon_sources,
+ 'install' : false,
+ },
+ 'gdbus-example-export' : {'install' : false},
+ 'gdbus-example-own-name' : {'install' : false},
+ 'gdbus-example-peer' : {'install' : false},
+ 'gdbus-example-proxy-subclass' : {'install' : false},
+ 'gdbus-example-server' : {'install' : false},
+ 'gdbus-example-subtree' : {'install' : false},
+ 'gdbus-example-watch-name' : {'install' : false},
+ 'gdbus-example-watch-proxy' : {'install' : false},
+ 'gsubprocess-testprog' : {'install' : false},
+ 'httpd' : {'install' : false},
+ 'proxy' : {'install' : false},
+ 'resolver' : {'install' : false},
+ 'send-data' : {'install' : false},
+ 'socket-server' : {'install' : false},
+ 'socket-client' : {
+ 'extra_sources' : ['gtlsconsoleinteraction.c'],
+ 'install' : false,
+ },
# These three are manual-run tests because they need a session bus but don't bring one up themselves
# FIXME: these build but don't seem to work!
- ['gdbus-example-objectmanager-client', [], [libgdbus_example_objectmanager_dep]],
- ['gdbus-example-objectmanager-server', [], [libgdbus_example_objectmanager_dep]],
- ['gdbus-test-fixture', [], [libgdbus_example_objectmanager_dep]],
-]
+ 'gdbus-example-objectmanager-client' : {
+ 'dependencies' : [libgdbus_example_objectmanager_dep],
+ 'install' : false,
+ },
+ 'gdbus-example-objectmanager-server' : {
+ 'dependencies' : [libgdbus_example_objectmanager_dep],
+ 'install' : false,
+ },
+ 'gdbus-test-fixture' : {
+ 'dependencies' : [libgdbus_example_objectmanager_dep],
+ 'install' : false,
+ },
+}]
if host_machine.system() != 'windows'
- uninstalled_test_extra_programs += [['gdbus-example-unix-fd-client']]
+ test_extra_programs += [{
+ 'gdbus-example-unix-fd-client' : {
+ 'install' : false,
+ },
+ }]
endif
-foreach extra_program : uninstalled_test_extra_programs + test_extra_programs
- srcs = ['@0@.c'.format(extra_program[0])]
- if extra_program.length() > 1
- srcs += extra_program[1]
- endif
- extra_deps = []
- if extra_program.length() > 2
- extra_deps = extra_program[2]
- endif
- executable(extra_program[0], srcs,
- install : false,
- c_args : test_c_args,
- dependencies : common_gio_tests_deps + extra_deps)
-endforeach
-
if not meson.is_cross_build() or meson.has_exe_wrapper()
plugin_resources_c = custom_target('plugin-resources.c',
@@ -441,13 +412,58 @@ if not meson.is_cross_build() or meson.has_exe_wrapper()
copy : true,
install : false)
- exe = executable('resources', 'resources.c', test_gresource,
- test_resources_c, test_resources2_c, test_resources2_h,
- install : false,
- c_args : test_c_args,
- dependencies : common_gio_tests_deps)
- test('resources', exe, env : test_env, suite : ['gio'])
+ gio_tests += [{
+ 'resources' : {
+ 'extra_sources' : [test_gresource, test_resources_c, test_resources2_c,
+ test_resources2_h],
+ },
+ }]
endif
+foreach test_dict : gio_tests
+ foreach test_name, extra_args : test_dict
+ source = extra_args.get('source', test_name + '.c')
+ extra_sources = extra_args.get('extra_sources', [])
+ install = installed_tests_enabled and extra_args.get('install', true)
+
+ if install
+ test_conf = configuration_data()
+ test_conf.set('installed_tests_dir', installed_tests_execdir)
+ test_conf.set('program', test_name)
+ configure_file(
+ input: installed_tests_template,
+ output: test_name + '.test',
+ install_dir: installed_tests_metadir,
+ configuration: test_conf
+ )
+ endif
+
+ exe = executable(test_name, [source, extra_sources],
+ c_args : test_c_args + extra_args.get('c_args', []),
+ dependencies : common_gio_tests_deps + extra_args.get('dependencies', []),
+ install_dir: installed_tests_execdir,
+ install: install,
+ )
+
+ suite = ['gio'] + extra_args.get('suite', [])
+ timeout = suite.contains('slow') ? 120 : 30
+ test(test_name, exe, env : test_env, timeout : timeout, suite : suite)
+ endforeach
+endforeach
+
+foreach program_dict : test_extra_programs
+ foreach program_name, extra_args : program_dict
+ source = extra_args.get('source', program_name + '.c')
+ extra_sources = extra_args.get('extra_sources', [])
+ install = installed_tests_enabled and extra_args.get('install', true)
+ executable(program_name, [source, extra_sources],
+ c_args : test_c_args,
+ dependencies : common_gio_tests_deps + extra_args.get('dependencies', []),
+ install_dir : installed_tests_execdir,
+ install : install,
+ )
+ endforeach
+endforeach
+
# FIXME: subdir('services')
subdir('modules')
diff --git a/gio/tests/resources.c b/gio/tests/resources.c
index 6ae8e7d64..70d8c03a6 100644
--- a/gio/tests/resources.c
+++ b/gio/tests/resources.c
@@ -317,6 +317,45 @@ test_resource_data_unaligned (void)
g_resource_unref (resource);
}
+/* Test error handling for corrupt GResource files (specifically, a corrupt
+ * GVDB header). */
+static void
+test_resource_data_corrupt (void)
+{
+ /* A GVDB header is 6 guint32s, and requires a magic number in the first two
+ * guint32s. A set of zero bytes of a greater length is considered corrupt. */
+ static const guint8 data[sizeof (guint32) * 7] = { 0, };
+ GBytes *bytes = NULL;
+ GResource *resource = NULL;
+ GError *local_error = NULL;
+
+ bytes = g_bytes_new_static (data, sizeof (data));
+ resource = g_resource_new_from_data (bytes, &local_error);
+ g_bytes_unref (bytes);
+ g_assert_error (local_error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_INTERNAL);
+ g_assert_null (resource);
+
+ g_clear_error (&local_error);
+}
+
+/* Test handling for empty GResource files. They should also be treated as
+ * corrupt. */
+static void
+test_resource_data_empty (void)
+{
+ GBytes *bytes = NULL;
+ GResource *resource = NULL;
+ GError *local_error = NULL;
+
+ bytes = g_bytes_new_static (NULL, 0);
+ resource = g_resource_new_from_data (bytes, &local_error);
+ g_bytes_unref (bytes);
+ g_assert_error (local_error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_INTERNAL);
+ g_assert_null (resource);
+
+ g_clear_error (&local_error);
+}
+
static void
test_resource_registered (void)
{
@@ -785,6 +824,8 @@ main (int argc,
g_test_add_func ("/resource/file-path", test_resource_file_path);
g_test_add_func ("/resource/data", test_resource_data);
g_test_add_func ("/resource/data_unaligned", test_resource_data_unaligned);
+ g_test_add_func ("/resource/data-corrupt", test_resource_data_corrupt);
+ g_test_add_func ("/resource/data-empty", test_resource_data_empty);
g_test_add_func ("/resource/registered", test_resource_registered);
g_test_add_func ("/resource/manual", test_resource_manual);
g_test_add_func ("/resource/manual2", test_resource_manual2);
diff --git a/gio/tests/trash.c b/gio/tests/trash.c
index 2abe0aa0c..176c4b9c3 100644
--- a/gio/tests/trash.c
+++ b/gio/tests/trash.c
@@ -35,23 +35,26 @@ test_trash_not_supported (void)
GFileInfo *info;
GError *error = NULL;
gboolean ret;
- GStatBuf file_stat, home_stat;
+ gchar *parent_dirname;
+ GStatBuf parent_stat, home_stat;
/* The test assumes that tmp file is located on system internal mount. */
file = g_file_new_tmp ("test-trashXXXXXX", &stream, &error);
+ parent_dirname = g_path_get_dirname (g_file_peek_path (file));
g_assert_no_error (error);
- g_assert_cmpint (g_lstat (g_file_peek_path (file), &file_stat), ==, 0);
- g_test_message ("File: %s (dev: %" G_GUINT64_FORMAT ")",
- g_file_peek_path (file), (guint64) file_stat.st_dev);
+ g_assert_cmpint (g_stat (parent_dirname, &parent_stat), ==, 0);
+ g_test_message ("File: %s (parent st_dev: %" G_GUINT64_FORMAT ")",
+ g_file_peek_path (file), (guint64) parent_stat.st_dev);
g_assert_cmpint (g_stat (g_get_home_dir (), &home_stat), ==, 0);
- g_test_message ("Home: %s (dev: %" G_GUINT64_FORMAT ")",
+ g_test_message ("Home: %s (st_dev: %" G_GUINT64_FORMAT ")",
g_get_home_dir (), (guint64) home_stat.st_dev);
- if (file_stat.st_dev == home_stat.st_dev)
+ if (parent_stat.st_dev == home_stat.st_dev)
{
g_test_skip ("The file has to be on another filesystem than the home trash to run this test");
+ g_free (parent_dirname);
g_object_unref (stream);
g_object_unref (file);
@@ -85,6 +88,7 @@ test_trash_not_supported (void)
g_io_stream_close (G_IO_STREAM (stream), NULL, &error);
g_assert_no_error (error);
+ g_free (parent_dirname);
g_object_unref (info);
g_object_unref (stream);
g_object_unref (file);