diff --git a/shared/nm-keyfile/nm-keyfile-utils.c b/shared/nm-keyfile/nm-keyfile-utils.c index 041b5eab11..45235495a6 100644 --- a/shared/nm-keyfile/nm-keyfile-utils.c +++ b/shared/nm-keyfile/nm-keyfile-utils.c @@ -9,6 +9,8 @@ #include +#include "nm-glib-aux/nm-str-buf.h" + #include "nm-keyfile-internal.h" #include "nm-setting-wired.h" #include "nm-setting-wireless.h" @@ -102,51 +104,114 @@ nm_keyfile_plugin_get_setting_name_for_alias (const char *alias) /*****************************************************************************/ -/* List helpers */ -#define DEFINE_KF_LIST_WRAPPER(stype, get_ctype, set_ctype) \ -get_ctype \ -nm_keyfile_plugin_kf_get_##stype##_list (GKeyFile *kf, \ - const char *group, \ - const char *key, \ - gsize *out_length, \ - GError **error) \ -{ \ - get_ctype list; \ - const char *alias; \ - GError *local = NULL; \ - gsize l; \ - \ - list = g_key_file_get_##stype##_list (kf, group, key, &l, &local); \ - if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { \ - alias = nm_keyfile_plugin_get_alias_for_setting_name (group); \ - if (alias) { \ - g_clear_error (&local); \ - list = g_key_file_get_##stype##_list (kf, alias, key, &l, &local); \ - } \ - } \ - if (local) \ - g_propagate_error (error, local); \ - if (!list) \ - l = 0; \ - NM_SET_OUT (out_length, l); \ - return list; \ -} \ - \ -void \ -nm_keyfile_plugin_kf_set_##stype##_list (GKeyFile *kf, \ - const char *group, \ - const char *key, \ - set_ctype list[], \ - gsize length) \ -{ \ - const char *alias; \ - \ - alias = nm_keyfile_plugin_get_alias_for_setting_name (group); \ - g_key_file_set_##stype##_list (kf, alias ?: group, key, list, length); \ +char ** +nm_keyfile_plugin_kf_get_string_list (GKeyFile *kf, + const char *group, + const char *key, + gsize *out_length, + GError **error) +{ + char **list; + const char *alias; + GError *local = NULL; + gsize l; + + list = g_key_file_get_string_list (kf, group, key, &l, &local); + if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { + alias = nm_keyfile_plugin_get_alias_for_setting_name (group); + if (alias) { + g_clear_error (&local); + list = g_key_file_get_string_list (kf, alias, key, &l, &local); + } + } + if (local) + g_propagate_error (error, local); + if (!list) + l = 0; + NM_SET_OUT (out_length, l); + return list; } -DEFINE_KF_LIST_WRAPPER(integer, int*, int); -DEFINE_KF_LIST_WRAPPER(string, char **, const char* const); +guint * +nm_keyfile_plugin_kf_get_integer_list_uint (GKeyFile *key_file, + const char *group_name, + const char *key, + gsize *out_length, + GError **error) +{ + GError *key_file_error = NULL; + gs_strfreev char **values = NULL; + gs_free guint *int_values = NULL; + gsize i, num_ints; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + NM_SET_OUT (out_length, 0); + + values = nm_keyfile_plugin_kf_get_string_list (key_file, group_name, key, &num_ints, &key_file_error); + + if (key_file_error) + g_propagate_error (error, key_file_error); + if (!values) + return NULL; + + int_values = g_new (guint, num_ints); + + for (i = 0; i < num_ints; i++) { + gint64 v; + + G_STATIC_ASSERT_EXPR (sizeof (v) > sizeof (guint)); + v = _nm_utils_ascii_str_to_int64 (values[i], 10, 0, G_MAXUINT, -1); + if (v == -1) { + g_set_error (error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Value cannot be interpreted as a list of numbers.")); + return NULL; + } + + int_values[i] = v; + } + + NM_SET_OUT (out_length, num_ints); + return g_steal_pointer (&int_values); +} + +void +nm_keyfile_plugin_kf_set_string_list (GKeyFile *kf, + const char *group, + const char *key, + const char *const*list, + gsize length) +{ + const char *alias; + + alias = nm_keyfile_plugin_get_alias_for_setting_name (group); + g_key_file_set_string_list (kf, alias ?: group, key, list, length); +} + +void +nm_keyfile_plugin_kf_set_integer_list_uint (GKeyFile *kf, + const char *group, + const char *key, + const guint *data, + gsize length) +{ + nm_auto_str_buf NMStrBuf strbuf = { }; + gsize i; + + g_return_if_fail (kf); + g_return_if_fail (!length || data); + g_return_if_fail (group && group[0]); + g_return_if_fail (key && key[0]); + + nm_str_buf_init (&strbuf, length * 4u + 2u, FALSE); + for (i = 0; i < length; i++) + nm_str_buf_append_printf (&strbuf, "%u;", data[i]); + nm_keyfile_plugin_kf_set_value (kf, group, key, nm_str_buf_get_str (&strbuf)); +} void nm_keyfile_plugin_kf_set_integer_list_uint8 (GKeyFile *kf, @@ -155,63 +220,64 @@ nm_keyfile_plugin_kf_set_integer_list_uint8 (GKeyFile *kf, const guint8 *data, gsize length) { + nm_auto_str_buf NMStrBuf strbuf = { }; gsize i; - gsize l = length * 4 + 2; - gs_free char *value = g_malloc (l); - char *s = value; g_return_if_fail (kf); g_return_if_fail (!length || data); g_return_if_fail (group && group[0]); g_return_if_fail (key && key[0]); - value[0] = '\0'; + nm_str_buf_init (&strbuf, length * 4u + 2u, FALSE); for (i = 0; i < length; i++) - nm_utils_strbuf_append (&s, &l, "%d;", (int) data[i]); - nm_assert (l > 0); - nm_keyfile_plugin_kf_set_value (kf, group, key, value); + nm_str_buf_append_printf (&strbuf, "%u;", (guint) data[i]); + nm_keyfile_plugin_kf_set_value (kf, group, key, nm_str_buf_get_str (&strbuf)); } -/* Single value helpers */ -#define DEFINE_KF_WRAPPER(stype, get_ctype, set_ctype) \ +#define DEFINE_KF_WRAPPER_GET(fcn_name, get_ctype, key_file_get_fcn) \ get_ctype \ -nm_keyfile_plugin_kf_get_##stype (GKeyFile *kf, \ - const char *group, \ - const char *key, \ - GError **error) \ +fcn_name (GKeyFile *kf, \ + const char *group, \ + const char *key, \ + GError **error) \ { \ get_ctype val; \ const char *alias; \ GError *local = NULL; \ - \ - val = g_key_file_get_##stype (kf, group, key, &local); \ +\ + val = key_file_get_fcn (kf, group, key, &local); \ if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { \ alias = nm_keyfile_plugin_get_alias_for_setting_name (group); \ if (alias) { \ g_clear_error (&local); \ - val = g_key_file_get_##stype (kf, alias, key, &local); \ + val = key_file_get_fcn (kf, alias, key, &local); \ } \ } \ if (local) \ g_propagate_error (error, local); \ return val; \ -} \ - \ -void \ -nm_keyfile_plugin_kf_set_##stype (GKeyFile *kf, \ - const char *group, \ - const char *key, \ - set_ctype value) \ -{ \ - const char *alias; \ - \ - alias = nm_keyfile_plugin_get_alias_for_setting_name (group); \ - g_key_file_set_##stype (kf, alias ?: group, key, value); \ } -DEFINE_KF_WRAPPER(string, char*, const char*); -DEFINE_KF_WRAPPER(boolean, gboolean, gboolean); -DEFINE_KF_WRAPPER(value, char*, const char*); +DEFINE_KF_WRAPPER_GET (nm_keyfile_plugin_kf_get_string, char *, g_key_file_get_string); +DEFINE_KF_WRAPPER_GET (nm_keyfile_plugin_kf_get_boolean, gboolean, g_key_file_get_boolean); +DEFINE_KF_WRAPPER_GET (nm_keyfile_plugin_kf_get_value, char *, g_key_file_get_value); + +#define DEFINE_KF_WRAPPER_SET(fcn_name, set_ctype, key_file_set_fcn) \ +void \ +fcn_name (GKeyFile *kf, \ + const char *group, \ + const char *key, \ + set_ctype value) \ +{ \ + const char *alias; \ +\ + alias = nm_keyfile_plugin_get_alias_for_setting_name (group); \ + key_file_set_fcn (kf, alias ?: group, key, value); \ +} + +DEFINE_KF_WRAPPER_SET (nm_keyfile_plugin_kf_set_string, const char *, g_key_file_set_string); +DEFINE_KF_WRAPPER_SET (nm_keyfile_plugin_kf_set_boolean, gboolean, g_key_file_set_boolean); +DEFINE_KF_WRAPPER_SET (nm_keyfile_plugin_kf_set_value, const char *, g_key_file_set_value); gint64 nm_keyfile_plugin_kf_get_int64 (GKeyFile *kf, diff --git a/shared/nm-keyfile/nm-keyfile-utils.h b/shared/nm-keyfile/nm-keyfile-utils.h index 98b0129a59..9b35e17ed6 100644 --- a/shared/nm-keyfile/nm-keyfile-utils.h +++ b/shared/nm-keyfile/nm-keyfile-utils.h @@ -19,20 +19,15 @@ const char *nm_keyfile_plugin_get_setting_name_for_alias (const char *alias); /*****************************************************************************/ -void nm_keyfile_plugin_kf_set_integer_list_uint8 (GKeyFile *kf, - const char *group, - const char *key, - const guint8 *list, - gsize length); +guint *nm_keyfile_plugin_kf_get_integer_list_uint (GKeyFile *kf, const char *group, const char *key, gsize *out_length, GError **error); +char **nm_keyfile_plugin_kf_get_string_list (GKeyFile *kf, const char *group, const char *key, gsize *out_length, GError **error); +char *nm_keyfile_plugin_kf_get_string (GKeyFile *kf, const char *group, const char *key, GError **error); +gboolean nm_keyfile_plugin_kf_get_boolean (GKeyFile *kf, const char *group, const char *key, GError **error); +char *nm_keyfile_plugin_kf_get_value (GKeyFile *kf, const char *group, const char *key, GError **error); -int *nm_keyfile_plugin_kf_get_integer_list (GKeyFile *kf, const char *group, const char *key, gsize *out_length, GError **error); -char **nm_keyfile_plugin_kf_get_string_list (GKeyFile *kf, const char *group, const char *key, gsize *out_length, GError **error); -char *nm_keyfile_plugin_kf_get_string (GKeyFile *kf, const char *group, const char *key, GError **error); -gboolean nm_keyfile_plugin_kf_get_boolean (GKeyFile *kf, const char *group, const char *key, GError **error); -char *nm_keyfile_plugin_kf_get_value (GKeyFile *kf, const char *group, const char *key, GError **error); - -void nm_keyfile_plugin_kf_set_integer_list (GKeyFile *kf, const char *group, const char *key, int *list, gsize length); -void nm_keyfile_plugin_kf_set_string_list (GKeyFile *kf, const char *group, const char *key, const char *const*list, gsize length); +void nm_keyfile_plugin_kf_set_integer_list_uint8 (GKeyFile *kf, const char *group, const char *key, const guint8 *list, gsize length); +void nm_keyfile_plugin_kf_set_integer_list_uint (GKeyFile *kf, const char *group, const char *key, const guint *list, gsize length); +void nm_keyfile_plugin_kf_set_string_list (GKeyFile *kf, const char *group, const char *key, const char *const*list, gsize length); void nm_keyfile_plugin_kf_set_string (GKeyFile *kf, const char *group, const char *key, const char *value); void nm_keyfile_plugin_kf_set_boolean (GKeyFile *kf, const char *group, const char *key, gboolean value); diff --git a/shared/nm-keyfile/nm-keyfile.c b/shared/nm-keyfile/nm-keyfile.c index 879b1b004f..c98fbdf2bb 100644 --- a/shared/nm-keyfile/nm-keyfile.c +++ b/shared/nm-keyfile/nm-keyfile.c @@ -164,23 +164,16 @@ read_array_of_uint (GKeyFile *file, const char *key) { gs_unref_array GArray *array = NULL; - gsize length; - gsize i; - gs_free int *tmp = NULL; gs_free_error GError *error = NULL; + gs_free guint *tmp = NULL; + gsize length; - tmp = nm_keyfile_plugin_kf_get_integer_list (file, nm_setting_get_name (setting), key, &length, &error); + tmp = nm_keyfile_plugin_kf_get_integer_list_uint (file, nm_setting_get_name (setting), key, &length, &error); if (error) return; array = g_array_sized_new (FALSE, FALSE, sizeof (guint), length); - - for (i = 0; i < length; i++) { - if (tmp[i] < 0) - return; - g_array_append_val (array, tmp[i]); - } - + g_array_append_vals (array, tmp, length); g_object_set (setting, key, array, NULL); } @@ -941,7 +934,7 @@ mac_address_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key char addr_str[NM_UTILS_HWADDR_LEN_MAX * 3]; guint8 addr_bin[NM_UTILS_HWADDR_LEN_MAX]; gs_free char *tmp_string = NULL; - gs_free int *int_list = NULL; + gs_free guint *int_list = NULL; const char *mac_str; gsize int_list_len; gsize i; @@ -962,12 +955,12 @@ mac_address_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key goto good_addr_bin; /* Old format; list of ints */ - int_list = nm_keyfile_plugin_kf_get_integer_list (info->keyfile, setting_name, key, &int_list_len, NULL); + int_list = nm_keyfile_plugin_kf_get_integer_list_uint (info->keyfile, setting_name, key, &int_list_len, NULL); if (int_list_len == addr_len) { for (i = 0; i < addr_len; i++) { - const int val = int_list[i]; + const guint val = int_list[i]; - if (val < 0 || val > 255) + if (val > 255) break; addr_bin[i] = (guint8) val; } @@ -1851,25 +1844,19 @@ write_array_of_uint (GKeyFile *file, const GValue *value) { GArray *array; - guint i; - gs_free int *tmp_array = NULL; - array = (GArray *) g_value_get_boxed (value); + array = g_value_get_boxed (value); + + nm_assert (!array || g_array_get_element_size (array) == sizeof (guint)); + if (!array || !array->len) return; - g_return_if_fail (g_array_get_element_size (array) == sizeof (guint)); - - tmp_array = g_new (int, array->len); - for (i = 0; i < array->len; i++) { - guint v = g_array_index (array, guint, i); - - if (v > G_MAXINT) - g_return_if_reached (); - tmp_array[i] = (int) v; - } - - nm_keyfile_plugin_kf_set_integer_list (file, nm_setting_get_name (setting), key, tmp_array, array->len); + nm_keyfile_plugin_kf_set_integer_list_uint (file, + nm_setting_get_name (setting), + key, + (const guint *) array->data, + array->len); } static void @@ -3101,24 +3088,24 @@ read_one_setting_value (KeyfileReaderInfo *info, nm_g_object_set_property_int64 (G_OBJECT (setting), key, i64, &err); } } else if (type == G_TYPE_BYTES) { - gs_free int *tmp = NULL; + gs_free guint *tmp = NULL; GByteArray *array; GBytes *bytes; gsize length; int i; gboolean already_warned = FALSE; - tmp = nm_keyfile_plugin_kf_get_integer_list (keyfile, setting_info->setting_name, key, &length, NULL); + tmp = nm_keyfile_plugin_kf_get_integer_list_uint (keyfile, setting_info->setting_name, key, &length, NULL); array = g_byte_array_sized_new (length); for (i = 0; i < length; i++) { - const int val = tmp[i]; + const guint val = tmp[i]; unsigned char v = (unsigned char) (val & 0xFF); - if (val < 0 || val > 255) { + if (val > 255u) { if ( !already_warned && !handle_warn (info, key, NM_KEYFILE_WARN_SEVERITY_WARN, - _("ignoring invalid byte element '%d' (not between 0 and 255 inclusive)"), + _("ignoring invalid byte element '%u' (not between 0 and 255 inclusive)"), val)) { g_byte_array_unref (array); return;