Commit f137d495 authored by Dan Winship's avatar Dan Winship

libnm-core: merge branch 'danw/validate-proptype-rh1182567'

https://bugzilla.redhat.com/show_bug.cgi?id=1182567
parents bf7865e8 76d9fc91
......@@ -660,17 +660,40 @@ get_property_for_dbus (NMSetting *setting,
return dbus_value;
}
static void
set_property_from_dbus (const NMSettingProperty *property, GVariant *src_value, GValue *dst_value)
static gboolean
set_property_from_dbus (const NMSettingProperty *property,
GVariant *src_value,
GValue *dst_value)
{
g_return_if_fail (property->param_spec != NULL);
if (property->from_dbus)
if (property->from_dbus) {
if (!g_variant_type_equal (g_variant_get_type (src_value), property->dbus_type))
return FALSE;
property->from_dbus (src_value, dst_value);
else if (dst_value->g_type == G_TYPE_BYTES)
} else if (dst_value->g_type == G_TYPE_BYTES) {
if (!g_variant_is_of_type (src_value, G_VARIANT_TYPE_BYTESTRING))
return FALSE;
_nm_utils_bytes_from_dbus (src_value, dst_value);
else
g_dbus_gvariant_to_gvalue (src_value, dst_value);
} else {
GValue tmp = G_VALUE_INIT;
g_dbus_gvariant_to_gvalue (src_value, &tmp);
if (G_VALUE_TYPE (&tmp) == G_VALUE_TYPE (dst_value))
*dst_value = tmp;
else {
gboolean success;
success = g_value_transform (&tmp, dst_value);
g_value_unset (&tmp);
if (!success)
return FALSE;
}
}
return TRUE;
}
......@@ -766,7 +789,6 @@ _nm_setting_new_from_dbus (GType setting_type,
GVariant *connection_dict,
GError **error)
{
NMSettingClass *class;
NMSetting *setting;
const NMSettingProperty *properties;
guint n_properties;
......@@ -781,11 +803,6 @@ _nm_setting_new_from_dbus (GType setting_type,
if (connection_dict)
g_return_val_if_fail (g_variant_is_of_type (connection_dict, NM_VARIANT_TYPE_CONNECTION), NULL);
/* g_type_class_ref() ensures the setting class is created if it hasn't
* already been used.
*/
class = g_type_class_ref (setting_type);
/* Build the setting object from the properties we know about; we assume
* that any propreties in @setting_dict that we don't know about can
* either be ignored or else has a backward-compatibility equivalent
......@@ -793,12 +810,32 @@ _nm_setting_new_from_dbus (GType setting_type,
*/
setting = (NMSetting *) g_object_new (setting_type, NULL);
properties = nm_setting_class_get_properties (class, &n_properties);
properties = nm_setting_class_get_properties (NM_SETTING_GET_CLASS (setting), &n_properties);
for (i = 0; i < n_properties; i++) {
const NMSettingProperty *property = &properties[i];
GVariant *value = g_variant_lookup_value (setting_dict, property->name, NULL);
GVariant *value;
if (property->param_spec && !(property->param_spec->flags & G_PARAM_WRITABLE))
continue;
value = g_variant_lookup_value (setting_dict, property->name, NULL);
if (value && property->set_func) {
if (!g_variant_type_equal (g_variant_get_type (value), property->dbus_type)) {
property_type_error:
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("can't set property of type '%s' from value of type '%s'"),
property->dbus_type ?
g_variant_type_peek_string (property->dbus_type) :
g_type_name (property->param_spec->value_type),
g_variant_get_type_string (value));
g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), property->name);
g_variant_unref (value);
g_object_unref (setting);
return NULL;
}
property->set_func (setting,
connection_dict,
property->name,
......@@ -810,11 +847,10 @@ _nm_setting_new_from_dbus (GType setting_type,
} else if (value && property->param_spec) {
GValue object_value = { 0, };
if (!(property->param_spec->flags & G_PARAM_WRITABLE))
continue;
g_value_init (&object_value, property->param_spec->value_type);
set_property_from_dbus (property, value, &object_value);
if (!set_property_from_dbus (property, value, &object_value))
goto property_type_error;
g_object_set_property (G_OBJECT (setting), property->param_spec->name, &object_value);
g_value_unset (&object_value);
}
......@@ -823,8 +859,6 @@ _nm_setting_new_from_dbus (GType setting_type,
g_variant_unref (value);
}
g_type_class_unref (class);
return setting;
}
......
......@@ -1140,6 +1140,183 @@ test_setting_new_from_dbus_enum (void)
g_object_unref (s_serial);
}
static void
test_setting_new_from_dbus_bad (void)
{
NMSetting *setting;
NMConnection *conn;
GBytes *ssid;
GPtrArray *addrs;
GVariant *orig_dict, *dict;
GError *error = NULL;
/* We want to test:
* - ordinary scalar properties
* - string properties
* - GBytes-valued properties (which are handled specially by set_property_from_dbus())
* - enum/flags-valued properties
* - overridden properties
* - transformed properties
*
* No single setting class has examples of all of these, so we need two settings.
*/
conn = nm_simple_connection_new ();
setting = nm_setting_connection_new ();
g_object_set (setting,
NM_SETTING_CONNECTION_ID, "test",
NM_SETTING_CONNECTION_UUID, "83c5a841-1759-4cdb-bfce-8d4087956497",
NULL);
nm_connection_add_setting (conn, setting);
setting = nm_setting_wireless_new ();
ssid = g_bytes_new ("my-ssid", 7);
g_object_set (setting,
/* scalar */
NM_SETTING_WIRELESS_RATE, 100,
/* string */
NM_SETTING_WIRELESS_MODE, NM_SETTING_WIRELESS_MODE_INFRA,
/* GBytes */
NM_SETTING_WIRELESS_SSID, ssid,
/* transformed */
NM_SETTING_WIRELESS_BSSID, "00:11:22:33:44:55",
NULL);
g_bytes_unref (ssid);
nm_connection_add_setting (conn, setting);
setting = nm_setting_ip6_config_new ();
addrs = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref);
g_ptr_array_add (addrs, nm_ip_address_new (AF_INET6, "1234::5678", 64, NULL));
g_object_set (setting,
/* enum */
NM_SETTING_IP6_CONFIG_IP6_PRIVACY, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR,
/* overridden */
NM_SETTING_IP_CONFIG_ADDRESSES, addrs,
/* (needed in order to verify()) */
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO,
NULL);
g_ptr_array_unref (addrs);
nm_connection_add_setting (conn, setting);
orig_dict = nm_connection_to_dbus (conn, NM_CONNECTION_SERIALIZE_ALL);
g_object_unref (conn);
/* sanity-check */
conn = nm_simple_connection_new_from_dbus (orig_dict, &error);
g_assert_no_error (error);
g_assert (conn);
g_object_unref (conn);
/* Compatible mismatches */
dict = g_variant_ref (orig_dict);
NMTST_VARIANT_EDITOR (dict,
NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_WIRELESS_SETTING_NAME,
NM_SETTING_WIRELESS_RATE,
"i", 10);
);
conn = nm_simple_connection_new_from_dbus (dict, &error);
g_assert (conn);
g_assert_no_error (error);
setting = nm_connection_get_setting (conn, NM_TYPE_SETTING_WIRELESS);
g_assert (setting);
g_assert_cmpint (nm_setting_wireless_get_rate (NM_SETTING_WIRELESS (setting)), ==, 10);
g_object_unref (conn);
g_variant_unref (dict);
dict = g_variant_ref (orig_dict);
NMTST_VARIANT_EDITOR (dict,
NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_IP6_PRIVACY,
"i", NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR);
);
conn = nm_simple_connection_new_from_dbus (dict, &error);
g_assert (conn);
g_assert_no_error (error);
setting = nm_connection_get_setting (conn, NM_TYPE_SETTING_IP6_CONFIG);
g_assert (setting);
g_assert_cmpint (nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (setting)), ==, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR);
g_object_unref (conn);
g_variant_unref (dict);
/* Incompatible mismatches */
dict = g_variant_ref (orig_dict);
NMTST_VARIANT_EDITOR (dict,
NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_WIRELESS_SETTING_NAME,
NM_SETTING_WIRELESS_RATE,
"s", "ten");
);
conn = nm_simple_connection_new_from_dbus (dict, &error);
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
g_assert (g_str_has_prefix (error->message, "802-11-wireless.rate:"));
g_clear_error (&error);
g_variant_unref (dict);
dict = g_variant_ref (orig_dict);
NMTST_VARIANT_EDITOR (dict,
NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_WIRELESS_SETTING_NAME,
NM_SETTING_WIRELESS_MODE,
"b", FALSE);
);
conn = nm_simple_connection_new_from_dbus (dict, &error);
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
g_assert (g_str_has_prefix (error->message, "802-11-wireless.mode:"));
g_clear_error (&error);
g_variant_unref (dict);
dict = g_variant_ref (orig_dict);
NMTST_VARIANT_EDITOR (dict,
NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_WIRELESS_SETTING_NAME,
NM_SETTING_WIRELESS_SSID,
"s", "fred");
);
conn = nm_simple_connection_new_from_dbus (dict, &error);
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
g_assert (g_str_has_prefix (error->message, "802-11-wireless.ssid:"));
g_clear_error (&error);
g_variant_unref (dict);
dict = g_variant_ref (orig_dict);
NMTST_VARIANT_EDITOR (dict,
NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_WIRELESS_SETTING_NAME,
NM_SETTING_WIRELESS_BSSID,
"i", 42);
);
conn = nm_simple_connection_new_from_dbus (dict, &error);
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
g_assert (g_str_has_prefix (error->message, "802-11-wireless.bssid:"));
g_clear_error (&error);
g_variant_unref (dict);
dict = g_variant_ref (orig_dict);
NMTST_VARIANT_EDITOR (dict,
NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_IP6_PRIVACY,
"s", "private");
);
conn = nm_simple_connection_new_from_dbus (dict, &error);
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
g_assert (g_str_has_prefix (error->message, "ipv6.ip6-privacy:"));
g_clear_error (&error);
g_variant_unref (dict);
dict = g_variant_ref (orig_dict);
NMTST_VARIANT_EDITOR (dict,
NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_IP_CONFIG_ADDRESSES,
"s", "1234::5678");
);
conn = nm_simple_connection_new_from_dbus (dict, &error);
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
g_assert (g_str_has_prefix (error->message, "ipv6.addresses:"));
g_clear_error (&error);
g_variant_unref (dict);
g_variant_unref (orig_dict);
}
static NMConnection *
new_test_connection (void)
{
......@@ -3901,6 +4078,7 @@ int main (int argc, char **argv)
g_test_add_func ("/core/general/test_setting_new_from_dbus", test_setting_new_from_dbus);
g_test_add_func ("/core/general/test_setting_new_from_dbus_transform", test_setting_new_from_dbus_transform);
g_test_add_func ("/core/general/test_setting_new_from_dbus_enum", test_setting_new_from_dbus_enum);
g_test_add_func ("/core/general/test_setting_new_from_dbus_bad", test_setting_new_from_dbus_bad);
g_test_add_func ("/core/general/test_connection_replace_settings", test_connection_replace_settings);
g_test_add_func ("/core/general/test_connection_replace_settings_from_connection", test_connection_replace_settings_from_connection);
g_test_add_func ("/core/general/test_connection_replace_settings_bad", test_connection_replace_settings_bad);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment