From 6bef72364df3dc56160eb309b280ebd40ac2cc26 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 17 Apr 2019 16:44:58 +0200 Subject: [PATCH 01/12] cli: fix handling empty match.interface-name property --- clients/common/nm-meta-setting-desc.c | 12 +++++++++--- clients/common/nm-meta-setting-desc.h | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 334b531f1b..964925f644 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -3455,16 +3455,22 @@ _get_fcn_match_interface_name (ARGS_GET_FCN) num = nm_setting_match_get_num_interface_names (s_match); for (i = 0; i < num; i++) { - const char *name; gs_free char *to_free = NULL; + const char *name; - if (i == 0) + name = nm_setting_match_get_interface_name (s_match, i); + if (!name || !name[0]) + continue; + if (!str) str = g_string_new (""); else g_string_append_c (str, ' '); - name = nm_setting_match_get_interface_name (s_match, i); g_string_append (str, _value_strescape (name, &to_free)); } + + NM_SET_OUT (out_is_default, num == 0); + if (!str) + return NULL; RETURN_STR_TO_FREE (g_string_free (str, FALSE)); } diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index 44a6827b7e..fbc3867a5c 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -438,7 +438,7 @@ struct _NMMetaType { NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags, NMMetaAccessorGetOutFlags *out_flags, - gboolean *out_is_defalt, + gboolean *out_is_default, gpointer *out_to_free); const char *const*(*complete_fcn) (const NMMetaAbstractInfo *info, const NMMetaEnvironment *environment, From 758bf32640f4bc8e265ca572aba38a5c619bd6e5 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 17 Apr 2019 16:52:20 +0200 Subject: [PATCH 02/12] cli: fix splitting of multilist property in setter The modes VALUE_STRSPLIT_MODE_OBJLIST* and VALUE_STRSPLIT_MODE_MULTILIST* are different. We must use the right mode. For example, _get_fcn_match_interface_name() concatenates the interface-names with space. So, the tokenizer of the setter must also use space as delimiter. VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE does that correctly, VALUE_STRSPLIT_MODE_OBJLIST_WITH_ESCAPE does not. --- clients/common/nm-meta-setting-desc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 964925f644..db4b93f623 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -1893,8 +1893,8 @@ _set_fcn_multilist (ARGS_SET_FCN) property_info->property_typ_data->subtype.multilist.strsplit_escaped_tokens ? VALUE_STRSPLIT_MODE_ESCAPED_TOKENS : ( property_info->property_typ_data->subtype.multilist.strsplit_with_escape - ? VALUE_STRSPLIT_MODE_OBJLIST_WITH_ESCAPE - : VALUE_STRSPLIT_MODE_OBJLIST), + ? VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE + : VALUE_STRSPLIT_MODE_MULTILIST), &nstrv); j = 0; From 5a71592087038a17009c12acd8d44d42cb01803e Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 17 Apr 2019 16:04:55 +0200 Subject: [PATCH 03/12] cli: default splitting list properties with escaped-tokens style When splitting (and concatenating) list-typed properties, we really should use nm_utils_escaped_tokens_split() and nm_utils_escaped_tokens_escape*(). Make that the default, and mark all properties to opt-in to the legacy behavior. --- clients/common/nm-meta-setting-desc.c | 42 ++++++++++++++++++++------- clients/common/nm-meta-setting-desc.h | 4 +-- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index db4b93f623..9b880833e7 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -1890,11 +1890,11 @@ _set_fcn_multilist (ARGS_SET_FCN) } strv = _value_strsplit (value, - property_info->property_typ_data->subtype.multilist.strsplit_escaped_tokens - ? VALUE_STRSPLIT_MODE_ESCAPED_TOKENS + property_info->property_typ_data->subtype.multilist.strsplit_plain + ? VALUE_STRSPLIT_MODE_MULTILIST : ( property_info->property_typ_data->subtype.multilist.strsplit_with_escape ? VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE - : VALUE_STRSPLIT_MODE_MULTILIST), + : VALUE_STRSPLIT_MODE_ESCAPED_TOKENS), &nstrv); j = 0; @@ -3283,11 +3283,11 @@ _set_fcn_objlist (ARGS_SET_FCN) } strv = _value_strsplit (value, - property_info->property_typ_data->subtype.objlist.strsplit_escaped_tokens - ? VALUE_STRSPLIT_MODE_ESCAPED_TOKENS + property_info->property_typ_data->subtype.objlist.strsplit_plain + ? VALUE_STRSPLIT_MODE_OBJLIST : ( property_info->property_typ_data->subtype.objlist.strsplit_with_escape ? VALUE_STRSPLIT_MODE_OBJLIST_WITH_ESCAPE - : VALUE_STRSPLIT_MODE_OBJLIST), + : VALUE_STRSPLIT_MODE_ESCAPED_TOKENS), &nstrv); if (_SET_FCN_DO_SET_ALL (modifier, value)) { @@ -4582,6 +4582,7 @@ static const NMMetaPropertyInfo *const property_infos_802_1X[] = { .add_fcn = MULTILIST_ADD_FCN (NMSetting8021x, nm_setting_802_1x_add_eap_method), .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSetting8021x, nm_setting_802_1x_remove_eap_method), .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSetting8021x, nm_setting_802_1x_remove_eap_method_by_value), + .strsplit_plain = TRUE, ), .values_static = NM_MAKE_STRV ("leap", "md5", "tls", "peap", "ttls", "sim", "fast", "pwd"), ), @@ -4627,6 +4628,7 @@ static const NMMetaPropertyInfo *const property_infos_802_1X[] = { .add_fcn = MULTILIST_ADD_FCN (NMSetting8021x, nm_setting_802_1x_add_altsubject_match), .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSetting8021x, nm_setting_802_1x_remove_altsubject_match), .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSetting8021x, nm_setting_802_1x_remove_altsubject_match_by_value), + .strsplit_plain = TRUE, ), ), ), @@ -4723,6 +4725,7 @@ static const NMMetaPropertyInfo *const property_infos_802_1X[] = { .add_fcn = MULTILIST_ADD_FCN (NMSetting8021x, nm_setting_802_1x_add_phase2_altsubject_match), .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSetting8021x, nm_setting_802_1x_remove_phase2_altsubject_match), .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSetting8021x, nm_setting_802_1x_remove_phase2_altsubject_match_by_value), + .strsplit_plain = TRUE, ), ), ), @@ -4997,7 +5000,6 @@ static const NMMetaPropertyInfo *const property_infos_BRIDGE[] = { .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingBridge, nm_setting_bridge_clear_vlans), .obj_to_str_fcn = _objlist_obj_to_str_fcn_bridge_vlans, .set_fcn = _objlist_set_fcn_bridge_vlans, - .strsplit_escaped_tokens = TRUE, ), ), ), @@ -5033,7 +5035,6 @@ static const NMMetaPropertyInfo *const property_infos_BRIDGE_PORT[] = { .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingBridgePort, nm_setting_bridge_port_clear_vlans), .obj_to_str_fcn = _objlist_obj_to_str_fcn_bridge_vlans, .set_fcn = _objlist_set_fcn_bridge_vlans, - .strsplit_escaped_tokens = TRUE, ), ), ), @@ -5168,6 +5169,7 @@ static const NMMetaPropertyInfo *const property_infos_CONNECTION[] = { .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingConnection, nm_setting_connection_remove_permission), .remove_by_value_fcn = _multilist_remove_by_value_fcn_connection_permissions, .validate2_fcn = _multilist_validate2_fcn_connection_permissions, + .strsplit_plain = TRUE, ), ), ), @@ -5217,6 +5219,7 @@ static const NMMetaPropertyInfo *const property_infos_CONNECTION[] = { .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingConnection, nm_setting_connection_remove_secondary), .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingConnection, nm_setting_connection_remove_secondary_by_value), .validate2_fcn = _multilist_validate2_fcn_uuid, + .strsplit_plain = TRUE, ), ), ), @@ -5570,6 +5573,7 @@ static const NMMetaPropertyInfo *const property_infos_IP4_CONFIG[] = { .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns), .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_by_value), .validate2_fcn = _multilist_validate2_fcn_ip_config_dns, + .strsplit_plain = TRUE, ), ), ), @@ -5582,6 +5586,7 @@ static const NMMetaPropertyInfo *const property_infos_IP4_CONFIG[] = { .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns_search), .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_search_by_value), .validate_fcn = _multilist_validate_fcn_is_domain, + .strsplit_plain = TRUE, ), ), ), @@ -5593,6 +5598,7 @@ static const NMMetaPropertyInfo *const property_infos_IP4_CONFIG[] = { .add_fcn = _multilist_add_fcn_ip_config_dns_options, .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns_option), .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_option_by_value), + .strsplit_plain = TRUE, ), .is_default_fcn = _is_default_func_ip_config_dns_options, ), @@ -5618,6 +5624,7 @@ static const NMMetaPropertyInfo *const property_infos_IP4_CONFIG[] = { .obj_to_str_fcn = _objlist_obj_to_str_fcn_ip_config_addresses, .set_fcn = _objlist_set_fcn_ip_config_addresses, .remove_by_idx_fcn_s = OBJLIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_address), + .strsplit_plain = TRUE, ), ), ), @@ -5648,6 +5655,7 @@ static const NMMetaPropertyInfo *const property_infos_IP4_CONFIG[] = { .set_fcn = _objlist_set_fcn_ip_config_routes, .remove_by_idx_fcn_s = OBJLIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_route), .delimit_pretty_with_semicolon = TRUE, + .strsplit_plain = TRUE, ), ), ), @@ -5682,7 +5690,6 @@ static const NMMetaPropertyInfo *const property_infos_IP4_CONFIG[] = { .obj_to_str_fcn = _objlist_obj_to_str_fcn_ip_config_routing_rules, .set_fcn = _objlist_set_fcn_ip_config_routing_rules, .remove_by_idx_fcn_u = OBJLIST_REMOVE_BY_IDX_FCN_U (NMSettingIPConfig, nm_setting_ip_config_remove_routing_rule), - .strsplit_escaped_tokens = TRUE, ), ), ), @@ -5778,6 +5785,7 @@ static const NMMetaPropertyInfo *const property_infos_IP6_CONFIG[] = { .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns), .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_by_value), .validate2_fcn = _multilist_validate2_fcn_ip_config_dns, + .strsplit_plain = TRUE, ), ), ), @@ -5790,6 +5798,7 @@ static const NMMetaPropertyInfo *const property_infos_IP6_CONFIG[] = { .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns_search), .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_search_by_value), .validate_fcn = _multilist_validate_fcn_is_domain, + .strsplit_plain = TRUE, ), ), ), @@ -5801,6 +5810,7 @@ static const NMMetaPropertyInfo *const property_infos_IP6_CONFIG[] = { .add_fcn = _multilist_add_fcn_ip_config_dns_options, .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns_option), .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_option_by_value), + .strsplit_plain = TRUE, ), .is_default_fcn = _is_default_func_ip_config_dns_options, ), @@ -5826,6 +5836,7 @@ static const NMMetaPropertyInfo *const property_infos_IP6_CONFIG[] = { .obj_to_str_fcn = _objlist_obj_to_str_fcn_ip_config_addresses, .set_fcn = _objlist_set_fcn_ip_config_addresses, .remove_by_idx_fcn_s = OBJLIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_address), + .strsplit_plain = TRUE, ), ), ), @@ -5856,6 +5867,7 @@ static const NMMetaPropertyInfo *const property_infos_IP6_CONFIG[] = { .set_fcn = _objlist_set_fcn_ip_config_routes, .remove_by_idx_fcn_s = OBJLIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_route), .delimit_pretty_with_semicolon = TRUE, + .strsplit_plain = TRUE, ), ), ), @@ -5890,7 +5902,6 @@ static const NMMetaPropertyInfo *const property_infos_IP6_CONFIG[] = { .obj_to_str_fcn = _objlist_obj_to_str_fcn_ip_config_routing_rules, .set_fcn = _objlist_set_fcn_ip_config_routing_rules, .remove_by_idx_fcn_u = OBJLIST_REMOVE_BY_IDX_FCN_U (NMSettingIPConfig, nm_setting_ip_config_remove_routing_rule), - .strsplit_escaped_tokens = TRUE, ), ), ), @@ -6456,6 +6467,7 @@ static const NMMetaPropertyInfo *const property_infos_SRIOV[] = { .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingSriov, nm_setting_sriov_clear_vfs), .obj_to_str_fcn = _objlist_obj_to_str_fcn_sriov_vfs, .set_fcn = _objlist_set_fcn_sriov_vfs, + .strsplit_plain = TRUE, ), ), ), @@ -6477,6 +6489,7 @@ static const NMMetaPropertyInfo *const property_infos_TC_CONFIG[] = { .obj_to_str_fcn = _objlist_obj_to_str_fcn_tc_config_qdiscs, .set_fcn = _objlist_set_fcn_tc_config_qdiscs, .remove_by_idx_fcn_u = OBJLIST_REMOVE_BY_IDX_FCN_U (NMSettingTCConfig, nm_setting_tc_config_remove_qdisc), + .strsplit_plain = TRUE, ), ), ), @@ -6489,6 +6502,7 @@ static const NMMetaPropertyInfo *const property_infos_TC_CONFIG[] = { .obj_to_str_fcn = _objlist_obj_to_str_fcn_tc_config_tfilters, .set_fcn = _objlist_set_fcn_tc_config_tfilters, .remove_by_idx_fcn_u = OBJLIST_REMOVE_BY_IDX_FCN_U (NMSettingTCConfig, nm_setting_tc_config_remove_tfilter), + .strsplit_plain = TRUE, ), ), ), @@ -6580,6 +6594,7 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = { .add_fcn = MULTILIST_ADD_FCN (NMSettingTeam, nm_setting_team_add_runner_tx_hash), .remove_by_idx_fcn_u = MULTILIST_REMOVE_BY_IDX_FCN_U (NMSettingTeam, nm_setting_team_remove_runner_tx_hash), .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingTeam, nm_setting_team_remove_runner_tx_hash_by_value), + .strsplit_plain = TRUE, ), .values_static = NM_MAKE_STRV ("eth", "vlan", "ipv4", "ipv6", "ip", "l3", "tcp", "udp", "sctp", "l4"), @@ -6650,6 +6665,7 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = { .obj_to_str_fcn = _objlist_obj_to_str_fcn_team_link_watchers, .set_fcn = _objlist_set_fcn_team_link_watchers, .remove_by_idx_fcn_u = OBJLIST_REMOVE_BY_IDX_FCN_U (NMSettingTeam, nm_setting_team_remove_link_watcher), + .strsplit_plain = TRUE, ), ), ), @@ -6726,6 +6742,7 @@ static const NMMetaPropertyInfo *const property_infos_TEAM_PORT[] = { .obj_to_str_fcn = _objlist_obj_to_str_fcn_team_link_watchers, .set_fcn = _objlist_set_fcn_team_link_watchers, .remove_by_idx_fcn_u = OBJLIST_REMOVE_BY_IDX_FCN_U (NMSettingTeamPort, nm_setting_team_port_remove_link_watcher), + .strsplit_plain = TRUE, ), ), ), @@ -7051,6 +7068,7 @@ static const NMMetaPropertyInfo *const property_infos_WIRED[] = { .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingWired, nm_setting_wired_remove_mac_blacklist_item), .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingWired, nm_setting_wired_remove_mac_blacklist_item_by_value), .validate2_fcn = _multilist_validate2_fcn_mac_addr, + .strsplit_plain = TRUE, ), ), ), @@ -7224,6 +7242,7 @@ static const NMMetaPropertyInfo *const property_infos_WIRELESS[] = { .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingWireless, nm_setting_wireless_remove_mac_blacklist_item), .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingWireless, nm_setting_wireless_remove_mac_blacklist_item_by_value), .validate2_fcn = _multilist_validate2_fcn_mac_addr, + .strsplit_plain = TRUE, ), ), ), @@ -7304,6 +7323,7 @@ static const NMMetaPropertyInfo *const property_infos_WIRELESS_SECURITY[] = { .add_fcn = MULTILIST_ADD_FCN (NMSettingWirelessSecurity, nm_setting_wireless_security_add_proto), .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingWirelessSecurity, nm_setting_wireless_security_remove_proto), .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingWirelessSecurity, nm_setting_wireless_security_remove_proto_by_value), + .strsplit_plain = TRUE, ), .values_static = NM_MAKE_STRV ("wpa", "rsn"), ), @@ -7316,6 +7336,7 @@ static const NMMetaPropertyInfo *const property_infos_WIRELESS_SECURITY[] = { .add_fcn = MULTILIST_ADD_FCN (NMSettingWirelessSecurity, nm_setting_wireless_security_add_pairwise), .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingWirelessSecurity, nm_setting_wireless_security_remove_pairwise), .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingWirelessSecurity, nm_setting_wireless_security_remove_pairwise_by_value), + .strsplit_plain = TRUE, ), .values_static = NM_MAKE_STRV ("tkip", "ccmp"), ), @@ -7328,6 +7349,7 @@ static const NMMetaPropertyInfo *const property_infos_WIRELESS_SECURITY[] = { .add_fcn = MULTILIST_ADD_FCN (NMSettingWirelessSecurity, nm_setting_wireless_security_add_group), .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingWirelessSecurity, nm_setting_wireless_security_remove_group), .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingWirelessSecurity, nm_setting_wireless_security_remove_group_by_value), + .strsplit_plain = TRUE, ), .values_static = NM_MAKE_STRV ("wep40", "wep104", "tkip", "ccmp"), ), diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index fbc3867a5c..4942563aab 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -280,8 +280,8 @@ struct _NMMetaPropertyTypData { void (*remove_by_idx_fcn_u) (NMSetting *setting, guint idx); void (*remove_by_idx_fcn_s) (NMSetting *setting, int idx); gboolean (*remove_by_value_fcn) (NMSetting *setting, const char *item); + bool strsplit_plain:1; bool strsplit_with_escape:1; - bool strsplit_escaped_tokens:1; } multilist; struct { guint (*get_num_fcn) (NMSetting *setting); @@ -297,8 +297,8 @@ struct _NMMetaPropertyTypData { void (*remove_by_idx_fcn_u) (NMSetting *setting, guint idx); void (*remove_by_idx_fcn_s) (NMSetting *setting, int idx); bool delimit_pretty_with_semicolon:1; + bool strsplit_plain:1; bool strsplit_with_escape:1; - bool strsplit_escaped_tokens:1; } objlist; struct { gboolean (*set_fcn) (NMSetting *setting, From 84bd1d38dfb2673f0d1163739a0ff008a7217a0d Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 17 Apr 2019 16:29:09 +0200 Subject: [PATCH 04/12] cli: assert for proper escaping when creating objlist string --- clients/common/nm-meta-setting-desc.c | 52 ++++++++++++++++++--------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 9b880833e7..a19dba5c3c 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -252,6 +252,38 @@ _value_strsplit (const char *value, return g_steal_pointer (&strv); } +static gboolean +_value_strsplit_assert_unsplitable (const char *str) +{ +#if NM_MORE_ASSERTS > 5 + gs_free const char **strv_test = NULL; + gsize j, l; + + /* Assert that we cannot split the token and that it + * has no unescaped delimiters. */ + + strv_test = _value_strsplit (str, + VALUE_STRSPLIT_MODE_ESCAPED_TOKENS, + NULL); + nm_assert (NM_PTRARRAY_LEN (strv_test) == 1); + + for (j = 0; str[j] != '\0'; ) { + if (str[j] == '\\') { + j++; + nm_assert (str[j] != '\0'); + } else + nm_assert (!NM_IN_SET (str[j], '\0', ',')); + j++; + } + l = j; + nm_assert ( !g_ascii_isspace (str[l - 1]) + || ( l >= 2 + && str[l - 2] == '\\')); +#endif + + return TRUE; +} + static NMIPAddress * _parse_ip_address (int family, const char *address, GError **error) { @@ -3092,23 +3124,11 @@ _get_fcn_objlist (ARGS_GET_FCN) continue; } -#if NM_MORE_ASSERTS nm_assert (start_offset < str->len); - if ( property_info->property_typ_data->subtype.objlist.strsplit_with_escape - && get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY) { - /* if the strsplit is done with VALUE_STRSPLIT_MODE_OBJLIST_WITH_ESCAPE, then the appended - * value must have no unescaped ','. */ - for (; start_offset < str->len; ) { - if (str->str[start_offset] == '\\') { - start_offset++; - nm_assert (start_offset < str->len); - nm_assert (!NM_IN_SET (str->str[start_offset], '\0')); - } else - nm_assert (!NM_IN_SET (str->str[start_offset], '\0', ',')); - start_offset++; - } - } -#endif + nm_assert (strlen (str->str) == str->len); + nm_assert ( property_info->property_typ_data->subtype.objlist.strsplit_plain + || get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY + || _value_strsplit_assert_unsplitable (&str->str[start_offset])); } NM_SET_OUT (out_is_default, num == 0); From 3f5df5ab7249141d08b0693a38f113e5bf2b3241 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 17 Apr 2019 16:29:28 +0200 Subject: [PATCH 05/12] cli: drop unused strsplit_with_escape mode for objlist properties --- clients/common/nm-meta-setting-desc.c | 10 +--------- clients/common/nm-meta-setting-desc.h | 1 - 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index a19dba5c3c..9260f6eff5 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -173,7 +173,6 @@ _value_str_as_index_list (const char *value, gsize *out_len) typedef enum { VALUE_STRSPLIT_MODE_STRIPPED, VALUE_STRSPLIT_MODE_OBJLIST, - VALUE_STRSPLIT_MODE_OBJLIST_WITH_ESCAPE, VALUE_STRSPLIT_MODE_MULTILIST, VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE, VALUE_STRSPLIT_MODE_ESCAPED_TOKENS, @@ -206,9 +205,6 @@ _value_strsplit (const char *value, case VALUE_STRSPLIT_MODE_OBJLIST: strv = nm_utils_strsplit_set (value, ","); break; - case VALUE_STRSPLIT_MODE_OBJLIST_WITH_ESCAPE: - strv = nm_utils_strsplit_set_full (value, ",", NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING); - break; case VALUE_STRSPLIT_MODE_MULTILIST: strv = nm_utils_strsplit_set (value, " \t,"); break; @@ -239,8 +235,6 @@ _value_strsplit (const char *value, if (split_mode == VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE) _nm_utils_unescape_plain ((char *) s, MULTILIST_WITH_ESCAPE_CHARS, TRUE); - else if (split_mode == VALUE_STRSPLIT_MODE_OBJLIST_WITH_ESCAPE) - _nm_utils_unescape_plain ((char *) s, ",", TRUE); else g_strchomp ((char *) s); @@ -3305,9 +3299,7 @@ _set_fcn_objlist (ARGS_SET_FCN) strv = _value_strsplit (value, property_info->property_typ_data->subtype.objlist.strsplit_plain ? VALUE_STRSPLIT_MODE_OBJLIST - : ( property_info->property_typ_data->subtype.objlist.strsplit_with_escape - ? VALUE_STRSPLIT_MODE_OBJLIST_WITH_ESCAPE - : VALUE_STRSPLIT_MODE_ESCAPED_TOKENS), + : VALUE_STRSPLIT_MODE_ESCAPED_TOKENS, &nstrv); if (_SET_FCN_DO_SET_ALL (modifier, value)) { diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index 4942563aab..c250700abd 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -298,7 +298,6 @@ struct _NMMetaPropertyTypData { void (*remove_by_idx_fcn_s) (NMSetting *setting, int idx); bool delimit_pretty_with_semicolon:1; bool strsplit_plain:1; - bool strsplit_with_escape:1; } objlist; struct { gboolean (*set_fcn) (NMSetting *setting, From b74d9a0bd5703f499c9bd432e85b89eb3f455cb7 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 17 Apr 2019 17:13:20 +0200 Subject: [PATCH 06/12] cli: return early when splitting with %VALUE_STRSPLIT_MODE_STRIPPED The reminder of the function only does (something akin to) g_strstrip(). As we split the strings are spaces to begin with, there is nothing to strip and we can return right away. --- clients/common/nm-meta-setting-desc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 9260f6eff5..65737d8032 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -201,7 +201,8 @@ _value_strsplit (const char *value, switch (split_mode) { case VALUE_STRSPLIT_MODE_STRIPPED: strv = nm_utils_strsplit_set (value, NM_ASCII_SPACES","); - break; + NM_SET_OUT (out_len, NM_PTRARRAY_LEN (strv)); + return g_steal_pointer (&strv); case VALUE_STRSPLIT_MODE_OBJLIST: strv = nm_utils_strsplit_set (value, ","); break; From 6093f49304a2d6bc45d4a8f7a1cac774f1c24203 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 17 Apr 2019 16:35:14 +0200 Subject: [PATCH 07/12] cli: refactor multilist property handling of "match.interface-names" We had %VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE, which was used by "match.interface-names". This uses nm_utils_strsplit_set_full() with %NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING and _nm_utils_unescape_plain(). We want eventually to use nm_utils_escaped_tokens_split() everywhere. We already have %VALUE_STRSPLIT_MODE_ESCAPED_TOKENS, which splits the list at ',' (and strips whitespaces at the around the delimiter). That differs from what %VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE did, which also considered whitespace a delimiter. So, we need a new mode %VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES which replaces the previous mode. Note that the previous implementation did almost the same thing. In fact, I cannot imagine examples where they behaved differently, but my feeling is that there might be some edge cases where this changes behavior. --- clients/common/nm-meta-setting-desc.c | 35 ++++++++++----------------- clients/common/nm-meta-setting-desc.h | 2 +- 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 65737d8032..5a1352ccce 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -165,7 +165,8 @@ _value_str_as_index_list (const char *value, gsize *out_len) return g_steal_pointer (&arr); } -#define MULTILIST_WITH_ESCAPE_CHARS NM_ASCII_SPACES"," +#define ESCAPED_TOKENS_WITH_SPACES_DELIMTER ' ' +#define ESCAPED_TOKENS_WITH_SPACES_DELIMTERS NM_ASCII_SPACES"," #define ESCAPED_TOKENS_DELIMITER ',' #define ESCAPED_TOKENS_DELIMITERS "," @@ -174,16 +175,10 @@ typedef enum { VALUE_STRSPLIT_MODE_STRIPPED, VALUE_STRSPLIT_MODE_OBJLIST, VALUE_STRSPLIT_MODE_MULTILIST, - VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE, VALUE_STRSPLIT_MODE_ESCAPED_TOKENS, + VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES, } ValueStrsplitMode; -static const char * -_value_strescape (const char *str, char **out_to_free) -{ - return _nm_utils_escape_plain (str, MULTILIST_WITH_ESCAPE_CHARS, out_to_free); -} - static const char ** _value_strsplit (const char *value, ValueStrsplitMode split_mode, @@ -209,13 +204,14 @@ _value_strsplit (const char *value, case VALUE_STRSPLIT_MODE_MULTILIST: strv = nm_utils_strsplit_set (value, " \t,"); break; - case VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE: - strv = nm_utils_strsplit_set_full (value, MULTILIST_WITH_ESCAPE_CHARS, NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING); - break; case VALUE_STRSPLIT_MODE_ESCAPED_TOKENS: strv = nm_utils_escaped_tokens_split (value, ESCAPED_TOKENS_DELIMITERS); NM_SET_OUT (out_len, NM_PTRARRAY_LEN (strv)); return g_steal_pointer (&strv); + case VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES: + strv = nm_utils_escaped_tokens_split (value, ESCAPED_TOKENS_WITH_SPACES_DELIMTERS); + NM_SET_OUT (out_len, NM_PTRARRAY_LEN (strv)); + return g_steal_pointer (&strv); default: nm_assert_not_reached (); break; @@ -234,11 +230,7 @@ _value_strsplit (const char *value, if (s[0] == '\0') continue; - if (split_mode == VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE) - _nm_utils_unescape_plain ((char *) s, MULTILIST_WITH_ESCAPE_CHARS, TRUE); - else - g_strchomp ((char *) s); - + g_strchomp ((char *) s); strv[len++] = s; } strv[len] = NULL; @@ -1919,8 +1911,8 @@ _set_fcn_multilist (ARGS_SET_FCN) strv = _value_strsplit (value, property_info->property_typ_data->subtype.multilist.strsplit_plain ? VALUE_STRSPLIT_MODE_MULTILIST - : ( property_info->property_typ_data->subtype.multilist.strsplit_with_escape - ? VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE + : ( property_info->property_typ_data->subtype.multilist.strsplit_with_spaces + ? VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES : VALUE_STRSPLIT_MODE_ESCAPED_TOKENS), &nstrv); @@ -3468,7 +3460,6 @@ _get_fcn_match_interface_name (ARGS_GET_FCN) num = nm_setting_match_get_num_interface_names (s_match); for (i = 0; i < num; i++) { - gs_free char *to_free = NULL; const char *name; name = nm_setting_match_get_interface_name (s_match, i); @@ -3477,8 +3468,8 @@ _get_fcn_match_interface_name (ARGS_GET_FCN) if (!str) str = g_string_new (""); else - g_string_append_c (str, ' '); - g_string_append (str, _value_strescape (name, &to_free)); + g_string_append_c (str, ESCAPED_TOKENS_WITH_SPACES_DELIMTER); + nm_utils_escaped_tokens_escape_gstr (name, ESCAPED_TOKENS_WITH_SPACES_DELIMTERS, str); } NM_SET_OUT (out_is_default, num == 0); @@ -6161,7 +6152,7 @@ static const NMMetaPropertyInfo *const property_infos_MATCH[] = { .add2_fcn = MULTILIST_ADD2_FCN (NMSettingMatch, nm_setting_match_add_interface_name), .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingMatch, nm_setting_match_remove_interface_name), .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingMatch, nm_setting_match_remove_interface_name_by_value), - .strsplit_with_escape = TRUE, + .strsplit_with_spaces = TRUE, ), ), ), diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index c250700abd..a5083ba603 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -281,7 +281,7 @@ struct _NMMetaPropertyTypData { void (*remove_by_idx_fcn_s) (NMSetting *setting, int idx); gboolean (*remove_by_value_fcn) (NMSetting *setting, const char *item); bool strsplit_plain:1; - bool strsplit_with_escape:1; + bool strsplit_with_spaces:1; } multilist; struct { guint (*get_num_fcn) (NMSetting *setting); From 941f27d350f8d086d3dbdda7ae19f6e4fa2856cf Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 17 Apr 2019 17:21:13 +0200 Subject: [PATCH 08/12] ifcfg-rh: use nm_utils_escaped_tokens* for "MATCH_INTERFACE_NAME" For one, use NM_ASCII_SPACES as delimiter when reading "MATCH_INTERFACE_NAME". Previously, it was only " \t". I think there is no change in behavior otherwise. --- src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c | 5 ++--- src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c | 10 ++++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index a5f158a85e..a86e61b9d7 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -1427,13 +1427,12 @@ make_match_setting (shvarFile *ifcfg) if (!v) return NULL; - strv = nm_utils_strsplit_set_full (v, " \t", NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING); + strv = nm_utils_escaped_tokens_split (v, NM_ASCII_SPACES); if (strv) { for (i = 0; strv[i]; i++) { if (!s_match) s_match = (NMSettingMatch *) nm_setting_match_new (); - nm_setting_match_add_interface_name (s_match, - _nm_utils_unescape_spaces ((char *) strv[i], TRUE)); + nm_setting_match_add_interface_name (s_match, strv[i]); } } diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index a8be7cdec2..2be986307e 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -2375,15 +2375,17 @@ write_match_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) num = nm_setting_match_get_num_interface_names (s_match); for (i = 0; i < num; i++) { - gs_free char *to_free = NULL; const char *name; - if (i == 0) + name = nm_setting_match_get_interface_name (s_match, i); + if (!name || !name[0]) + continue; + + if (!str) str = g_string_new (""); else g_string_append_c (str, ' '); - name = nm_setting_match_get_interface_name (s_match, i); - g_string_append (str, _nm_utils_escape_spaces (name, &to_free)); + nm_utils_escaped_tokens_escape_gstr (name, NM_ASCII_SPACES, str); } if (str) From 304eab8703dc1c77211d0c7f32a76932b725bd86 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 17 Apr 2019 17:30:27 +0200 Subject: [PATCH 09/12] shared: remove unused _nm_utils_escape_plain()/_nm_utils_escape_spaces() API ... and the "unescape" variants. This is replaced by nm_utils_escaped_tokens_split() and nm_utils_escaped_tokens_escape*() API. --- libnm-core/tests/test-general.c | 98 ------------------------------- shared/nm-utils/nm-shared-utils.c | 75 ----------------------- shared/nm-utils/nm-shared-utils.h | 17 ------ 3 files changed, 190 deletions(-) diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index d3743e0ede..64f937cbcf 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -8074,102 +8074,6 @@ test_ethtool_offload (void) g_assert_cmpstr (d->optname, ==, NM_ETHTOOL_OPTNAME_FEATURE_RXHASH); } -static void -test_nm_utils_escape_spaces (void) -{ - char *to_free; - - g_assert_cmpstr (_nm_utils_escape_spaces (NULL, &to_free), ==, NULL); - g_free (to_free); - - g_assert_cmpstr (_nm_utils_escape_spaces ("", &to_free), ==, ""); - g_free (to_free); - - g_assert_cmpstr (_nm_utils_escape_spaces (" ", &to_free), ==, "\\ "); - g_free (to_free); - - g_assert_cmpstr (_nm_utils_escape_spaces ("\t ", &to_free), ==, "\\\t\\ "); - g_free (to_free); - - g_assert_cmpstr (_nm_utils_escape_spaces ("abc", &to_free), ==, "abc"); - g_free (to_free); - - g_assert_cmpstr (_nm_utils_escape_spaces ("abc def", &to_free), ==, "abc\\ def"); - g_free (to_free); - - g_assert_cmpstr (_nm_utils_escape_spaces ("abc\tdef", &to_free), ==, "abc\\\tdef"); - g_free (to_free); -} - -static void -_do_test_unescape_spaces (const char *in, const char *out) -{ - nm_auto_free_gstring GString *str_out = g_string_new (NULL); - nm_auto_free_gstring GString *str_in = g_string_new (NULL); - guint i; - - for (i = 0; i < 10; i++) { - - g_string_set_size (str_in, 0); - - g_string_append (str_in, in); - - if (i == 0) - g_assert_cmpstr (_nm_utils_unescape_spaces (str_in->str, FALSE), ==, out); - else if (i == 1) - g_assert_cmpstr (_nm_utils_unescape_spaces (str_in->str, TRUE), ==, out); - else { - bool do_strip = nmtst_get_rand_bool (); - guint n = nmtst_get_rand_int () % 20; - guint j; - - g_string_set_size (str_out, 0); - if (!do_strip) - g_string_append (str_out, out); - - for (j = 0; j < n; j++) { - gboolean append = nmtst_get_rand_bool (); - char ch = nmtst_rand_select (' ', '\t'); - - if (append && out[0] && out[strlen (out) - 1] == '\\') - append = FALSE; - - g_string_insert_c (str_in, append ? -1 : 0, ch); - if (!do_strip) - g_string_insert_c (str_out, append ? -1 : 0, ch); - } - - if (do_strip) - g_assert_cmpstr (_nm_utils_unescape_spaces (str_in->str, TRUE), ==, out); - else - g_assert_cmpstr (_nm_utils_unescape_spaces (str_in->str, FALSE), ==, str_out->str); - } - } -} - -static void -test_nm_utils_unescape_spaces (void) -{ - _do_test_unescape_spaces ("", ""); - _do_test_unescape_spaces ("\\", "\\"); - _do_test_unescape_spaces ("\\ ", " "); - _do_test_unescape_spaces ("\\\t", "\t"); - _do_test_unescape_spaces ("a", "a"); - _do_test_unescape_spaces ("\\a", "\\a"); - _do_test_unescape_spaces ("foobar", "foobar"); - _do_test_unescape_spaces ("foo bar", "foo bar"); - _do_test_unescape_spaces ("foo\\ bar", "foo bar"); - _do_test_unescape_spaces ("foo\\", "foo\\"); - _do_test_unescape_spaces ("\\\\", "\\\\"); - _do_test_unescape_spaces ("foo bar", "foo bar"); - _do_test_unescape_spaces ("\\ foo bar", " foo bar"); - _do_test_unescape_spaces ("\\ foo bar\\ ", " foo bar "); - _do_test_unescape_spaces ("\\\tfoo bar\\\t", "\tfoo bar\t"); - _do_test_unescape_spaces ("\\\tfoo bar \\\t", "\tfoo bar \t"); - _do_test_unescape_spaces ("\\\t", "\t"); - _do_test_unescape_spaces ("\\\t \\ ", "\t "); -} - /*****************************************************************************/ NMTST_DEFINE (); @@ -8323,8 +8227,6 @@ int main (int argc, char **argv) g_test_add_func ("/core/general/_nm_utils_dns_option_find_idx", test_nm_utils_dns_option_find_idx); g_test_add_func ("/core/general/_nm_utils_validate_json", test_nm_utils_check_valid_json); g_test_add_func ("/core/general/_nm_utils_team_config_equal", test_nm_utils_team_config_equal); - g_test_add_func ("/core/general/_nm_utils_escape_spaces", test_nm_utils_escape_spaces); - g_test_add_func ("/core/general/_nm_utils_unescape_spaces", test_nm_utils_unescape_spaces); g_test_add_func ("/core/general/test_nm_utils_enum", test_nm_utils_enum); g_test_add_func ("/core/general/nm-set-out", test_nm_set_out); g_test_add_func ("/core/general/route_attributes/parse", test_route_attributes_parse); diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c index 06cd481ebb..cf08a77fde 100644 --- a/shared/nm-utils/nm-shared-utils.c +++ b/shared/nm-utils/nm-shared-utils.c @@ -2618,81 +2618,6 @@ _nm_utils_user_data_unpack (gpointer user_data, int nargs, ...) /*****************************************************************************/ -const char * -_nm_utils_escape_plain (const char *str, const char *candidates, char **to_free) -{ - const char *ptr = str; - char *ret, *r; - guint8 ch_lookup[256]; - - *to_free = NULL; - - if (!str) - return NULL; - - _char_lookup_table_init (ch_lookup, candidates ?: NM_ASCII_SPACES); - - while (TRUE) { - if (!*ptr) - return str; - if (_char_lookup_has (ch_lookup, *ptr)) - break; - ptr++; - } - - ptr = str; - ret = g_new (char, strlen (str) * 2 + 1); - r = ret; - *to_free = ret; - while (*ptr) { - if (_char_lookup_has (ch_lookup, *ptr)) - *r++ = '\\'; - *r++ = *ptr++; - } - *r = '\0'; - - return ret; -} - -char * -_nm_utils_unescape_plain (char *str, const char *candidates, gboolean do_strip) -{ - gsize i = 0; - gsize j = 0; - gsize preserve_space_at = 0; - guint8 ch_lookup[256]; - - if (!str) - return NULL; - - _char_lookup_table_init (ch_lookup, candidates ?: NM_ASCII_SPACES); - - if (do_strip) { - while (str[i] && _char_lookup_has (ch_lookup, str[i])) - i++; - } - - for (; str[i]; i++) { - if ( str[i] == '\\' - && _char_lookup_has (ch_lookup, str[i+1])) { - preserve_space_at = j; - i++; - } - str[j++] = str[i]; - } - str[j] = '\0'; - - if (do_strip && j > 0) { - while ( --j > preserve_space_at - && _char_lookup_has (ch_lookup, str[j])) - str[j] = '\0'; - } - - return str; -} - -/*****************************************************************************/ - typedef struct { gpointer callback_user_data; GCancellable *cancellable; diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h index 6bfc37acbf..af3c2f830b 100644 --- a/shared/nm-utils/nm-shared-utils.h +++ b/shared/nm-utils/nm-shared-utils.h @@ -1110,23 +1110,6 @@ void _nm_utils_user_data_unpack (gpointer user_data, int nargs, ...); /*****************************************************************************/ -const char *_nm_utils_escape_plain (const char *str, const char *candidates, char **to_free); -char *_nm_utils_unescape_plain (char *str, const char *candidates, gboolean do_strip); - -static inline const char * -_nm_utils_escape_spaces (const char *str, char **to_free) -{ - return _nm_utils_escape_plain (str, NM_ASCII_SPACES, to_free); -} - -static inline char * -_nm_utils_unescape_spaces (char *str, gboolean do_strip) -{ - return _nm_utils_unescape_plain (str, NM_ASCII_SPACES, do_strip); -} - -/*****************************************************************************/ - typedef void (*NMUtilsInvokeOnIdleCallback) (gpointer callback_user_data, GCancellable *cancellable); From 7a92fb6bf4f6a9d285f2d6d5f0f216151ebfbf96 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 18 Apr 2019 07:58:38 +0200 Subject: [PATCH 10/12] cli: unify set of characters to tokenize list properties the only change in behaviour is for VALUE_STRSPLIT_MODE_MULTILIST. Previously, we would split at " \t,", now we will also split at the white space characters "\n\r\f". --- clients/common/nm-meta-setting-desc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 5a1352ccce..1d1a5c6d92 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -195,14 +195,14 @@ _value_strsplit (const char *value, /* note that all modes remove empty tokens (",", "a,,b", ",,"). */ switch (split_mode) { case VALUE_STRSPLIT_MODE_STRIPPED: - strv = nm_utils_strsplit_set (value, NM_ASCII_SPACES","); + strv = nm_utils_strsplit_set (value, ESCAPED_TOKENS_WITH_SPACES_DELIMTERS); NM_SET_OUT (out_len, NM_PTRARRAY_LEN (strv)); return g_steal_pointer (&strv); case VALUE_STRSPLIT_MODE_OBJLIST: - strv = nm_utils_strsplit_set (value, ","); + strv = nm_utils_strsplit_set (value, ESCAPED_TOKENS_DELIMITERS); break; case VALUE_STRSPLIT_MODE_MULTILIST: - strv = nm_utils_strsplit_set (value, " \t,"); + strv = nm_utils_strsplit_set (value, ESCAPED_TOKENS_WITH_SPACES_DELIMTERS); break; case VALUE_STRSPLIT_MODE_ESCAPED_TOKENS: strv = nm_utils_escaped_tokens_split (value, ESCAPED_TOKENS_DELIMITERS); From bbfd366805f8c389a9445337499aabd04cb0929f Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 18 Apr 2019 08:08:32 +0200 Subject: [PATCH 11/12] cli: cleanup _get_fcn_vlan_xgress_priority_map() - merge the pointless helper function vlan_priorities_to_string() into the only caller _get_fcn_vlan_xgress_priority_map(). - minor cleanups, like setting out-is-default if num==0, not based on whether we have a non-empty string. There is not difference in practice, because nm_setting_vlan_get_priority() never fails. Hence they are identical. But nm_setting_vlan_get_priority() has an API that allows it to fail, so we should declare the default depending on the number of vlan priorities. - don't allocate the temporary GString instance if we won't need it. - only append the delimiter if needed, and not truncate it afterwards. It might have even worse performance this way, but it feels more correct to me. - also cache the result of nm_setting_vlan_get_num_priorities(). NMSettingVlan's implementation is horrible and uses a GSList to track the list of priorities. This makes it relatively expensive to call get-num-priorities repeatedly (and pointless). --- clients/common/nm-meta-setting-desc.c | 44 +++++++++++++-------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 1d1a5c6d92..53a945c827 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -1777,25 +1777,6 @@ vlan_flags_to_string (guint32 flags, NMMetaAccessorGetType get_type) return g_string_free (flag_str, FALSE); } -static char * -vlan_priorities_to_string (NMSettingVlan *s_vlan, NMVlanPriorityMap map) -{ - GString *priorities; - int i; - - priorities = g_string_new (NULL); - for (i = 0; i < nm_setting_vlan_get_num_priorities (s_vlan, map); i++) { - guint32 from, to; - - if (nm_setting_vlan_get_priority (s_vlan, map, i, &from, &to)) - g_string_append_printf (priorities, "%d:%d,", from, to); - } - if (priorities->len) - g_string_truncate (priorities, priorities->len-1); /* chop off trailing ',' */ - - return g_string_free (priorities, FALSE); -} - static char * secret_flags_to_string (guint32 flags, NMMetaAccessorGetType get_type) { @@ -3862,14 +3843,31 @@ _vlan_priority_map_type_from_property_info (const NMMetaPropertyInfo *property_i static gconstpointer _get_fcn_vlan_xgress_priority_map (ARGS_GET_FCN) { + NMVlanPriorityMap map_type = _vlan_priority_map_type_from_property_info (property_info); NMSettingVlan *s_vlan = NM_SETTING_VLAN (setting); - char *str; + GString *str = NULL; + guint32 i, num; RETURN_UNSUPPORTED_GET_TYPE (); - str = vlan_priorities_to_string (s_vlan, _vlan_priority_map_type_from_property_info (property_info)); - NM_SET_OUT (out_is_default, !str || !str[0]); - RETURN_STR_TO_FREE (str); + num = nm_setting_vlan_get_num_priorities (s_vlan, map_type); + for (i = 0; i < num; i++) { + guint32 from, to; + + if (!nm_setting_vlan_get_priority (s_vlan, map_type, i, &from, &to)) + continue; + + if (!str) + str = g_string_new (NULL); + else + g_string_append_c (str, ','); + g_string_append_printf (str, "%d:%d", from, to); + } + + NM_SET_OUT (out_is_default, num == 0); + if (!str) + return NULL; + RETURN_STR_TO_FREE (g_string_free (str, FALSE)); } static gboolean From 7f01da917ef866c5976c359375e26c6aa33206cc Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 18 Apr 2019 08:16:27 +0200 Subject: [PATCH 12/12] cli: use "escaped-tokens" style for splitting "vlan.xgress-priority-map" list There should be little difference here, because the priority list is (and was) never serialized with special characters like backslashes or delimiters that require escaping. Likewise, no working code actually tried to set such characters. Still, drop the plain VALUE_STRSPLIT_MODE_STRIPPED and use VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES instead. We should have a small set of modes that we use for splitting strings. --- clients/common/nm-meta-setting-desc.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 53a945c827..ffaf60714c 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -172,7 +172,6 @@ _value_str_as_index_list (const char *value, gsize *out_len) #define ESCAPED_TOKENS_DELIMITERS "," typedef enum { - VALUE_STRSPLIT_MODE_STRIPPED, VALUE_STRSPLIT_MODE_OBJLIST, VALUE_STRSPLIT_MODE_MULTILIST, VALUE_STRSPLIT_MODE_ESCAPED_TOKENS, @@ -194,10 +193,6 @@ _value_strsplit (const char *value, /* note that all modes remove empty tokens (",", "a,,b", ",,"). */ switch (split_mode) { - case VALUE_STRSPLIT_MODE_STRIPPED: - strv = nm_utils_strsplit_set (value, ESCAPED_TOKENS_WITH_SPACES_DELIMTERS); - NM_SET_OUT (out_len, NM_PTRARRAY_LEN (strv)); - return g_steal_pointer (&strv); case VALUE_STRSPLIT_MODE_OBJLIST: strv = nm_utils_strsplit_set (value, ESCAPED_TOKENS_DELIMITERS); break; @@ -3860,7 +3855,7 @@ _get_fcn_vlan_xgress_priority_map (ARGS_GET_FCN) if (!str) str = g_string_new (NULL); else - g_string_append_c (str, ','); + g_string_append_c (str, ESCAPED_TOKENS_WITH_SPACES_DELIMTER); g_string_append_printf (str, "%d:%d", from, to); } @@ -3882,7 +3877,7 @@ _set_fcn_vlan_xgress_priority_map (ARGS_SET_FCN) return TRUE; } - prio_map = _value_strsplit (value, VALUE_STRSPLIT_MODE_STRIPPED, &len); + prio_map = _value_strsplit (value, VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES, &len); for (i = 0; i < len; i++) { if (!nm_utils_vlan_priority_map_parse_str (map_type,