diff --git a/src/core/dns/nm-dns-manager.c b/src/core/dns/nm-dns-manager.c index 86d65c0510..8f87fec1ba 100644 --- a/src/core/dns/nm-dns-manager.c +++ b/src/core/dns/nm-dns-manager.c @@ -543,7 +543,7 @@ add_string_item(GPtrArray *array, const char *str, gboolean dup) static void add_dns_option_item(GPtrArray *array, const char *str) { - if (_nm_utils_dns_option_find_idx(array, str) < 0) + if (_nm_utils_dns_option_find_idx((const char *const *) array->pdata, array->len, str) < 0) g_ptr_array_add(array, g_strdup(str)); } diff --git a/src/libnm-core-impl/nm-setting-ip-config.c b/src/libnm-core-impl/nm-setting-ip-config.c index 1cae1e4447..c55babaf20 100644 --- a/src/libnm-core-impl/nm-setting-ip-config.c +++ b/src/libnm-core-impl/nm-setting-ip-config.c @@ -4345,6 +4345,12 @@ nm_setting_ip_config_clear_dns_searches(NMSettingIPConfig *setting) _notify(setting, PROP_DNS_SEARCH); } +static gssize +_dns_option_find_idx_garray(const GArray *arr, const char *option) +{ + return _nm_utils_dns_option_find_idx(nm_g_array_data(arr), nm_g_array_len(arr), option); +} + /** * nm_setting_ip_config_get_num_dns_options: * @setting: the #NMSettingIPConfig @@ -4356,13 +4362,9 @@ nm_setting_ip_config_clear_dns_searches(NMSettingIPConfig *setting) guint nm_setting_ip_config_get_num_dns_options(NMSettingIPConfig *setting) { - NMSettingIPConfigPrivate *priv; - g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), 0); - priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - - return priv->dns_options ? priv->dns_options->len : 0; + return nm_g_array_len(NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dns_options.arr); } /** @@ -4384,7 +4386,7 @@ nm_setting_ip_config_has_dns_options(NMSettingIPConfig *setting) { g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), 0); - return !!NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dns_options; + return !!NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dns_options.arr; } /** @@ -4392,6 +4394,8 @@ nm_setting_ip_config_has_dns_options(NMSettingIPConfig *setting) * @setting: the #NMSettingIPConfig * @idx: index number of the DNS option * + * Since 1.46, access at index "len" is allowed and returns NULL. + * * Returns: the DNS option at index @idx * * Since: 1.2 @@ -4399,15 +4403,11 @@ nm_setting_ip_config_has_dns_options(NMSettingIPConfig *setting) const char * nm_setting_ip_config_get_dns_option(NMSettingIPConfig *setting, guint idx) { - NMSettingIPConfigPrivate *priv; - g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NULL); - priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - g_return_val_if_fail(priv->dns_options, NULL); - g_return_val_if_fail(idx < priv->dns_options->len, NULL); - - return priv->dns_options->pdata[idx]; + return nm_strvarray_get_idxnull_or_greturn( + NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dns_options.arr, + idx); } /** @@ -4427,11 +4427,11 @@ nm_setting_ip_config_next_valid_dns_option(NMSettingIPConfig *setting, guint idx priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - if (!priv->dns_options) + if (!priv->dns_options.arr) return -1; - for (; idx < priv->dns_options->len; idx++) { - if (_nm_utils_dns_option_validate(priv->dns_options->pdata[idx], + for (; idx < priv->dns_options.arr->len; idx++) { + if (_nm_utils_dns_option_validate(nm_strvarray_get_idx(priv->dns_options.arr, idx), NULL, NULL, NM_SETTING_IP_CONFIG_GET_ADDR_FAMILY(setting), @@ -4466,14 +4466,11 @@ nm_setting_ip_config_add_dns_option(NMSettingIPConfig *setting, const char *dns_ return FALSE; priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - if (!priv->dns_options) - priv->dns_options = g_ptr_array_new_with_free_func(g_free); - else { - if (_nm_utils_dns_option_find_idx(priv->dns_options, dns_option) >= 0) - return FALSE; - } - g_ptr_array_add(priv->dns_options, g_strdup(dns_option)); + if (_dns_option_find_idx_garray(priv->dns_options.arr, dns_option) >= 0) + return FALSE; + + nm_strvarray_ensure_and_add(&priv->dns_options.arr, dns_option); _notify(setting, PROP_DNS_OPTIONS); return TRUE; } @@ -4495,10 +4492,10 @@ nm_setting_ip_config_remove_dns_option(NMSettingIPConfig *setting, int idx) g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - g_return_if_fail(priv->dns_options); - g_return_if_fail(idx >= 0 && idx < priv->dns_options->len); - g_ptr_array_remove_index(priv->dns_options, idx); + g_return_if_fail(idx >= 0 && idx < nm_g_array_len(priv->dns_options.arr)); + + nm_strvarray_remove_index(priv->dns_options.arr, idx); _notify(setting, PROP_DNS_OPTIONS); } @@ -4524,17 +4521,14 @@ nm_setting_ip_config_remove_dns_option_by_value(NMSettingIPConfig *setting, cons g_return_val_if_fail(dns_option[0] != '\0', FALSE); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - if (!priv->dns_options) + + i = _dns_option_find_idx_garray(priv->dns_options.arr, dns_option); + if (i < 0) return FALSE; - i = _nm_utils_dns_option_find_idx(priv->dns_options, dns_option); - if (i >= 0) { - g_ptr_array_remove_index(priv->dns_options, i); - _notify(setting, PROP_DNS_OPTIONS); - return TRUE; - } - - return FALSE; + nm_strvarray_remove_index(priv->dns_options.arr, i); + _notify(setting, PROP_DNS_OPTIONS); + return TRUE; } /** @@ -4555,18 +4549,17 @@ nm_setting_ip_config_clear_dns_options(NMSettingIPConfig *setting, gboolean is_s g_return_if_fail(NM_IS_SETTING_IP_CONFIG(setting)); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - if (!priv->dns_options) { + if (!priv->dns_options.arr) { if (!is_set) return; - priv->dns_options = g_ptr_array_new_with_free_func(g_free); + nm_strvarray_ensure(&priv->dns_options.arr); } else { - if (!is_set) { - g_ptr_array_unref(priv->dns_options); - priv->dns_options = NULL; - } else { - if (priv->dns_options->len == 0) + if (!is_set) + nm_strvarray_clear(&priv->dns_options.arr); + else { + if (priv->dns_options.arr->len == 0) return; - g_ptr_array_set_size(priv->dns_options, 0); + g_array_set_size(priv->dns_options.arr, 0); } } _notify(setting, PROP_DNS_OPTIONS); @@ -6124,9 +6117,13 @@ _nm_sett_info_property_override_create_array_ip_config(int addr_family) .direct_offset = NM_STRUCT_OFFSET_ENSURE_TYPE(NMValueStrv, NMSettingIPConfigPrivate, dns_search)); - _nm_properties_override_gobj(properties_override, - obj_properties[PROP_DNS_OPTIONS], - &nm_sett_info_propert_type_gprop_strv_oldstyle); + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_DNS_OPTIONS], + &nm_sett_info_propert_type_direct_strv, + .direct_offset = + NM_STRUCT_OFFSET_ENSURE_TYPE(NMValueStrv, NMSettingIPConfigPrivate, dns_options), + .direct_strv_preserve_empty = TRUE, ); _nm_properties_override_gobj(properties_override, obj_properties[PROP_DHCP_REJECT_SERVERS], @@ -6151,11 +6148,6 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) case PROP_DNS: g_value_take_boxed(value, _nm_utils_ptrarray_to_strv(priv->dns)); break; - case PROP_DNS_OPTIONS: - g_value_take_boxed(value, - priv->dns_options ? _nm_utils_ptrarray_to_strv(priv->dns_options) - : NULL); - break; case PROP_ADDRESSES: g_value_take_boxed(value, _nm_utils_copy_array(priv->addresses, @@ -6177,9 +6169,10 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) static void set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMSettingIPConfig *setting = NM_SETTING_IP_CONFIG(object); - NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - char **strv; + NMSettingIPConfig *setting = NM_SETTING_IP_CONFIG(object); + NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + gs_unref_array GArray *array_free = NULL; + const char *const *strv; guint i; switch (prop_id) { @@ -6196,21 +6189,16 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps break; } case PROP_DNS_OPTIONS: - strv = g_value_get_boxed(value); - if (!strv) { - if (priv->dns_options) { - g_ptr_array_unref(priv->dns_options); - priv->dns_options = NULL; - } - } else { - if (priv->dns_options) - g_ptr_array_set_size(priv->dns_options, 0); - else - priv->dns_options = g_ptr_array_new_with_free_func(g_free); + strv = g_value_get_boxed(value); + array_free = g_steal_pointer(&priv->dns_options.arr); + if (strv) { + nm_strvarray_ensure(&priv->dns_options.arr); for (i = 0; strv[i]; i++) { - if (_nm_utils_dns_option_validate(strv[i], NULL, NULL, AF_UNSPEC, NULL) - && _nm_utils_dns_option_find_idx(priv->dns_options, strv[i]) < 0) - g_ptr_array_add(priv->dns_options, g_strdup(strv[i])); + const char *str = strv[i]; + + if (_nm_utils_dns_option_validate(str, NULL, NULL, AF_UNSPEC, NULL) + && _dns_option_find_idx_garray(priv->dns_options.arr, str) < 0) + nm_strvarray_add(priv->dns_options.arr, str); } } break; @@ -6256,7 +6244,6 @@ finalize(GObject *object) NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(self); nm_g_ptr_array_unref(priv->dns); - nm_g_ptr_array_unref(priv->dns_options); g_ptr_array_unref(priv->addresses); g_ptr_array_unref(priv->routes); nm_g_ptr_array_unref(priv->routing_rules); diff --git a/src/libnm-core-impl/nm-setting-private.h b/src/libnm-core-impl/nm-setting-private.h index e3f73fec5f..8964f6c798 100644 --- a/src/libnm-core-impl/nm-setting-private.h +++ b/src/libnm-core-impl/nm-setting-private.h @@ -176,8 +176,8 @@ struct _NMSettingIPConfigClass { typedef struct { NMValueStrv dns_search; /* array of domain name strings */ NMValueStrv dhcp_reject_servers; + NMValueStrv dns_options; /* array of DNS options */ GPtrArray *dns; /* array of IP address strings */ - GPtrArray *dns_options; /* array of DNS options */ GPtrArray *addresses; /* array of NMIPAddress */ GPtrArray *routes; /* array of NMIPRoute */ GPtrArray *routing_rules; diff --git a/src/libnm-core-impl/nm-utils.c b/src/libnm-core-impl/nm-utils.c index e59e572ef3..0dda3915ac 100644 --- a/src/libnm-core-impl/nm-utils.c +++ b/src/libnm-core-impl/nm-utils.c @@ -4790,7 +4790,8 @@ _nm_utils_dns_option_validate(const char *option, /** * _nm_utils_dns_option_find_idx: - * @array: an array of strings + * @strv: an array of strings of length @strv_len + * @strv_len: the length of @strv, or -1 for a NULL terminated strv array. * @option: a dns option string * * Searches for an option in an array of strings. The match is @@ -4800,18 +4801,28 @@ _nm_utils_dns_option_validate(const char *option, * found. */ gssize -_nm_utils_dns_option_find_idx(GPtrArray *array, const char *option) +_nm_utils_dns_option_find_idx(const char *const *strv, gssize strv_len, const char *option) { gs_free char *option_name = NULL; - guint i; + gsize l; + gsize i; + + if (strv_len >= 0) + l = strv_len; + else + l = NM_PTRARRAY_LEN(strv); + + if (l == 0) + return -1; if (!_nm_utils_dns_option_validate(option, &option_name, NULL, AF_UNSPEC, NULL)) return -1; - for (i = 0; i < array->len; i++) { + for (i = 0; i < l; i++) { + const char *str = strv[i]; gs_free char *tmp_name = NULL; - if (_nm_utils_dns_option_validate(array->pdata[i], &tmp_name, NULL, AF_UNSPEC, NULL)) { + if (_nm_utils_dns_option_validate(str, &tmp_name, NULL, AF_UNSPEC, NULL)) { if (nm_streq(tmp_name, option_name)) return i; } diff --git a/src/libnm-core-impl/tests/test-general.c b/src/libnm-core-impl/tests/test-general.c index a873861871..e34cc8c282 100644 --- a/src/libnm-core-impl/tests/test-general.c +++ b/src/libnm-core-impl/tests/test-general.c @@ -5375,10 +5375,8 @@ test_setting_ip4_changed_signal(void) g_object_get(s_ip4, NM_SETTING_IP_CONFIG_DNS_OPTIONS, &strv, NULL); g_assert_null(strv); - NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(priv->dns_options)); g_assert_null(nm_setting_ip_config_get_dns_option(s_ip4, 0)); - g_test_assert_expected_messages(); - NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(priv->dns_options)); + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(_idx <= _len)); g_assert_null(nm_setting_ip_config_get_dns_option(s_ip4, 1)); g_test_assert_expected_messages(); @@ -5394,10 +5392,8 @@ test_setting_ip4_changed_signal(void) nm_clear_pointer(&strv, g_strfreev); g_assert_cmpstr(nm_setting_ip_config_get_dns_option(s_ip4, 0), ==, "debug"); - NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx < priv->dns_options->len)); g_assert_null(nm_setting_ip_config_get_dns_option(s_ip4, 1)); - g_test_assert_expected_messages(); - NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx < priv->dns_options->len)); + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(_idx <= _len)); g_assert_null(nm_setting_ip_config_get_dns_option(s_ip4, 2)); g_test_assert_expected_messages(); @@ -5411,14 +5407,13 @@ test_setting_ip4_changed_signal(void) g_assert_cmpstr(strv[0], ==, NULL); nm_clear_pointer(&strv, g_strfreev); - NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx < priv->dns_options->len)); g_assert_null(nm_setting_ip_config_get_dns_option(s_ip4, 0)); - g_test_assert_expected_messages(); - NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx < priv->dns_options->len)); + NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(_idx <= _len)); g_assert_null(nm_setting_ip_config_get_dns_option(s_ip4, 1)); g_test_assert_expected_messages(); - NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(idx >= 0 && idx < priv->dns_options->len)); + NMTST_EXPECT_LIBNM_CRITICAL( + NMTST_G_RETURN_MSG(idx >= 0 && idx < nm_g_array_len(priv->dns_options.arr))); ASSERT_UNCHANGED(nm_setting_ip_config_remove_dns_option(s_ip4, 1)); g_test_assert_expected_messages(); @@ -8878,24 +8873,23 @@ test_nm_utils_dns_option_validate(void) static void test_nm_utils_dns_option_find_idx(void) { - GPtrArray *options; + const char *const options[] = { + "debug", + "timeout:5", + "edns0", + }; - options = g_ptr_array_new(); +#define _find_idx(options, option) \ + _nm_utils_dns_option_find_idx((options), G_N_ELEMENTS(options), ("" option "")) - g_ptr_array_add(options, "debug"); - g_ptr_array_add(options, "timeout:5"); - g_ptr_array_add(options, "edns0"); - - g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "debug"), ==, 0); - g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "debug:1"), ==, 0); - g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "timeout"), ==, 1); - g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "timeout:5"), ==, 1); - g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "timeout:2"), ==, 1); - g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "edns0"), ==, 2); - g_assert_cmpint(_nm_utils_dns_option_find_idx(options, "rotate"), ==, -1); - g_assert_cmpint(_nm_utils_dns_option_find_idx(options, ""), ==, -1); - - g_ptr_array_free(options, TRUE); + g_assert_cmpint(_find_idx(options, "debug"), ==, 0); + g_assert_cmpint(_find_idx(options, "debug:1"), ==, 0); + g_assert_cmpint(_find_idx(options, "timeout"), ==, 1); + g_assert_cmpint(_find_idx(options, "timeout:5"), ==, 1); + g_assert_cmpint(_find_idx(options, "timeout:2"), ==, 1); + g_assert_cmpint(_find_idx(options, "edns0"), ==, 2); + g_assert_cmpint(_find_idx(options, "rotate"), ==, -1); + g_assert_cmpint(_find_idx(options, ""), ==, -1); } /*****************************************************************************/ diff --git a/src/libnm-core-intern/nm-core-internal.h b/src/libnm-core-intern/nm-core-internal.h index 2d42025a61..673348c640 100644 --- a/src/libnm-core-intern/nm-core-internal.h +++ b/src/libnm-core-intern/nm-core-internal.h @@ -413,7 +413,8 @@ gboolean _nm_utils_dns_option_validate(const char *option, long *out_value, int addr_family, const NMUtilsDNSOptionDesc *option_descs); -gssize _nm_utils_dns_option_find_idx(GPtrArray *array, const char *option); + +gssize _nm_utils_dns_option_find_idx(const char *const *strv, gssize strv_len, const char *option); int nm_setting_ip_config_next_valid_dns_option(NMSettingIPConfig *setting, guint idx);