From 317e8c132d1fd6373a698846932a10c443979726 Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Wed, 17 Apr 2013 09:45:23 -0400 Subject: [PATCH] GDBusMethodInvocation: add property return checks Add some type checking for the values returned from async property handling calls, similar in spirit to the type checking we do for normal method calls. https://bugzilla.gnome.org/show_bug.cgi?id=698375 --- gio/gdbusmethodinvocation.c | 59 +++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/gio/gdbusmethodinvocation.c b/gio/gdbusmethodinvocation.c index ad19d9d09..bd40aaf31 100644 --- a/gio/gdbusmethodinvocation.c +++ b/gio/gdbusmethodinvocation.c @@ -418,6 +418,65 @@ g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocatio g_variant_type_free (type); } + /* property_info is only non-NULL if set that way from + * GDBusConnection, so this must be the case of async property + * handling on either 'Get', 'Set' or 'GetAll'. + */ + if (invocation->property_info != NULL) + { + if (g_str_equal (invocation->method_name, "Get")) + { + GVariant *nested; + + if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(v)"))) + { + g_warning ("Type of return value for property 'Get' call should be '(v)' but got '%s'", + g_variant_get_type_string (parameters)); + goto out; + } + + /* Go deeper and make sure that the value inside of the + * variant matches the property type. + */ + g_variant_get (parameters, "(v)", &nested); + if (!g_str_equal (g_variant_get_type_string (nested), invocation->property_info->signature)) + { + g_warning ("Value returned from property 'Get' call for '%s' should be '%s' but is '%s'", + invocation->property_info->name, invocation->property_info->signature, + g_variant_get_type_string (nested)); + } + g_variant_unref (nested); + } + + else if (g_str_equal (invocation->method_name, "GetAll")) + { + if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a{sv})"))) + { + g_warning ("Type of return value for property 'GetAll' call should be '(a{sv})' but got '%s'", + g_variant_get_type_string (parameters)); + goto out; + } + + /* Could iterate the list of properties and make sure that all + * of them are actually on the interface and with the correct + * types, but let's not do that for now... + */ + } + + else if (g_str_equal (invocation->method_name, "Set")) + { + if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE_UNIT)) + { + g_warning ("Type of return value for property 'Set' call should be '()' but got '%s'", + g_variant_get_type_string (parameters)); + goto out; + } + } + + else + g_assert_not_reached (); + } + if (G_UNLIKELY (_g_dbus_debug_return ())) { _g_dbus_debug_print_lock ();