summaryrefslogtreecommitdiff
path: root/gio
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2021-10-29 10:28:40 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2021-10-29 10:28:40 +0900
commit01661d9c1888e4230ae0ea499265e70b9b436d63 (patch)
treedea19695c780ea54389db567b74727a3e3719f0e /gio
parent5457625a8c549d3f02daaa7398ebe9bca159e4fa (diff)
downloadglib-01661d9c1888e4230ae0ea499265e70b9b436d63.tar.gz
glib-01661d9c1888e4230ae0ea499265e70b9b436d63.tar.bz2
glib-01661d9c1888e4230ae0ea499265e70b9b436d63.zip
Imported Upstream version 2.66.7upstream/2.66.7
Diffstat (limited to 'gio')
-rw-r--r--gio/gdbusconnection.c11
-rw-r--r--gio/gdbusserver.c5
-rw-r--r--gio/gkeyfilesettingsbackend.c14
-rw-r--r--gio/gtlspassword.c2
-rw-r--r--gio/tests/gdbus-peer.c187
-rw-r--r--gio/tests/gsettings.c170
-rw-r--r--gio/tests/tls-interaction.c55
7 files changed, 441 insertions, 3 deletions
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index 633198b02..75b818069 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -121,6 +121,13 @@
#include "glibintl.h"
+#define G_DBUS_CONNECTION_FLAGS_ALL \
+ (G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | \
+ G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER | \
+ G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS | \
+ G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION | \
+ G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING)
+
/**
* SECTION:gdbusconnection
* @short_description: D-Bus Connections
@@ -2706,6 +2713,7 @@ g_dbus_connection_new (GIOStream *stream,
_g_dbus_initialize ();
g_return_if_fail (G_IS_IO_STREAM (stream));
+ g_return_if_fail ((flags & ~G_DBUS_CONNECTION_FLAGS_ALL) == 0);
g_async_initable_new_async (G_TYPE_DBUS_CONNECTION,
G_PRIORITY_DEFAULT,
@@ -2793,6 +2801,7 @@ g_dbus_connection_new_sync (GIOStream *stream,
{
_g_dbus_initialize ();
g_return_val_if_fail (G_IS_IO_STREAM (stream), NULL);
+ g_return_val_if_fail ((flags & ~G_DBUS_CONNECTION_FLAGS_ALL) == 0, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
return g_initable_new (G_TYPE_DBUS_CONNECTION,
cancellable,
@@ -2850,6 +2859,7 @@ g_dbus_connection_new_for_address (const gchar *address,
_g_dbus_initialize ();
g_return_if_fail (address != NULL);
+ g_return_if_fail ((flags & ~G_DBUS_CONNECTION_FLAGS_ALL) == 0);
g_async_initable_new_async (G_TYPE_DBUS_CONNECTION,
G_PRIORITY_DEFAULT,
@@ -2937,6 +2947,7 @@ g_dbus_connection_new_for_address_sync (const gchar *address,
_g_dbus_initialize ();
g_return_val_if_fail (address != NULL, NULL);
+ g_return_val_if_fail ((flags & ~G_DBUS_CONNECTION_FLAGS_ALL) == 0, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
return g_initable_new (G_TYPE_DBUS_CONNECTION,
cancellable,
diff --git a/gio/gdbusserver.c b/gio/gdbusserver.c
index 4a8dab0ea..64bac73ae 100644
--- a/gio/gdbusserver.c
+++ b/gio/gdbusserver.c
@@ -57,6 +57,10 @@
#include "glibintl.h"
+#define G_DBUS_SERVER_FLAGS_ALL \
+ (G_DBUS_SERVER_FLAGS_RUN_IN_THREAD | \
+ G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS)
+
/**
* SECTION:gdbusserver
* @short_description: Helper for accepting connections
@@ -512,6 +516,7 @@ g_dbus_server_new_sync (const gchar *address,
g_return_val_if_fail (address != NULL, NULL);
g_return_val_if_fail (g_dbus_is_guid (guid), NULL);
+ g_return_val_if_fail ((flags & ~G_DBUS_SERVER_FLAGS_ALL) == 0, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
server = g_initable_new (G_TYPE_DBUS_SERVER,
diff --git a/gio/gkeyfilesettingsbackend.c b/gio/gkeyfilesettingsbackend.c
index 25b057672..de216e615 100644
--- a/gio/gkeyfilesettingsbackend.c
+++ b/gio/gkeyfilesettingsbackend.c
@@ -158,6 +158,13 @@ convert_path (GKeyfileSettingsBackend *kfsb,
last_slash = strrchr (key, '/');
+ /* Disallow empty group names or key names */
+ if (key_len == 0 ||
+ (last_slash != NULL &&
+ (*(last_slash + 1) == '\0' ||
+ last_slash == key)))
+ return FALSE;
+
if (kfsb->root_group)
{
/* if a root_group was specified, make sure the user hasn't given
@@ -185,7 +192,12 @@ convert_path (GKeyfileSettingsBackend *kfsb,
}
if (basename)
- *basename = g_memdup2 (last_slash + 1, key_len - (last_slash - key));
+ {
+ if (last_slash != NULL)
+ *basename = g_memdup2 (last_slash + 1, key_len - (last_slash - key));
+ else
+ *basename = g_strdup (key);
+ }
return TRUE;
}
diff --git a/gio/gtlspassword.c b/gio/gtlspassword.c
index dbcec41a8..bd86a6dfe 100644
--- a/gio/gtlspassword.c
+++ b/gio/gtlspassword.c
@@ -291,7 +291,7 @@ g_tls_password_set_value (GTlsPassword *password,
{
/* FIXME: g_tls_password_set_value_full() doesn’t support unsigned gsize */
gsize length_unsigned = strlen ((gchar *) value);
- g_return_if_fail (length_unsigned > G_MAXSSIZE);
+ g_return_if_fail (length_unsigned <= G_MAXSSIZE);
length = (gssize) length_unsigned;
}
diff --git a/gio/tests/gdbus-peer.c b/gio/tests/gdbus-peer.c
index 8450a3be7..a03ebbbbe 100644
--- a/gio/tests/gdbus-peer.c
+++ b/gio/tests/gdbus-peer.c
@@ -1139,6 +1139,183 @@ test_peer (void)
/* ---------------------------------------------------------------------------------------------------- */
+#define VALID_GUID "0123456789abcdef0123456789abcdef"
+
+static void
+test_peer_invalid_server (void)
+{
+ GDBusServer *server;
+
+ if (!g_test_undefined ())
+ {
+ g_test_skip ("Not exercising programming errors");
+ return;
+ }
+
+ if (g_test_subprocess ())
+ {
+ /* This assumes we are not going to run out of GDBusServerFlags
+ * any time soon */
+ server = g_dbus_server_new_sync ("tcp:", (GDBusServerFlags) (1 << 30),
+ VALID_GUID,
+ NULL, NULL, NULL);
+ g_assert_null (server);
+ }
+ else
+ {
+ g_test_trap_subprocess (NULL, 0, 0);
+ g_test_trap_assert_failed ();
+ g_test_trap_assert_stderr ("*CRITICAL*G_DBUS_SERVER_FLAGS_ALL*");
+ }
+}
+
+static void
+test_peer_invalid_conn_stream_sync (void)
+{
+ GSocket *sock;
+ GSocketConnection *socket_conn;
+ GIOStream *iostream;
+ GDBusConnection *conn;
+
+ if (!g_test_undefined ())
+ {
+ g_test_skip ("Not exercising programming errors");
+ return;
+ }
+
+ sock = g_socket_new (G_SOCKET_FAMILY_IPV4,
+ G_SOCKET_TYPE_STREAM,
+ G_SOCKET_PROTOCOL_TCP,
+ NULL);
+
+ if (sock == NULL)
+ {
+ g_test_skip ("TCP not available?");
+ return;
+ }
+
+ socket_conn = g_socket_connection_factory_create_connection (sock);
+ g_assert_nonnull (socket_conn);
+ iostream = G_IO_STREAM (socket_conn);
+ g_assert_nonnull (iostream);
+
+ if (g_test_subprocess ())
+ {
+ /* This assumes we are not going to run out of GDBusConnectionFlags
+ * any time soon */
+ conn = g_dbus_connection_new_sync (iostream, VALID_GUID,
+ (GDBusConnectionFlags) (1 << 30),
+ NULL, NULL, NULL);
+ g_assert_null (conn);
+ }
+ else
+ {
+ g_test_trap_subprocess (NULL, 0, 0);
+ g_test_trap_assert_failed ();
+ g_test_trap_assert_stderr ("*CRITICAL*G_DBUS_CONNECTION_FLAGS_ALL*");
+ }
+
+ g_clear_object (&sock);
+ g_clear_object (&socket_conn);
+}
+
+static void
+test_peer_invalid_conn_stream_async (void)
+{
+ GSocket *sock;
+ GSocketConnection *socket_conn;
+ GIOStream *iostream;
+
+ if (!g_test_undefined ())
+ {
+ g_test_skip ("Not exercising programming errors");
+ return;
+ }
+
+ sock = g_socket_new (G_SOCKET_FAMILY_IPV4,
+ G_SOCKET_TYPE_STREAM,
+ G_SOCKET_PROTOCOL_TCP,
+ NULL);
+
+ if (sock == NULL)
+ {
+ g_test_skip ("TCP not available?");
+ return;
+ }
+
+ socket_conn = g_socket_connection_factory_create_connection (sock);
+ g_assert_nonnull (socket_conn);
+ iostream = G_IO_STREAM (socket_conn);
+ g_assert_nonnull (iostream);
+
+ if (g_test_subprocess ())
+ {
+ g_dbus_connection_new (iostream, VALID_GUID,
+ (GDBusConnectionFlags) (1 << 30),
+ NULL, NULL, NULL, NULL);
+ }
+ else
+ {
+ g_test_trap_subprocess (NULL, 0, 0);
+ g_test_trap_assert_failed ();
+ g_test_trap_assert_stderr ("*CRITICAL*G_DBUS_CONNECTION_FLAGS_ALL*");
+ }
+
+ g_clear_object (&sock);
+ g_clear_object (&socket_conn);
+}
+
+static void
+test_peer_invalid_conn_addr_sync (void)
+{
+ GDBusConnection *conn;
+
+ if (!g_test_undefined ())
+ {
+ g_test_skip ("Not exercising programming errors");
+ return;
+ }
+
+ if (g_test_subprocess ())
+ {
+ conn = g_dbus_connection_new_for_address_sync ("tcp:",
+ (GDBusConnectionFlags) (1 << 30),
+ NULL, NULL, NULL);
+ g_assert_null (conn);
+ }
+ else
+ {
+ g_test_trap_subprocess (NULL, 0, 0);
+ g_test_trap_assert_failed ();
+ g_test_trap_assert_stderr ("*CRITICAL*G_DBUS_CONNECTION_FLAGS_ALL*");
+ }
+}
+
+static void
+test_peer_invalid_conn_addr_async (void)
+{
+ if (!g_test_undefined ())
+ {
+ g_test_skip ("Not exercising programming errors");
+ return;
+ }
+
+ if (g_test_subprocess ())
+ {
+ g_dbus_connection_new_for_address ("tcp:",
+ (GDBusConnectionFlags) (1 << 30),
+ NULL, NULL, NULL, NULL);
+ }
+ else
+ {
+ g_test_trap_subprocess (NULL, 0, 0);
+ g_test_trap_assert_failed ();
+ g_test_trap_assert_stderr ("*CRITICAL*G_DBUS_CONNECTION_FLAGS_ALL*");
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
static void
test_peer_signals (void)
{
@@ -2010,6 +2187,16 @@ main (int argc,
test_interface_introspection_data = introspection_data->interfaces[0];
g_test_add_func ("/gdbus/peer-to-peer", test_peer);
+ g_test_add_func ("/gdbus/peer-to-peer/invalid/server",
+ test_peer_invalid_server);
+ g_test_add_func ("/gdbus/peer-to-peer/invalid/conn/stream/async",
+ test_peer_invalid_conn_stream_async);
+ g_test_add_func ("/gdbus/peer-to-peer/invalid/conn/stream/sync",
+ test_peer_invalid_conn_stream_sync);
+ g_test_add_func ("/gdbus/peer-to-peer/invalid/conn/addr/async",
+ test_peer_invalid_conn_addr_async);
+ g_test_add_func ("/gdbus/peer-to-peer/invalid/conn/addr/sync",
+ test_peer_invalid_conn_addr_sync);
g_test_add_func ("/gdbus/peer-to-peer/signals", test_peer_signals);
g_test_add_func ("/gdbus/delayed-message-processing", delayed_message_processing);
g_test_add_func ("/gdbus/nonce-tcp", test_nonce_tcp);
diff --git a/gio/tests/gsettings.c b/gio/tests/gsettings.c
index baadca8f5..6e5a6d367 100644
--- a/gio/tests/gsettings.c
+++ b/gio/tests/gsettings.c
@@ -1740,6 +1740,14 @@ key_changed_cb (GSettings *settings, const gchar *key, gpointer data)
(*b) = TRUE;
}
+typedef struct
+{
+ const gchar *path;
+ const gchar *root_group;
+ const gchar *keyfile_group;
+ const gchar *root_path;
+} KeyfileTestData;
+
/*
* Test that using a keyfile works
*/
@@ -1834,7 +1842,11 @@ test_keyfile (Fixture *fixture,
g_free (str);
g_settings_set (settings, "farewell", "s", "cheerio");
-
+
+ /* Check that empty keys/groups are not allowed. */
+ g_assert_false (g_settings_is_writable (settings, ""));
+ g_assert_false (g_settings_is_writable (settings, "/"));
+
/* When executing as root, changing the mode of the keyfile will have
* no effect on the writability of the settings.
*/
@@ -1866,6 +1878,149 @@ test_keyfile (Fixture *fixture,
g_free (keyfile_path);
}
+/*
+ * Test that using a keyfile works with a schema with no path set.
+ */
+static void
+test_keyfile_no_path (Fixture *fixture,
+ gconstpointer user_data)
+{
+ const KeyfileTestData *test_data = user_data;
+ GSettingsBackend *kf_backend;
+ GSettings *settings;
+ GKeyFile *keyfile;
+ gboolean writable;
+ gchar *key = NULL;
+ GError *error = NULL;
+ gchar *keyfile_path = NULL, *store_path = NULL;
+
+ keyfile_path = g_build_filename (fixture->tmp_dir, "keyfile", NULL);
+ store_path = g_build_filename (keyfile_path, "gsettings.store", NULL);
+ kf_backend = g_keyfile_settings_backend_new (store_path, test_data->root_path, test_data->root_group);
+ settings = g_settings_new_with_backend_and_path ("org.gtk.test.no-path", kf_backend, test_data->path);
+ g_object_unref (kf_backend);
+
+ g_settings_reset (settings, "test-boolean");
+ g_assert_true (g_settings_get_boolean (settings, "test-boolean"));
+
+ writable = g_settings_is_writable (settings, "test-boolean");
+ g_assert_true (writable);
+ g_settings_set (settings, "test-boolean", "b", FALSE);
+
+ g_assert_false (g_settings_get_boolean (settings, "test-boolean"));
+
+ g_settings_delay (settings);
+ g_settings_set (settings, "test-boolean", "b", TRUE);
+ g_settings_apply (settings);
+
+ keyfile = g_key_file_new ();
+ g_assert_true (g_key_file_load_from_file (keyfile, store_path, 0, NULL));
+
+ g_assert_true (g_key_file_get_boolean (keyfile, test_data->keyfile_group, "test-boolean", NULL));
+
+ g_key_file_free (keyfile);
+
+ g_settings_reset (settings, "test-boolean");
+ g_settings_apply (settings);
+ keyfile = g_key_file_new ();
+ g_assert_true (g_key_file_load_from_file (keyfile, store_path, 0, NULL));
+
+ g_assert_false (g_key_file_get_string (keyfile, test_data->keyfile_group, "test-boolean", &error));
+ g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND);
+ g_clear_error (&error);
+
+ /* Check that empty keys/groups are not allowed. */
+ g_assert_false (g_settings_is_writable (settings, ""));
+ g_assert_false (g_settings_is_writable (settings, "/"));
+
+ /* Keys which ghost the root group name are not allowed. This can only be
+ * tested when the path is `/` as otherwise it acts as a prefix and prevents
+ * any ghosting. */
+ if (g_str_equal (test_data->path, "/"))
+ {
+ key = g_strdup_printf ("%s/%s", test_data->root_group, "");
+ g_assert_false (g_settings_is_writable (settings, key));
+ g_free (key);
+
+ key = g_strdup_printf ("%s/%s", test_data->root_group, "/");
+ g_assert_false (g_settings_is_writable (settings, key));
+ g_free (key);
+
+ key = g_strdup_printf ("%s/%s", test_data->root_group, "test-boolean");
+ g_assert_false (g_settings_is_writable (settings, key));
+ g_free (key);
+ }
+
+ g_key_file_free (keyfile);
+ g_object_unref (settings);
+
+ /* Clean up the temporary directory. */
+ g_assert_no_errno (g_chmod (keyfile_path, 0777));
+ g_assert_no_errno (g_remove (store_path));
+ g_assert_no_errno (g_rmdir (keyfile_path));
+ g_free (store_path);
+ g_free (keyfile_path);
+}
+
+/*
+ * Test that a keyfile rejects writes to keys outside its root path.
+ */
+static void
+test_keyfile_outside_root_path (Fixture *fixture,
+ gconstpointer user_data)
+{
+ GSettingsBackend *kf_backend;
+ GSettings *settings;
+ gchar *keyfile_path = NULL, *store_path = NULL;
+
+ keyfile_path = g_build_filename (fixture->tmp_dir, "keyfile", NULL);
+ store_path = g_build_filename (keyfile_path, "gsettings.store", NULL);
+ kf_backend = g_keyfile_settings_backend_new (store_path, "/tests/basic-types/", "root");
+ settings = g_settings_new_with_backend_and_path ("org.gtk.test.no-path", kf_backend, "/tests/");
+ g_object_unref (kf_backend);
+
+ g_assert_false (g_settings_is_writable (settings, "test-boolean"));
+
+ g_object_unref (settings);
+
+ /* Clean up the temporary directory. The keyfile probably doesn’t exist, so
+ * don’t error on failure. */
+ g_remove (store_path);
+ g_assert_no_errno (g_rmdir (keyfile_path));
+ g_free (store_path);
+ g_free (keyfile_path);
+}
+
+/*
+ * Test that a keyfile rejects writes to keys in the root if no root group is set.
+ */
+static void
+test_keyfile_no_root_group (Fixture *fixture,
+ gconstpointer user_data)
+{
+ GSettingsBackend *kf_backend;
+ GSettings *settings;
+ gchar *keyfile_path = NULL, *store_path = NULL;
+
+ keyfile_path = g_build_filename (fixture->tmp_dir, "keyfile", NULL);
+ store_path = g_build_filename (keyfile_path, "gsettings.store", NULL);
+ kf_backend = g_keyfile_settings_backend_new (store_path, "/", NULL);
+ settings = g_settings_new_with_backend_and_path ("org.gtk.test.no-path", kf_backend, "/");
+ g_object_unref (kf_backend);
+
+ g_assert_false (g_settings_is_writable (settings, "test-boolean"));
+ g_assert_true (g_settings_is_writable (settings, "child/test-boolean"));
+
+ g_object_unref (settings);
+
+ /* Clean up the temporary directory. The keyfile probably doesn’t exist, so
+ * don’t error on failure. */
+ g_remove (store_path);
+ g_assert_no_errno (g_rmdir (keyfile_path));
+ g_free (store_path);
+ g_free (keyfile_path);
+}
+
/* Test that getting child schemas works
*/
static void
@@ -2844,6 +2999,14 @@ main (int argc, char *argv[])
gchar *override_text;
gchar *enums;
gint result;
+ const KeyfileTestData keyfile_test_data_explicit_path = { "/tests/", "root", "tests", "/" };
+ const KeyfileTestData keyfile_test_data_empty_path = { "/", "root", "root", "/" };
+ const KeyfileTestData keyfile_test_data_long_path = {
+ "/tests/path/is/very/long/and/this/makes/some/comparisons/take/a/different/branch/",
+ "root",
+ "tests/path/is/very/long/and/this/makes/some/comparisons/take/a/different/branch",
+ "/"
+ };
/* Meson build sets this */
#ifdef TEST_LOCALE_PATH
@@ -2967,6 +3130,11 @@ main (int argc, char *argv[])
}
g_test_add ("/gsettings/keyfile", Fixture, NULL, setup, test_keyfile, teardown);
+ g_test_add ("/gsettings/keyfile/explicit-path", Fixture, &keyfile_test_data_explicit_path, setup, test_keyfile_no_path, teardown);
+ g_test_add ("/gsettings/keyfile/empty-path", Fixture, &keyfile_test_data_empty_path, setup, test_keyfile_no_path, teardown);
+ g_test_add ("/gsettings/keyfile/long-path", Fixture, &keyfile_test_data_long_path, setup, test_keyfile_no_path, teardown);
+ g_test_add ("/gsettings/keyfile/outside-root-path", Fixture, NULL, setup, test_keyfile_outside_root_path, teardown);
+ g_test_add ("/gsettings/keyfile/no-root-group", Fixture, NULL, setup, test_keyfile_no_root_group, teardown);
g_test_add_func ("/gsettings/child-schema", test_child_schema);
g_test_add_func ("/gsettings/strinfo", test_strinfo);
g_test_add_func ("/gsettings/enums", test_enums);
diff --git a/gio/tests/tls-interaction.c b/gio/tests/tls-interaction.c
index 4f0737d7e..5661e8e0d 100644
--- a/gio/tests/tls-interaction.c
+++ b/gio/tests/tls-interaction.c
@@ -174,6 +174,38 @@ test_interaction_ask_password_finish_failure (GTlsInteraction *interaction,
}
+/* Return a copy of @str that is allocated in a silly way, to exercise
+ * custom free-functions. The returned pointer points to a copy of @str
+ * in a buffer of the form "BEFORE \0 str \0 AFTER". */
+static guchar *
+special_dup (const char *str)
+{
+ GString *buf = g_string_new ("BEFORE");
+ guchar *ret;
+
+ g_string_append_c (buf, '\0');
+ g_string_append (buf, str);
+ g_string_append_c (buf, '\0');
+ g_string_append (buf, "AFTER");
+ ret = (guchar *) g_string_free (buf, FALSE);
+ return ret + strlen ("BEFORE") + 1;
+}
+
+
+/* Free a copy of @str that was made with special_dup(), after asserting
+ * that it has not been corrupted. */
+static void
+special_free (gpointer p)
+{
+ gchar *s = p;
+ gchar *buf = s - strlen ("BEFORE") - 1;
+
+ g_assert_cmpstr (buf, ==, "BEFORE");
+ g_assert_cmpstr (s + strlen (s) + 1, ==, "AFTER");
+ g_free (buf);
+}
+
+
static GTlsInteractionResult
test_interaction_ask_password_sync_success (GTlsInteraction *interaction,
GTlsPassword *password,
@@ -181,6 +213,8 @@ test_interaction_ask_password_sync_success (GTlsInteraction *interaction,
GError **error)
{
TestInteraction *self;
+ const guchar *value;
+ gsize len;
g_assert (TEST_IS_INTERACTION (interaction));
self = TEST_INTERACTION (interaction);
@@ -192,6 +226,27 @@ test_interaction_ask_password_sync_success (GTlsInteraction *interaction,
g_assert (error != NULL);
g_assert (*error == NULL);
+ /* Exercise different ways to set the value */
+ g_tls_password_set_value (password, (const guchar *) "foo", 4);
+ len = 0;
+ value = g_tls_password_get_value (password, &len);
+ g_assert_cmpmem (value, len, "foo", 4);
+
+ g_tls_password_set_value (password, (const guchar *) "bar", -1);
+ len = 0;
+ value = g_tls_password_get_value (password, &len);
+ g_assert_cmpmem (value, len, "bar", 3);
+
+ g_tls_password_set_value_full (password, special_dup ("baa"), 4, special_free);
+ len = 0;
+ value = g_tls_password_get_value (password, &len);
+ g_assert_cmpmem (value, len, "baa", 4);
+
+ g_tls_password_set_value_full (password, special_dup ("baz"), -1, special_free);
+ len = 0;
+ value = g_tls_password_get_value (password, &len);
+ g_assert_cmpmem (value, len, "baz", 3);
+
/* Don't do this in real life. Include a null terminator for testing */
g_tls_password_set_value (password, (const guchar *)"the password", 13);
return G_TLS_INTERACTION_HANDLED;