diff options
author | Thomas Haller <thaller@redhat.com> | 2020-06-26 09:36:18 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2020-06-26 09:36:18 +0200 |
commit | 62747bb07653ab362c33abeae04213de7bde177d (patch) | |
tree | cf774d691c95512b64fdfc40d677da013a36c6c0 | |
parent | d0a2eb8f050d753fa2ca65bbab00ef192bec66d2 (diff) | |
parent | 3b4a4bef7b276cbd2ff587d6586ebbce456859eb (diff) | |
download | NetworkManager-62747bb07653ab362c33abeae04213de7bde177d.tar.gz |
all: merge branch 'th/strbuf-uses'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/547
-rw-r--r-- | libnm-core/nm-core-internal.h | 4 | ||||
-rw-r--r-- | libnm-core/nm-keyfile/nm-keyfile-utils.c | 44 | ||||
-rw-r--r-- | libnm-core/nm-keyfile/nm-keyfile.c | 257 | ||||
-rw-r--r-- | libnm-core/nm-setting-bridge.c | 35 | ||||
-rw-r--r-- | libnm-core/nm-setting-ip-config.c | 133 | ||||
-rw-r--r-- | libnm-core/nm-utils.c | 332 | ||||
-rw-r--r-- | libnm-core/tests/test-general.c | 50 | ||||
-rw-r--r-- | shared/nm-glib-aux/nm-shared-utils.c | 10 | ||||
-rw-r--r-- | shared/nm-glib-aux/nm-shared-utils.h | 52 | ||||
-rw-r--r-- | shared/nm-glib-aux/nm-str-buf.h | 99 | ||||
-rw-r--r-- | shared/nm-glib-aux/tests/test-shared-general.c | 2 | ||||
-rw-r--r-- | src/supplicant/nm-supplicant-config.c | 78 |
12 files changed, 672 insertions, 424 deletions
diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index 1d67b09408..a5ccaeaa5c 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -894,10 +894,6 @@ gboolean nm_utils_base64secret_normalize (const char *base64_key, /*****************************************************************************/ -void _nm_bridge_vlan_str_append_rest (const NMBridgeVlan *vlan, - GString *string, - gboolean leading_space); - gboolean nm_utils_connection_is_adhoc_wpa (NMConnection *connection); const char *nm_utils_wifi_freq_to_band (guint32 freq); diff --git a/libnm-core/nm-keyfile/nm-keyfile-utils.c b/libnm-core/nm-keyfile/nm-keyfile-utils.c index 0ffce40b96..e8119b1bd3 100644 --- a/libnm-core/nm-keyfile/nm-keyfile-utils.c +++ b/libnm-core/nm-keyfile/nm-keyfile-utils.c @@ -504,8 +504,9 @@ static const char * _keyfile_key_encode (const char *name, char **out_to_free) { - gsize len, i; - GString *str; + NMStrBuf str; + gsize len; + gsize i; nm_assert (name); nm_assert (out_to_free && !*out_to_free); @@ -555,14 +556,15 @@ _keyfile_key_encode (const char *name, len = i + strlen (&name[i]); nm_assert (len == strlen (name)); - str = g_string_sized_new (len + 15); + + nm_str_buf_init (&str, len + 15u, FALSE); if (name[0] == ' ') { nm_assert (i == 0); - g_string_append (str, "\\20"); + nm_str_buf_append (&str, "\\20"); i = 1; } else - g_string_append_len (str, name, i); + nm_str_buf_append_len (&str, name, i); for (;; i++) { const guchar ch = (guchar) name[i]; @@ -577,21 +579,24 @@ _keyfile_key_encode (const char *name, && g_ascii_isxdigit (name[i + 1]) && g_ascii_isxdigit (name[i + 2])) || ( ch == ' ' - && name[i + 1] == '\0')) - g_string_append_printf (str, "\\%02X", ch); - else - g_string_append_c (str, (char) ch); + && name[i + 1] == '\0')) { + nm_str_buf_append_c (&str, '\\'); + nm_str_buf_append_c_hex (&str, ch, TRUE); + } else + nm_str_buf_append_c (&str, (char) ch); } - return (*out_to_free = g_string_free (str, FALSE)); + return (*out_to_free = nm_str_buf_finalize (&str, NULL)); } static const char * _keyfile_key_decode (const char *key, char **out_to_free) { - gsize i, len; - GString *str; + char *out; + gsize len; + gsize i; + gsize j; nm_assert (key); nm_assert (out_to_free && !*out_to_free); @@ -617,9 +622,12 @@ _keyfile_key_decode (const char *key, return ""; nm_assert (len == strlen (key)); - str = g_string_sized_new (len + 3); - g_string_append_len (str, key, i); + out = g_new (char, len + 1u); + + memcpy (out, key, sizeof (char) * i); + + j = i; for (;;) { const char ch = key[i]; char ch1, ch2; @@ -633,16 +641,18 @@ _keyfile_key_decode (const char *key, && g_ascii_isxdigit ((ch2 = key[i + 2]))) { v = (g_ascii_xdigit_value (ch1) << 4) + g_ascii_xdigit_value (ch2); if (v != 0) { - g_string_append_c (str, (char) v); + out[j++] = (char) v; i += 3; continue; } } - g_string_append_c (str, ch); + out[j++] = ch; i++; } - return (*out_to_free = g_string_free (str, FALSE)); + nm_assert (j <= len); + out[j] = '\0'; + return (*out_to_free = out); } /*****************************************************************************/ diff --git a/libnm-core/nm-keyfile/nm-keyfile.c b/libnm-core/nm-keyfile/nm-keyfile.c index 77af2b6492..aeaf527450 100644 --- a/libnm-core/nm-keyfile/nm-keyfile.c +++ b/libnm-core/nm-keyfile/nm-keyfile.c @@ -16,6 +16,7 @@ #include <arpa/inet.h> #include <linux/pkt_sched.h> +#include "nm-glib-aux/nm-str-buf.h" #include "nm-glib-aux/nm-secret-utils.h" #include "systemd/nm-sd-utils-shared.h" #include "nm-libnm-core-intern/nm-common-macros.h" @@ -2107,79 +2108,81 @@ write_ip_values (GKeyFile *file, const char *gateway, gboolean is_route) { - nm_auto_free_gstring GString *output = NULL; - int addr_family; - guint i; - const char *addr; - const char *gw; - guint32 plen; - char key_name[64]; - char *key_name_idx; - - if (!array->len) - return; - - addr_family = nm_streq (setting_name, NM_SETTING_IP4_CONFIG_SETTING_NAME) - ? AF_INET - : AF_INET6; - - strcpy (key_name, is_route ? "route" : "address"); - key_name_idx = key_name + strlen (key_name); - - output = g_string_sized_new (2*INET_ADDRSTRLEN + 10); - for (i = 0; i < array->len; i++) { - gint64 metric = -1; - - if (is_route) { - NMIPRoute *route = array->pdata[i]; + if (array->len > 0) { + nm_auto_str_buf NMStrBuf output = NM_STR_BUF_INIT (2*INET_ADDRSTRLEN + 10, FALSE); + int addr_family; + guint i; + const char *addr; + const char *gw; + guint32 plen; + char key_name[64]; + char *key_name_idx; + + addr_family = nm_streq (setting_name, NM_SETTING_IP4_CONFIG_SETTING_NAME) + ? AF_INET + : AF_INET6; + + strcpy (key_name, is_route ? "route" : "address"); + key_name_idx = key_name + strlen (key_name); + + for (i = 0; i < array->len; i++) { + gint64 metric = -1; + + if (is_route) { + NMIPRoute *route = array->pdata[i]; + + addr = nm_ip_route_get_dest (route); + plen = nm_ip_route_get_prefix (route); + gw = nm_ip_route_get_next_hop (route); + metric = nm_ip_route_get_metric (route); + } else { + NMIPAddress *address = array->pdata[i]; - addr = nm_ip_route_get_dest (route); - plen = nm_ip_route_get_prefix (route); - gw = nm_ip_route_get_next_hop (route); - metric = nm_ip_route_get_metric (route); - } else { - NMIPAddress *address = array->pdata[i]; + addr = nm_ip_address_get_address (address); + plen = nm_ip_address_get_prefix (address); + gw = (i == 0) + ? gateway + : NULL; + } - addr = nm_ip_address_get_address (address); - plen = nm_ip_address_get_prefix (address); - gw = (i == 0) - ? gateway - : NULL; - } + nm_str_buf_set_size (&output, 0, FALSE, FALSE); + nm_str_buf_append_printf (&output, "%s/%u", addr, plen); + if ( metric != -1 + || gw) { + /* Older versions of the plugin do not support the form + * "a.b.c.d/plen,,metric", so, we always have to write the + * gateway, even if there isn't one. + * The current version supports reading of the above form. + */ + if (!gw) { + if (addr_family == AF_INET) + gw = "0.0.0.0"; + else + gw = "::"; + } - g_string_set_size (output, 0); - g_string_append_printf (output, "%s/%u", addr, plen); - if ( metric != -1 - || gw) { - /* Older versions of the plugin do not support the form - * "a.b.c.d/plen,,metric", so, we always have to write the - * gateway, even if there isn't one. - * The current version supports reading of the above form. - */ - if (!gw) { - if (addr_family == AF_INET) - gw = "0.0.0.0"; - else - gw = "::"; + nm_str_buf_append_c (&output, ','); + nm_str_buf_append (&output, gw); + if ( is_route + && metric != -1) + nm_str_buf_append_printf (&output, ",%lu", (unsigned long) metric); } - g_string_append_printf (output, ",%s", gw); - if ( is_route - && metric != -1) - g_string_append_printf (output, ",%lu", (unsigned long) metric); - } - - sprintf (key_name_idx, "%u", i + 1); - nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, output->str); + sprintf (key_name_idx, "%u", i + 1); + nm_keyfile_plugin_kf_set_string (file, + setting_name, + key_name, + nm_str_buf_get_str (&output)); - if (is_route) { - gs_free char *attributes = NULL; + if (is_route) { + gs_free char *attributes = NULL; - attributes = nm_utils_format_variant_attributes (_nm_ip_route_get_attributes (array->pdata[i]), - ',', '='); - if (attributes) { - g_strlcat (key_name, "_options", sizeof (key_name)); - nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, attributes); + attributes = nm_utils_format_variant_attributes (_nm_ip_route_get_attributes (array->pdata[i]), + ',', '='); + if (attributes) { + g_strlcat (key_name, "_options", sizeof (key_name)); + nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, attributes); + } } } } @@ -2220,34 +2223,29 @@ bridge_vlan_writer (KeyfileWriterInfo *info, const char *key, const GValue *value) { - NMBridgeVlan *vlan; GPtrArray *vlans; - GString *string; - guint i; - - vlans = (GPtrArray *) g_value_get_boxed (value); - if (!vlans || !vlans->len) - return; - string = g_string_new (""); - for (i = 0; i < vlans->len; i++) { - gs_free char *vlan_str = NULL; + vlans = g_value_get_boxed (value); + if ( vlans + && vlans->len > 0) { + const guint string_initial_size = vlans->len * 10u; + nm_auto_str_buf NMStrBuf string = NM_STR_BUF_INIT (string_initial_size, FALSE); + guint i; - vlan = vlans->pdata[i]; - vlan_str = nm_bridge_vlan_to_str (vlan, NULL); - if (!vlan_str) - continue; - if (string->len > 0) - g_string_append (string, ","); - nm_utils_escaped_tokens_escape_gstr_assert (vlan_str, ",", string); - } + for (i = 0; i < vlans->len; i++) { + gs_free char *vlan_str = NULL; - nm_keyfile_plugin_kf_set_string (info->keyfile, - nm_setting_get_name (setting), - "vlans", - string->str); + vlan_str = nm_bridge_vlan_to_str (vlans->pdata[i], NULL); + if (i > 0) + nm_str_buf_append_c (&string, ','); + nm_utils_escaped_tokens_escape_strbuf_assert (vlan_str, ",", &string); + } - g_string_free (string, TRUE); + nm_keyfile_plugin_kf_set_string (info->keyfile, + nm_setting_get_name (setting), + "vlans", + nm_str_buf_get_str (&string)); + } } @@ -2348,17 +2346,21 @@ qdisc_writer (KeyfileWriterInfo *info, const char *key, const GValue *value) { - gsize i; + nm_auto_free_gstring GString *key_name = NULL; + nm_auto_free_gstring GString *value_str = NULL; GPtrArray *array; + guint i; - array = (GPtrArray *) g_value_get_boxed (value); - if (!array || !array->len) + array = g_value_get_boxed (value); + if ( !array + || !array->len) return; for (i = 0; i < array->len; i++) { NMTCQdisc *qdisc = array->pdata[i]; - GString *key_name = g_string_sized_new (16); - GString *value_str = g_string_sized_new (60); + + nm_gstring_prepare (&key_name); + nm_gstring_prepare (&value_str); g_string_append (key_name, "qdisc."); _nm_utils_string_append_tc_parent (key_name, NULL, @@ -2369,9 +2371,6 @@ qdisc_writer (KeyfileWriterInfo *info, NM_SETTING_TC_CONFIG_SETTING_NAME, key_name->str, value_str->str); - - g_string_free (key_name, TRUE); - g_string_free (value_str, TRUE); } } @@ -2381,17 +2380,21 @@ tfilter_writer (KeyfileWriterInfo *info, const char *key, const GValue *value) { - gsize i; + nm_auto_free_gstring GString *key_name = NULL; + nm_auto_free_gstring GString *value_str = NULL; GPtrArray *array; + guint i; - array = (GPtrArray *) g_value_get_boxed (value); - if (!array || !array->len) + array = g_value_get_boxed (value); + if ( !array + || !array->len) return; for (i = 0; i < array->len; i++) { NMTCTfilter *tfilter = array->pdata[i]; - GString *key_name = g_string_sized_new (16); - GString *value_str = g_string_sized_new (60); + + nm_gstring_prepare (&key_name); + nm_gstring_prepare (&value_str); g_string_append (key_name, "tfilter."); _nm_utils_string_append_tc_parent (key_name, NULL, @@ -2402,9 +2405,6 @@ tfilter_writer (KeyfileWriterInfo *info, NM_SETTING_TC_CONFIG_SETTING_NAME, key_name->str, value_str->str); - - g_string_free (key_name, TRUE); - g_string_free (value_str, TRUE); } } @@ -4309,46 +4309,53 @@ char * nm_keyfile_utils_create_filename (const char *name, gboolean with_extension) { - GString *str; - const char *f = name; /* keyfile used to escape with '*', do not change that behavior. * * But for newly added escapings, use '_' instead. * Also, @with_extension is new-style. */ const char ESCAPE_CHAR = with_extension ? '_' : '*'; const char ESCAPE_CHAR2 = '_'; + NMStrBuf str; + char *p; + gsize len; + gsize i; g_return_val_if_fail (name && name[0], NULL); - str = g_string_sized_new (60); + nm_str_buf_init (&str, 0, FALSE); + + len = strlen (name); + + p = nm_str_buf_append_len0 (&str, name, len); /* Convert '/' to ESCAPE_CHAR */ - for (f = name; f[0]; f++) { - if (f[0] == '/') - g_string_append_c (str, ESCAPE_CHAR); - else - g_string_append_c (str, f[0]); + for (i = 0; i < len; i++) { + if (p[i] == '/') + p[i] = ESCAPE_CHAR; } /* nm_keyfile_utils_create_filename() must avoid anything that ignore_filename() would reject. * We can escape here more aggressivly then what we would read back. */ - if (str->str[0] == '.') - str->str[0] = ESCAPE_CHAR2; - if (str->str[str->len - 1] == '~') - str->str[str->len - 1] = ESCAPE_CHAR2; - if ( check_mkstemp_suffix (str->str) - || check_suffix (str->str, PEM_TAG) - || check_suffix (str->str, DER_TAG)) - g_string_append_c (str, ESCAPE_CHAR2); + if (p[0] == '.') + p[0] = ESCAPE_CHAR2; + if (p[str.len - 1] == '~') + p[str.len - 1] = ESCAPE_CHAR2; + + if ( check_mkstemp_suffix (p) + || check_suffix (p, PEM_TAG) + || check_suffix (p, DER_TAG)) + nm_str_buf_append_c (&str, ESCAPE_CHAR2); if (with_extension) - g_string_append (str, NM_KEYFILE_PATH_SUFFIX_NMCONNECTION); + nm_str_buf_append (&str, NM_KEYFILE_PATH_SUFFIX_NMCONNECTION); + + p = nm_str_buf_finalize (&str, NULL); /* nm_keyfile_utils_create_filename() must mirror ignore_filename() */ - nm_assert (!strchr (str->str, '/')); - nm_assert (!nm_keyfile_utils_ignore_filename (str->str, with_extension)); + nm_assert (!strchr (p, '/')); + nm_assert (!nm_keyfile_utils_ignore_filename (p, with_extension)); - return g_string_free (str, FALSE);; + return p; } /*****************************************************************************/ diff --git a/libnm-core/nm-setting-bridge.c b/libnm-core/nm-setting-bridge.c index 2ead27393e..0595af8730 100644 --- a/libnm-core/nm-setting-bridge.c +++ b/libnm-core/nm-setting-bridge.c @@ -10,6 +10,7 @@ #include <ctype.h> #include <stdlib.h> +#include "nm-glib-aux/nm-str-buf.h" #include "nm-connection-private.h" #include "nm-utils.h" #include "nm-utils-private.h" @@ -407,25 +408,6 @@ nm_bridge_vlan_new_clone (const NMBridgeVlan *vlan) return copy; } -void -_nm_bridge_vlan_str_append_rest (const NMBridgeVlan *vlan, - GString *string, - gboolean leading_space) -{ - if (nm_bridge_vlan_is_pvid (vlan)) { - if (leading_space) - g_string_append_c (string, ' '); - g_string_append (string, "pvid"); - leading_space = TRUE; - } - if (nm_bridge_vlan_is_untagged (vlan)) { - if (leading_space) - g_string_append_c (string, ' '); - g_string_append (string, "untagged"); - leading_space = TRUE; - } -} - /** * nm_bridge_vlan_to_str: * @vlan: the %NMBridgeVlan @@ -440,7 +422,7 @@ _nm_bridge_vlan_str_append_rest (const NMBridgeVlan *vlan, char * nm_bridge_vlan_to_str (const NMBridgeVlan *vlan, GError **error) { - GString *string; + NMStrBuf string; g_return_val_if_fail (vlan, NULL); g_return_val_if_fail (!error || !*error, NULL); @@ -449,16 +431,19 @@ nm_bridge_vlan_to_str (const NMBridgeVlan *vlan, GError **error) * future if more parameters are added to the object that could * make it invalid. */ - string = g_string_sized_new (28); + nm_str_buf_init (&string, NM_UTILS_GET_NEXT_REALLOC_SIZE_32, FALSE); if (vlan->vid_start == vlan->vid_end) - g_string_append_printf (string, "%u", vlan->vid_start); + nm_str_buf_append_printf (&string, "%u", vlan->vid_start); else - g_string_append_printf (string, "%u-%u", vlan->vid_start, vlan->vid_end); + nm_str_buf_append_printf (&string, "%u-%u", vlan->vid_start, vlan->vid_end); - _nm_bridge_vlan_str_append_rest (vlan, string, TRUE); + if (nm_bridge_vlan_is_pvid (vlan)) + nm_str_buf_append (&string, " pvid"); + if (nm_bridge_vlan_is_untagged (vlan)) + nm_str_buf_append (&string, " untagged"); - return g_string_free (string, FALSE); + return nm_str_buf_finalize (&string, NULL); } /** diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c index f7a022b6cb..c377452170 100644 --- a/libnm-core/nm-setting-ip-config.c +++ b/libnm-core/nm-setting-ip-config.c @@ -11,6 +11,7 @@ #include <arpa/inet.h> #include <linux/fib_rules.h> +#include "nm-glib-aux/nm-str-buf.h" #include "nm-setting-ip4-config.h" #include "nm-setting-ip6-config.h" #include "nm-utils.h" @@ -3404,7 +3405,7 @@ next_words_consumed: } static void -_rr_string_append_inet_addr (GString *str, +_rr_string_append_inet_addr (NMStrBuf *str, gboolean is_from /* or else is-to */, gboolean required, int addr_family, @@ -3415,26 +3416,26 @@ _rr_string_append_inet_addr (GString *str, if (addr_len == 0) { if (required) { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "%s %s/0", - is_from ? "from" : "to", - (addr_family == AF_INET) - ? "0.0.0.0" - : "::"); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (str, ' '), + "%s %s/0", + is_from ? "from" : "to", + (addr_family == AF_INET) + ? "0.0.0.0" + : "::"); } return; } - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "%s %s", - is_from ? "from" : "to", - nm_utils_inet_ntop (addr_family, - addr_bin, - addr_str)); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (str, ' '), + "%s %s", + is_from ? "from" : "to", + nm_utils_inet_ntop (addr_family, + addr_bin, + addr_str)); if (addr_len != nm_utils_addr_family_to_size (addr_family) * 8) { - g_string_append_printf (str, - "/%u", - addr_len); + nm_str_buf_append_printf (str, + "/%u", + addr_len); } } @@ -3457,8 +3458,8 @@ nm_ip_routing_rule_to_string (const NMIPRoutingRule *self, GHashTable *extra_args, GError **error) { - nm_auto_free_gstring GString *str = NULL; int addr_family; + NMStrBuf str; g_return_val_if_fail (NM_IS_IP_ROUTING_RULE (self, TRUE), NULL); @@ -3494,18 +3495,18 @@ nm_ip_routing_rule_to_string (const NMIPRoutingRule *self, } } - str = g_string_sized_new (30); + nm_str_buf_init (&str, NM_UTILS_GET_NEXT_REALLOC_SIZE_32, FALSE); if (self->priority_has) { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "priority %u", - (guint) self->priority); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '), + "priority %u", + (guint) self->priority); } if (self->invert) - g_string_append (nm_gstring_add_space_delimiter (str), "not"); + nm_str_buf_append (nm_str_buf_append_required_delimiter (&str, ' '), "not"); - _rr_string_append_inet_addr (str, + _rr_string_append_inet_addr (&str, TRUE, ( !self->to_has || !self->to_valid), @@ -3515,7 +3516,7 @@ nm_ip_routing_rule_to_string (const NMIPRoutingRule *self, ? self->from_len : 0); - _rr_string_append_inet_addr (str, + _rr_string_append_inet_addr (&str, FALSE, FALSE, addr_family, @@ -3525,88 +3526,88 @@ nm_ip_routing_rule_to_string (const NMIPRoutingRule *self, : 0); if (self->tos != 0) { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "tos 0x%02x", - (guint) self->tos); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '), + "tos 0x%02x", + (guint) self->tos); } if (self->ipproto != 0) { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "ipproto %u", - (guint) self->ipproto); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '), + "ipproto %u", + (guint) self->ipproto); } if ( self->fwmark != 0 || self->fwmask != 0) { if (self->fwmark != 0) { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "fwmark 0x%x", - self->fwmark); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '), + "fwmark 0x%x", + self->fwmark); } else { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "fwmark 0"); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '), + "fwmark 0"); } if (self->fwmask != 0xFFFFFFFFu) { if (self->fwmask != 0) - g_string_append_printf (str, "/0x%x", self->fwmask); + nm_str_buf_append_printf (&str, "/0x%x", self->fwmask); else - g_string_append_printf (str, "/0"); + nm_str_buf_append_printf (&str, "/0"); } } if ( self->sport_start != 0 || self->sport_end != 0) { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "sport %u", - self->sport_start); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '), + "sport %u", + self->sport_start); if (self->sport_start != self->sport_end) { - g_string_append_printf (str, - "-%u", - self->sport_end); + nm_str_buf_append_printf (&str, + "-%u", + self->sport_end); } } if ( self->dport_start != 0 || self->dport_end != 0) { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "dport %u", - self->dport_start); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '), + "dport %u", + self->dport_start); if (self->dport_start != self->dport_end) { - g_string_append_printf (str, - "-%u", - self->dport_end); + nm_str_buf_append_printf (&str, + "-%u", + self->dport_end); } } if (self->iifname) { - g_string_append (nm_gstring_add_space_delimiter (str), - "iif "); - nm_utils_escaped_tokens_escape_gstr (self->iifname, - NM_ASCII_SPACES, - str); + nm_str_buf_append (nm_str_buf_append_required_delimiter (&str, ' '), + "iif "); + nm_utils_escaped_tokens_escape_strbuf (self->iifname, + NM_ASCII_SPACES, + &str); } if (self->oifname) { - g_string_append (nm_gstring_add_space_delimiter (str), - "oif "); - nm_utils_escaped_tokens_escape_gstr (self->oifname, - NM_ASCII_SPACES, - str); + nm_str_buf_append (nm_str_buf_append_required_delimiter (&str, ' '), + "oif "); + nm_utils_escaped_tokens_escape_strbuf (self->oifname, + NM_ASCII_SPACES, + &str); } if (self->table != 0) { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "table %u", - (guint) self->table); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '), + "table %u", + (guint) self->table); } if (self->suppress_prefixlength != -1) { - g_string_append_printf (nm_gstring_add_space_delimiter (str), - "suppress_prefixlength %d", - (int) self->suppress_prefixlength); + nm_str_buf_append_printf (nm_str_buf_append_required_delimiter (&str, ' '), + "suppress_prefixlength %d", + (int) self->suppress_prefixlength); } - return g_string_free (g_steal_pointer (&str), FALSE); + return nm_str_buf_finalize (&str, NULL); } /*****************************************************************************/ diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index c88afb3238..ca6b70ce20 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -20,6 +20,7 @@ #include "nm-json.h" #endif +#include "nm-glib-aux/nm-str-buf.h" #include "nm-glib-aux/nm-enum-utils.h" #include "nm-glib-aux/nm-time-utils.h" #include "nm-glib-aux/nm-secret-utils.h" @@ -2067,8 +2068,8 @@ nm_utils_ip_addresses_from_variant (GVariant *value, g_variant_iter_init (&attrs_iter, addr_var); while (g_variant_iter_next (&attrs_iter, "{&sv}", &attr_name, &attr_val)) { - if ( strcmp (attr_name, "address") != 0 - && strcmp (attr_name, "prefix") != 0) + if (!NM_IN_STRSET (attr_name, "address", + "prefix")) nm_ip_address_set_attribute (addr, attr_name, attr_val); g_variant_unref (attr_val); } @@ -2193,10 +2194,10 @@ nm_utils_ip_routes_from_variant (GVariant *value, g_variant_iter_init (&attrs_iter, route_var); while (g_variant_iter_next (&attrs_iter, "{&sv}", &attr_name, &attr_val)) { - if ( strcmp (attr_name, "dest") != 0 - && strcmp (attr_name, "prefix") != 0 - && strcmp (attr_name, "next-hop") != 0 - && strcmp (attr_name, "metric") != 0) + if (!NM_IN_STRSET (attr_name, "dest", + "prefix", + "next-hop", + "metric")) nm_ip_route_set_attribute (route, attr_name, attr_val); g_variant_unref (attr_val); } @@ -2376,7 +2377,8 @@ _nm_utils_string_append_tc_qdisc_rest (GString *string, NMTCQdisc *qdisc) const char *kind = nm_tc_qdisc_get_kind (qdisc); gs_free char *str = NULL; - if (handle != TC_H_UNSPEC && strcmp (kind, "ingress") != 0) { + if ( handle != TC_H_UNSPEC + && !nm_streq (kind, "ingress")) { g_string_append (string, "handle "); _string_append_tc_handle (string, handle); g_string_append_c (string, ' '); @@ -2468,7 +2470,7 @@ _tc_read_common_opts (const char *str, variant = g_hash_table_lookup (ht, "kind"); if (variant) { *kind = g_variant_dup_string (variant, NULL); - if (strcmp (*kind, "ingress") == 0) { + if (nm_streq (*kind, "ingress")) { if (*parent == TC_H_UNSPEC) *parent = TC_H_INGRESS; if (*handle == TC_H_UNSPEC) @@ -2524,7 +2526,7 @@ nm_utils_tc_qdisc_from_str (const char *str, GError **error) return NULL; for (i = 0; rest && tc_qdisc_attribute_spec[i]; i++) { - if (strcmp (tc_qdisc_attribute_spec[i]->kind, kind) == 0) { + if (nm_streq (tc_qdisc_attribute_spec[i]->kind, kind)) { options = nm_utils_parse_variant_attributes (rest, ' ', ' ', FALSE, tc_qdisc_attribute_spec[i]->attrs, @@ -2670,9 +2672,9 @@ nm_utils_tc_action_from_str (const char *str, GError **error) } kind = g_variant_get_string (variant, NULL); - if (strcmp (kind, "simple") == 0) + if (nm_streq (kind, "simple")) attrs = tc_action_simple_attribute_spec; - else if (strcmp (kind, "mirred") == 0) + else if (nm_streq (kind, "mirred")) attrs = tc_action_mirred_attribute_spec; else attrs = NULL; @@ -3300,30 +3302,29 @@ nm_utils_uuid_generate_from_string (const char *s, gssize slen, int uuid_type, g char * _nm_utils_uuid_generate_from_strings (const char *string1, ...) { - GString *str; - va_list args; - const char *s; - char *uuid; - if (!string1) return nm_utils_uuid_generate_from_string (NULL, 0, NM_UTILS_UUID_TYPE_VERSION3, NM_UTILS_UUID_NS); - str = g_string_sized_new (120); /* effectively allocates power of 2 (128)*/ + { + nm_auto_str_buf NMStrBuf str = NM_STR_BUF_INIT (NM_UTILS_GET_NEXT_REALLOC_SIZE_104, FALSE); + va_list args; + const char *s; - g_string_append_len (str, string1, strlen (string1) + 1); + nm_str_buf_append_len (&str, string1, strlen (string1) + 1u); - va_start (args, string1); - s = va_arg (args, const char *); - while (s) { - g_string_append_len (str, s, strlen (s) + 1); + va_start (args, string1); s = va_arg (args, const char *); - } - va_end (args); - - uuid = nm_utils_uuid_generate_from_string (str->str, str->len, NM_UTILS_UUID_TYPE_VERSION3, NM_UTILS_UUID_NS); + while (s) { + nm_str_buf_append_len (&str, s, strlen (s) + 1u); + s = va_arg (args, const char *); + } + va_end (args); - g_string_free (str, TRUE); - return uuid; + return nm_utils_uuid_generate_from_string (nm_str_buf_get_str_unsafe (&str), + str.len, + NM_UTILS_UUID_TYPE_VERSION3, + NM_UTILS_UUID_NS); + } } /*****************************************************************************/ @@ -3571,9 +3572,6 @@ nm_utils_file_search_in_paths (const char *progname, gpointer user_data, GError **error) { - GString *tmp; - const char *ret; - g_return_val_if_fail (!error || !*error, NULL); g_return_val_if_fail (progname && progname[0] && !strchr (progname, '/'), NULL); g_return_val_if_fail (file_test_flags || predicate, NULL); @@ -3582,32 +3580,35 @@ nm_utils_file_search_in_paths (const char *progname, * it simpler to pass in a path from configure checks. */ if ( try_first && try_first[0] == '/' - && (file_test_flags == 0 || g_file_test (try_first, file_test_flags)) - && (!predicate || predicate (try_first, user_data))) + && ( file_test_flags == 0 + || g_file_test (try_first, file_test_flags)) + && ( !predicate + || predicate (try_first, user_data))) return g_intern_string (try_first); - if (!paths || !*paths) - goto NOT_FOUND; + if ( paths + && paths[0]) { + nm_auto_str_buf NMStrBuf strbuf = NM_STR_BUF_INIT (NM_UTILS_GET_NEXT_REALLOC_SIZE_104, FALSE); - tmp = g_string_sized_new (50); - for (; *paths; paths++) { - if (!*paths) - continue; - g_string_append (tmp, *paths); - if (tmp->str[tmp->len - 1] != '/') - g_string_append_c (tmp, '/'); - g_string_append (tmp, progname); - if ( (file_test_flags == 0 || g_file_test (tmp->str, file_test_flags)) - && (!predicate || predicate (tmp->str, user_data))) { - ret = g_intern_string (tmp->str); - g_string_free (tmp, TRUE); - return ret; + for (; *paths; paths++) { + const char *path = *paths; + const char *s; + + if (!path[0]) + continue; + + nm_str_buf_reset (&strbuf, path); + nm_str_buf_ensure_trailing_c (&strbuf, '/'); + s = nm_str_buf_append0 (&strbuf, progname); + + if ( ( file_test_flags == 0 + || g_file_test (s, file_test_flags)) + && ( !predicate + || predicate (s, user_data))) + return g_intern_string (s); } - g_string_set_size (tmp, 0); } - g_string_free (tmp, TRUE); -NOT_FOUND: g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("Could not find \"%s\" binary"), progname); return NULL; } @@ -3620,7 +3621,7 @@ struct cf_pair { guint32 freq; }; -static struct cf_pair a_table[] = { +static const struct cf_pair a_table[] = { /* A band */ { 7, 5035 }, { 8, 5040 }, @@ -3667,10 +3668,60 @@ static struct cf_pair a_table[] = { { 188, 4945 }, { 192, 4960 }, { 196, 4980 }, - { 0, -1 } + { 0, 0 } }; -static struct cf_pair bg_table[] = { +static const guint a_table_freqs[G_N_ELEMENTS (a_table)] = { + /* A band */ + 5035, + 5040, + 5045, + 5055, + 5060, + 5080, + 5170, + 5180, + 5190, + 5200, + 5210, + 5220, + 5230, + 5240, + 5250, + 5260, + 5280, + 5290, + 5300, + 5320, + 5500, + 5520, + 5540, + 5560, + 5580, + 5600, + 5620, + 5640, + 5660, + 5680, + 5700, + 5745, + 5760, + 5765, + 5785, + 5800, + 5805, + 5825, + 4915, + 4920, + 4925, + 4935, + 4945, + 4960, + 4980, + 0, +}; + +static const struct cf_pair bg_table[] = { /* B/G band */ { 1, 2412 }, { 2, 2417 }, @@ -3686,7 +3737,26 @@ static struct cf_pair bg_table[] = { { 12, 2467 }, { 13, 2472 }, { 14, 2484 }, - { 0, -1 } + { 0, 0 } +}; + +static const guint bg_table_freqs[G_N_ELEMENTS (bg_table)] = { + /* B/G band */ + 2412, + 2417, + 2422, + 2427, + 2432, + 2437, + 2442, + 2447, + 2452, + 2457, + 2462, + 2467, + 2472, + 2484, + 0, }; /** @@ -3703,16 +3773,16 @@ nm_utils_wifi_freq_to_channel (guint32 freq) int i = 0; if (freq > 4900) { - while (a_table[i].chan && (a_table[i].freq != freq)) + while ( a_table[i].freq + && (a_table[i].freq != freq)) i++; return a_table[i].chan; - } else { - while (bg_table[i].chan && (bg_table[i].freq != freq)) - i++; - return bg_table[i].chan; } - return 0; + while ( bg_table[i].freq + && (bg_table[i].freq != freq)) + i++; + return bg_table[i].chan; } /** @@ -3748,16 +3818,24 @@ nm_utils_wifi_freq_to_band (guint32 freq) guint32 nm_utils_wifi_channel_to_freq (guint32 channel, const char *band) { - int i = 0; + int i; - if (!strcmp (band, "a")) { - while (a_table[i].chan && (a_table[i].chan != channel)) - i++; - return a_table[i].freq; - } else if (!strcmp (band, "bg")) { - while (bg_table[i].chan && (bg_table[i].chan != channel)) - i++; - return bg_table[i].freq; + g_return_val_if_fail (band, 0); + + if (nm_streq (band, "a")) { + for (i = 0; a_table[i].chan; i++) { + if (a_table[i].chan == channel) + return a_table[i].freq; + } + return ((guint32) -1); + } + + if (nm_streq (band, "bg")) { + for (i = 0; bg_table[i].chan; i++) { + if (bg_table[i].chan == channel) + return bg_table[i].freq; + } + return ((guint32) -1); } return 0; @@ -3776,26 +3854,24 @@ nm_utils_wifi_channel_to_freq (guint32 channel, const char *band) guint32 nm_utils_wifi_find_next_channel (guint32 channel, int direction, char *band) { - size_t a_size = sizeof (a_table) / sizeof (struct cf_pair); - size_t bg_size = sizeof (bg_table) / sizeof (struct cf_pair); - struct cf_pair *pair = NULL; + size_t a_size = G_N_ELEMENTS (a_table); + size_t bg_size = G_N_ELEMENTS (bg_table); + const struct cf_pair *pair; - if (!strcmp (band, "a")) { + if (nm_streq (band, "a")) { if (channel < a_table[0].chan) return a_table[0].chan; if (channel > a_table[a_size - 2].chan) return a_table[a_size - 2].chan; pair = &a_table[0]; - } else if (!strcmp (band, "bg")) { + } else if (nm_streq (band, "bg")) { if (channel < bg_table[0].chan) return bg_table[0].chan; if (channel > bg_table[bg_size - 2].chan) return bg_table[bg_size - 2].chan; pair = &bg_table[0]; - } else { - g_assert_not_reached (); - return 0; - } + } else + g_return_val_if_reached (0); while (pair->chan) { if (channel == pair->chan) @@ -3823,49 +3899,32 @@ nm_utils_wifi_find_next_channel (guint32 channel, int direction, char *band) gboolean nm_utils_wifi_is_channel_valid (guint32 channel, const char *band) { - struct cf_pair *table = NULL; - int i = 0; - - if (!strcmp (band, "a")) - table = a_table; - else if (!strcmp (band, "bg")) - table = bg_table; - else - return FALSE; - - while (table[i].chan && (table[i].chan != channel)) - i++; - - if (table[i].chan != 0) - return TRUE; - else - return FALSE; -} - -static const guint * -_wifi_freqs (gboolean bg_band) -{ - static guint *freqs_2ghz = NULL; - static guint *freqs_5ghz = NULL; - guint *freqs; - - freqs = bg_band ? freqs_2ghz : freqs_5ghz; - if (G_UNLIKELY (freqs == NULL)) { - struct cf_pair *table; - int i; + guint32 freq; - table = bg_band ? bg_table : a_table; - freqs = g_new0 (guint, bg_band ? G_N_ELEMENTS (bg_table) : G_N_ELEMENTS (a_table)); - for (i = 0; table[i].chan; i++) - freqs[i] = table[i].freq; - freqs[i] = 0; - if (bg_band) - freqs_2ghz = freqs; - else - freqs_5ghz = freqs; - } - return freqs; -} + freq = nm_utils_wifi_channel_to_freq (channel, band); + + return !NM_IN_SET (freq, 0u, (guint32) -1); +} + +#define _nm_assert_wifi_freqs(table, table_freqs) \ + G_STMT_START { \ + if (NM_MORE_ASSERT_ONCE (5)) { \ + int i, j; \ + \ + G_STATIC_ASSERT (G_N_ELEMENTS (table) > 0); \ + G_STATIC_ASSERT (G_N_ELEMENTS (table) == G_N_ELEMENTS (table_freqs)); \ + \ + for (i = 0; i < G_N_ELEMENTS (table); i++) { \ + nm_assert ((i == G_N_ELEMENTS (table) - 1) == (table[i].chan == 0)); \ + nm_assert ((i == G_N_ELEMENTS (table) - 1) == (table[i].freq == 0)); \ + nm_assert (table[i].freq == table_freqs[i]); \ + for (j = 0; j < i; j++) { \ + nm_assert (table[j].chan != table[i].chan); \ + nm_assert (table[j].freq != table[i].freq); \ + } \ + } \ + } \ + } G_STMT_END /** * nm_utils_wifi_2ghz_freqs: @@ -3879,7 +3938,8 @@ _wifi_freqs (gboolean bg_band) const guint * nm_utils_wifi_2ghz_freqs (void) { - return _wifi_freqs (TRUE); + _nm_assert_wifi_freqs (bg_table, bg_table_freqs); + return bg_table_freqs; } /** @@ -3894,7 +3954,8 @@ nm_utils_wifi_2ghz_freqs (void) const guint * nm_utils_wifi_5ghz_freqs (void) { - return _wifi_freqs (FALSE); + _nm_assert_wifi_freqs (a_table, a_table_freqs); + return a_table_freqs; } /** @@ -5028,7 +5089,7 @@ typedef struct { const char *num; } BondMode; -static BondMode bond_mode_table[] = { +static const BondMode bond_mode_table[] = { [0] = { "balance-rr", "0" }, [1] = { "active-backup", "1" }, [2] = { "balance-xor", "2" }, @@ -5080,8 +5141,8 @@ nm_utils_bond_mode_string_to_int (const char *mode) return -1; for (i = 0; i < G_N_ELEMENTS (bond_mode_table); i++) { - if ( strcmp (mode, bond_mode_table[i].str) == 0 - || strcmp (mode, bond_mode_table[i].num) == 0) + if (NM_IN_STRSET (mode, bond_mode_table[i].str, + bond_mode_table[i].num)) return i; } return -1; @@ -5139,13 +5200,13 @@ _nm_utils_strstrdictkey_equal (gconstpointer a, gconstpointer b) return FALSE; if (k1->type & STRSTRDICTKEY_ALL_SET) { - if (strcmp (k1->data, k2->data) != 0) + if (!nm_streq (k1->data, k2->data)) return FALSE; if (k1->type == STRSTRDICTKEY_ALL_SET) { gsize l = strlen (k1->data) + 1; - return strcmp (&k1->data[l], &k2->data[l]) == 0; + return nm_streq (&k1->data[l], &k2->data[l]); } } @@ -5196,7 +5257,7 @@ validate_dns_option (const char *name, return !!*name; for (desc = option_descs; desc->name; desc++) { - if (!strcmp (name, desc->name) && + if (nm_streq (name, desc->name) && numeric == desc->numeric && (!desc->ipv6_only || ipv6)) return TRUE; @@ -5286,26 +5347,21 @@ _nm_utils_dns_option_validate (const char *option, */ gssize _nm_utils_dns_option_find_idx (GPtrArray *array, const char *option) { - gboolean ret; - char *option_name, *tmp_name; + gs_free char *option_name = NULL; guint i; if (!_nm_utils_dns_option_validate (option, &option_name, NULL, FALSE, NULL)) return -1; for (i = 0; i < array->len; i++) { + gs_free char *tmp_name = NULL; + if (_nm_utils_dns_option_validate (array->pdata[i], &tmp_name, NULL, FALSE, NULL)) { - ret = strcmp (tmp_name, option_name); - g_free (tmp_name); - if (!ret) { - g_free (option_name); + if (nm_streq (tmp_name, option_name)) return i; - } } - } - g_free (option_name); return -1; } diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index f70a7d5a65..a1c716f473 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -9100,6 +9100,55 @@ test_strsplit_quoted (void) /*****************************************************************************/ +static void +_do_wifi_ghz_freqs (const guint *freqs, const char *band) +{ + int len; + int j; + int i; + + g_assert (NM_IN_STRSET (band, "a", "bg")); + g_assert (freqs); + g_assert (freqs[0] != 0); + + for (i = 0; freqs[i]; i++) { + for (j = 0; j < i; j++) + g_assert (freqs[i] != freqs[j]); + } + len = i; + + g_assert (nm_utils_wifi_freq_to_channel (0) == 0); + g_assert (nm_utils_wifi_channel_to_freq (0, "bg") == -1); + g_assert (nm_utils_wifi_channel_to_freq (0, "foo") == 0); + g_assert (!nm_utils_wifi_is_channel_valid (0, "bg")); + g_assert (!nm_utils_wifi_is_channel_valid (0, "foo")); + + for (i = 0; i < len; i++) { + guint freq = freqs[i]; + guint32 chan; + guint32 freq2; + + chan = nm_utils_wifi_freq_to_channel (freq); + g_assert (chan != 0); + + freq2 = nm_utils_wifi_channel_to_freq (chan, band); + g_assert (freq2 == freq); + + g_assert (nm_utils_wifi_is_channel_valid (chan, band)); + } + + g_assert (freqs[len] == 0); +} + +static void +test_nm_utils_wifi_ghz_freqs (void) +{ + _do_wifi_ghz_freqs (nm_utils_wifi_2ghz_freqs (), "bg"); + _do_wifi_ghz_freqs (nm_utils_wifi_5ghz_freqs (), "a"); +} + +/*****************************************************************************/ + NMTST_DEFINE (); int main (int argc, char **argv) @@ -9273,6 +9322,7 @@ int main (int argc, char **argv) g_test_add_data_func ("/core/general/test_integrate_maincontext/2", GUINT_TO_POINTER (2), test_integrate_maincontext); g_test_add_func ("/core/general/test_nm_ip_addr_zero", test_nm_ip_addr_zero); + g_test_add_func ("/core/general/test_nm_utils_wifi_ghz_freqs", test_nm_utils_wifi_ghz_freqs); g_test_add_func ("/core/general/test_strsplit_quoted", test_strsplit_quoted); diff --git a/shared/nm-glib-aux/nm-shared-utils.c b/shared/nm-glib-aux/nm-shared-utils.c index a2e90273c5..8290016448 100644 --- a/shared/nm-glib-aux/nm-shared-utils.c +++ b/shared/nm-glib-aux/nm-shared-utils.c @@ -23,6 +23,9 @@ G_STATIC_ASSERT (G_STRUCT_OFFSET (NMUtilsNamedValue, value_ptr) == sizeof (const /*****************************************************************************/ +const char _nm_hexchar_table_lower[16] = "0123456789abcdef"; +const char _nm_hexchar_table_upper[16] = "0123456789ABCDEF"; + const void *const _NM_PTRARRAY_EMPTY[1] = { NULL }; /*****************************************************************************/ @@ -4966,7 +4969,12 @@ nm_str_buf_append_printf (NMStrBuf *strbuf, nm_assert (l < G_MAXINT); if ((gsize) l >= available) { - gsize l2 = ((gsize) l) + 1u; + gsize l2; + + if (l == 0) + return; + + l2 = ((gsize) l) + 1u; nm_str_buf_maybe_expand (strbuf, l2, FALSE); diff --git a/shared/nm-glib-aux/nm-shared-utils.h b/shared/nm-glib-aux/nm-shared-utils.h index 893ec11c0d..c16a89b3af 100644 --- a/shared/nm-glib-aux/nm-shared-utils.h +++ b/shared/nm-glib-aux/nm-shared-utils.h @@ -631,23 +631,24 @@ nm_utils_escaped_tokens_escape (const char *str, out_to_free); } -static inline GString * -nm_utils_escaped_tokens_escape_gstr_assert (const char *str, - const char *delimiters, - GString *gstring) +/** + * nm_utils_escaped_tokens_escape_unnecessary: + * @str: the string to check for "escape" + * @delimiters: the delimiters + * + * This asserts that calling nm_utils_escaped_tokens_escape() + * on @str has no effect and returns @str directly. This is only + * for asserting that @str is safe to not require any escaping. + * + * Returns: @str + */ +static inline const char * +nm_utils_escaped_tokens_escape_unnecessary (const char *str, + const char *delimiters) { #if NM_MORE_ASSERTS > 0 - /* Just appends @str to @gstring, but also assert that - * no escaping is necessary. - * - * Use nm_utils_escaped_tokens_escape_gstr_assert() instead - * of nm_utils_escaped_tokens_escape_gstr(), if you *know* that - * @str contains no delimiters, no backslashes, and no trailing - * whitespace that requires escaping. */ - nm_assert (str); - nm_assert (gstring); nm_assert (delimiters); { @@ -660,8 +661,16 @@ nm_utils_escaped_tokens_escape_gstr_assert (const char *str, } #endif - g_string_append (gstring, str); - return gstring; + return str; +} + +static inline void +nm_utils_escaped_tokens_escape_gstr_assert (const char *str, + const char *delimiters, + GString *gstring) +{ + g_string_append (gstring, + nm_utils_escaped_tokens_escape_unnecessary (str, delimiters)); } static inline GString * @@ -1809,6 +1818,17 @@ int nm_utils_getpagesize (void); /*****************************************************************************/ +extern const char _nm_hexchar_table_lower[16]; +extern const char _nm_hexchar_table_upper[16]; + +static inline char +nm_hexchar (int x, gboolean upper_case) +{ + return upper_case + ? _nm_hexchar_table_upper[x & 15] + : _nm_hexchar_table_lower[x & 15]; +} + char *nm_utils_bin2hexstr_full (gconstpointer addr, gsize length, char delimiter, @@ -1985,6 +2005,8 @@ void nm_indirect_g_free (gpointer arg); * via nm_utils_get_next_realloc_size() gives you 232, and so on. By using * these sizes, it results in one less allocation, if you anyway don't know the * exact size in advance. */ +#define NM_UTILS_GET_NEXT_REALLOC_SIZE_32 ((gsize) 32) +#define NM_UTILS_GET_NEXT_REALLOC_SIZE_40 ((gsize) 40) #define NM_UTILS_GET_NEXT_REALLOC_SIZE_104 ((gsize) 104) #define NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 ((gsize) 1000) diff --git a/shared/nm-glib-aux/nm-str-buf.h b/shared/nm-glib-aux/nm-str-buf.h index 13af81c01d..61246969de 100644 --- a/shared/nm-glib-aux/nm-str-buf.h +++ b/shared/nm-glib-aux/nm-str-buf.h @@ -212,6 +212,16 @@ nm_str_buf_append_c4 (NMStrBuf *strbuf, } static inline void +nm_str_buf_append_c_hex (NMStrBuf *strbuf, + char ch, + gboolean upper_case) +{ + nm_str_buf_maybe_expand (strbuf, 3, FALSE); + strbuf->_priv_str[strbuf->_priv_len++] = nm_hexchar (((guchar) ch) >> 4, upper_case); + strbuf->_priv_str[strbuf->_priv_len++] = nm_hexchar ((guchar) ch, upper_case); +} + +static inline void nm_str_buf_append_len (NMStrBuf *strbuf, const char *str, gsize len) @@ -225,6 +235,25 @@ nm_str_buf_append_len (NMStrBuf *strbuf, } } +static inline char * +nm_str_buf_append_len0 (NMStrBuf *strbuf, + const char *str, + gsize len) +{ + _nm_str_buf_assert (strbuf); + + /* this is basically like nm_str_buf_append_len() and + * nm_str_buf_get_str() in one. */ + + nm_str_buf_maybe_expand (strbuf, len + 1u, FALSE); + if (len > 0) { + memcpy (&strbuf->_priv_str[strbuf->_priv_len], str, len); + strbuf->_priv_len += len; + } + strbuf->_priv_str[strbuf->_priv_len] = '\0'; + return strbuf->_priv_str; +} + static inline void nm_str_buf_append (NMStrBuf *strbuf, const char *str) @@ -234,6 +263,15 @@ nm_str_buf_append (NMStrBuf *strbuf, nm_str_buf_append_len (strbuf, str, strlen (str)); } +static inline char * +nm_str_buf_append0 (NMStrBuf *strbuf, + const char *str) +{ + nm_assert (str); + + return nm_str_buf_append_len0 (strbuf, str, strlen (str)); +} + void nm_str_buf_append_printf (NMStrBuf *strbuf, const char *format, ...) _nm_printf (2, 3); @@ -248,6 +286,65 @@ nm_str_buf_ensure_trailing_c (NMStrBuf *strbuf, char ch) nm_str_buf_append_c (strbuf, ch); } +static inline NMStrBuf * +nm_str_buf_append_required_delimiter (NMStrBuf *strbuf, + char delimiter) +{ + _nm_str_buf_assert (strbuf); + + /* appends the @delimiter if it is required (that is, if the + * string is not empty). */ + if (strbuf->len > 0) + nm_str_buf_append_c (strbuf, delimiter); + return strbuf; +} + +static inline void +nm_str_buf_reset (NMStrBuf *strbuf, + const char *str) +{ + _nm_str_buf_assert (strbuf); + + if (strbuf->_priv_len > 0) { + if (strbuf->_priv_do_bzero_mem) { + /* we only clear the memory that we wrote to. */ + nm_explicit_bzero (strbuf->_priv_str, strbuf->_priv_len); + } + strbuf->_priv_len = 0; + } + + if (str) + nm_str_buf_append (strbuf, str); +} + +/*****************************************************************************/ + +/* Calls nm_utils_escaped_tokens_escape() on @str and appends the + * result to @strbuf. */ +static inline void +nm_utils_escaped_tokens_escape_strbuf (const char *str, + const char *delimiters, + NMStrBuf *strbuf) +{ + gs_free char *str_to_free = NULL; + + nm_assert (str); + + nm_str_buf_append (strbuf, + nm_utils_escaped_tokens_escape (str, delimiters, &str_to_free)); +} + +/* Calls nm_utils_escaped_tokens_escape_unnecessary() on @str and appends the + * string to @strbuf. */ +static inline void +nm_utils_escaped_tokens_escape_strbuf_assert (const char *str, + const char *delimiters, + NMStrBuf *strbuf) +{ + nm_str_buf_append (strbuf, + nm_utils_escaped_tokens_escape_unnecessary (str, delimiters)); +} + /*****************************************************************************/ static inline gboolean @@ -281,7 +378,7 @@ nm_str_buf_is_initalized (NMStrBuf *strbuf) * NUL character is always present after "strbuf->len" characters. * If currently no buffer is allocated, this will return %NULL. */ -static inline const char * +static inline char * nm_str_buf_get_str (NMStrBuf *strbuf) { _nm_str_buf_assert (strbuf); diff --git a/shared/nm-glib-aux/tests/test-shared-general.c b/shared/nm-glib-aux/tests/test-shared-general.c index 5c8bdf18e8..a435e28195 100644 --- a/shared/nm-glib-aux/tests/test-shared-general.c +++ b/shared/nm-glib-aux/tests/test-shared-general.c @@ -636,6 +636,8 @@ test_nm_utils_get_next_realloc_size (void) { G_MAXSIZE - 24u, G_MAXSIZE, G_MAXSIZE }, { G_MAXSIZE - 1u, G_MAXSIZE, G_MAXSIZE }, { G_MAXSIZE, G_MAXSIZE, G_MAXSIZE }, + { NM_UTILS_GET_NEXT_REALLOC_SIZE_32, NM_UTILS_GET_NEXT_REALLOC_SIZE_32, NM_UTILS_GET_NEXT_REALLOC_SIZE_32 }, + { NM_UTILS_GET_NEXT_REALLOC_SIZE_40, NM_UTILS_GET_NEXT_REALLOC_SIZE_40, NM_UTILS_GET_NEXT_REALLOC_SIZE_40 }, { NM_UTILS_GET_NEXT_REALLOC_SIZE_104, NM_UTILS_GET_NEXT_REALLOC_SIZE_104, NM_UTILS_GET_NEXT_REALLOC_SIZE_104 }, { NM_UTILS_GET_NEXT_REALLOC_SIZE_1000, NM_UTILS_GET_NEXT_REALLOC_SIZE_1000, NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 }, }; diff --git a/src/supplicant/nm-supplicant-config.c b/src/supplicant/nm-supplicant-config.c index 058792d026..1e09697721 100644 --- a/src/supplicant/nm-supplicant-config.c +++ b/src/supplicant/nm-supplicant-config.c @@ -10,8 +10,8 @@ #include <stdlib.h> +#include "nm-glib-aux/nm-str-buf.h" #include "nm-core-internal.h" - #include "nm-supplicant-settings-verify.h" #include "nm-setting.h" #include "nm-libnm-core-intern/nm-auth-subject.h" @@ -342,26 +342,39 @@ wifi_freqs_to_string (gboolean bg_band) { static const char *str_2ghz = NULL; static const char *str_5ghz = NULL; - const char *str; + const char **f_p; + const char *f; + + f_p = bg_band + ? &str_2ghz + : &str_5ghz; - str = bg_band ? str_2ghz : str_5ghz; +again: + f = g_atomic_pointer_get (f_p); - if (G_UNLIKELY (str == NULL)) { - GString *tmp; + if (G_UNLIKELY (!f)) { + nm_auto_str_buf NMStrBuf strbuf = NM_STR_BUF_INIT (400, FALSE); const guint *freqs; int i; - freqs = bg_band ? nm_utils_wifi_2ghz_freqs () : nm_utils_wifi_5ghz_freqs (); - tmp = g_string_sized_new (bg_band ? 70 : 225); - for (i = 0; freqs[i]; i++) - g_string_append_printf (tmp, i == 0 ? "%d" : " %d", freqs[i]); - str = g_string_free (tmp, FALSE); - if (bg_band) - str_2ghz = str; - else - str_5ghz = str; + freqs = bg_band + ? nm_utils_wifi_2ghz_freqs () + : nm_utils_wifi_5ghz_freqs (); + for (i = 0; freqs[i]; i++) { + if (i > 0) + nm_str_buf_append_c (&strbuf, ' '); + nm_str_buf_append_printf (&strbuf, "%u", freqs[i]); + } + + f = g_strdup (nm_str_buf_get_str (&strbuf)); + + if (!g_atomic_pointer_compare_and_exchange (f_p, NULL, f)) { + g_free ((char *) f); + goto again; + } } - return str; + + return f; } gboolean @@ -464,9 +477,9 @@ nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self, priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); mode = nm_setting_wireless_get_mode (setting); - is_adhoc = (mode && !strcmp (mode, "adhoc")) ? TRUE : FALSE; - is_ap = (mode && !strcmp (mode, "ap")) ? TRUE : FALSE; - is_mesh = (mode && !strcmp (mode, "mesh")) ? TRUE : FALSE; + is_adhoc = nm_streq0 (mode, "adhoc"); + is_ap = nm_streq0 (mode, "ap"); + is_mesh = nm_streq0 (mode, "mesh"); if (is_adhoc || is_ap) priv->ap_scan = 2; else @@ -540,9 +553,9 @@ nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self, } else { const char *freqs = NULL; - if (!strcmp (band, "a")) + if (nm_streq (band, "a")) freqs = wifi_freqs_to_string (FALSE); - else if (!strcmp (band, "bg")) + else if (nm_streq (band, "bg")) freqs = wifi_freqs_to_string (TRUE); if (freqs && !nm_supplicant_config_add_option (self, "freq_list", freqs, strlen (freqs), NULL, error)) @@ -888,10 +901,10 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, } /* Only WPA-specific things when using WPA */ - if ( !strcmp (key_mgmt, "wpa-psk") - || !strcmp (key_mgmt, "wpa-eap") - || !strcmp (key_mgmt, "sae") - || !strcmp (key_mgmt, "owe")) { + if (NM_IN_STRSET (key_mgmt, "wpa-psk", + "wpa-eap", + "sae", + "owe")) { if (!ADD_STRING_LIST_VAL (self, setting, wireless_security, proto, protos, "proto", ' ', TRUE, NULL, error)) return FALSE; if (!ADD_STRING_LIST_VAL (self, setting, wireless_security, pairwise, pairwise, "pairwise", ' ', TRUE, NULL, error)) @@ -914,7 +927,7 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, } /* WEP keys if required */ - if (!strcmp (key_mgmt, "none")) { + if (nm_streq (key_mgmt, "none")) { NMWepKeyType wep_type = nm_setting_wireless_security_get_wep_key_type (setting); const char *wep0 = nm_setting_wireless_security_get_wep_key (setting, 0); const char *wep1 = nm_setting_wireless_security_get_wep_key (setting, 1); @@ -939,9 +952,9 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, } } - if (auth_alg && !strcmp (auth_alg, "leap")) { + if (nm_streq0 (auth_alg, "leap")) { /* LEAP */ - if (!strcmp (key_mgmt, "ieee8021x")) { + if (nm_streq (key_mgmt, "ieee8021x")) { const char *tmp; tmp = nm_setting_wireless_security_get_leap_username (setting); @@ -961,7 +974,8 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, } } else { /* 802.1x for Dynamic WEP and WPA-Enterprise */ - if (!strcmp (key_mgmt, "ieee8021x") || !strcmp (key_mgmt, "wpa-eap")) { + if (NM_IN_STRSET (key_mgmt, "ieee8021x", + "wpa-eap")) { if (!setting_8021x) { g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG, "Cannot set key-mgmt %s with missing 8021x setting", key_mgmt); @@ -971,7 +985,7 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, return FALSE; } - if (!strcmp (key_mgmt, "wpa-eap")) { + if (nm_streq (key_mgmt, "wpa-eap")) { /* When using WPA-Enterprise, we want to use Proactive Key Caching (also * called Opportunistic Key Caching) to avoid full EAP exchanges when * roaming between access points in the same mobility group. @@ -1135,9 +1149,9 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, phase1 = g_string_new (NULL); peapver = nm_setting_802_1x_get_phase1_peapver (setting); if (peapver) { - if (!strcmp (peapver, "0")) + if (nm_streq (peapver, "0")) g_string_append (phase1, "peapver=0"); - else if (!strcmp (peapver, "1")) + else if (nm_streq (peapver, "1")) g_string_append (phase1, "peapver=1"); } @@ -1153,7 +1167,7 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, g_string_append_c (phase1, ' '); g_string_append_printf (phase1, "fast_provisioning=%s", value); - if (strcmp (value, "0") != 0) + if (!nm_streq (value, "0")) fast_provisoning_allowed = TRUE; } |