From 081650eb67cf85e741d8e30babb9b7884b4fd36f Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sun, 21 Jun 2020 22:40:17 +0200 Subject: [PATCH 01/20] shared: avoid copying empty string in nm_str_buf_append_printf() --- shared/nm-glib-aux/nm-shared-utils.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/shared/nm-glib-aux/nm-shared-utils.c b/shared/nm-glib-aux/nm-shared-utils.c index a2e90273c5..48635df343 100644 --- a/shared/nm-glib-aux/nm-shared-utils.c +++ b/shared/nm-glib-aux/nm-shared-utils.c @@ -4966,7 +4966,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); From de4df9f5297b6d20cec0a2044f2563dd3c98d149 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 26 Jun 2020 09:28:32 +0200 Subject: [PATCH 02/20] shared: return non-const pointer from nm_str_buf_get_str() It's more convenient in certain cases. The user is allowed to modified the content of the returned buffer. --- shared/nm-glib-aux/nm-str-buf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/nm-glib-aux/nm-str-buf.h b/shared/nm-glib-aux/nm-str-buf.h index 13af81c01d..da082abe67 100644 --- a/shared/nm-glib-aux/nm-str-buf.h +++ b/shared/nm-glib-aux/nm-str-buf.h @@ -281,7 +281,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); From 506f95ecaf45bf344034a16c3ab353885ed57763 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 20 Jun 2020 20:27:48 +0200 Subject: [PATCH 03/20] shared: add NM_UTILS_GET_NEXT_REALLOC_SIZE_32 and _40 macros --- shared/nm-glib-aux/nm-shared-utils.h | 2 ++ shared/nm-glib-aux/tests/test-shared-general.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/shared/nm-glib-aux/nm-shared-utils.h b/shared/nm-glib-aux/nm-shared-utils.h index 893ec11c0d..589275739c 100644 --- a/shared/nm-glib-aux/nm-shared-utils.h +++ b/shared/nm-glib-aux/nm-shared-utils.h @@ -1985,6 +1985,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/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 }, }; From d53abfd9898e33d375693837cc491168a986b450 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sun, 21 Jun 2020 11:25:33 +0200 Subject: [PATCH 04/20] shared: add nm_str_buf_append0() and nm_str_buf_append_len0() helper These are basically nm_str_buf_append()/nm_str_buf_append_len() and nm_str_buf_get_str() in one. --- shared/nm-glib-aux/nm-str-buf.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/shared/nm-glib-aux/nm-str-buf.h b/shared/nm-glib-aux/nm-str-buf.h index da082abe67..a2253ae89a 100644 --- a/shared/nm-glib-aux/nm-str-buf.h +++ b/shared/nm-glib-aux/nm-str-buf.h @@ -225,6 +225,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 +253,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); From 069be33fbdc0a6f925795b9ac7bdc7712b9799ba Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 20 Jun 2020 19:43:23 +0200 Subject: [PATCH 05/20] shared: add nm_hexchar() helper --- shared/nm-glib-aux/nm-shared-utils.c | 3 +++ shared/nm-glib-aux/nm-shared-utils.h | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/shared/nm-glib-aux/nm-shared-utils.c b/shared/nm-glib-aux/nm-shared-utils.c index 48635df343..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 }; /*****************************************************************************/ diff --git a/shared/nm-glib-aux/nm-shared-utils.h b/shared/nm-glib-aux/nm-shared-utils.h index 589275739c..43b8288b0a 100644 --- a/shared/nm-glib-aux/nm-shared-utils.h +++ b/shared/nm-glib-aux/nm-shared-utils.h @@ -1809,6 +1809,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, From 85e27b1f9c8b6977d2dd23982e9a869f2996ee04 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 20 Jun 2020 19:43:56 +0200 Subject: [PATCH 06/20] shared: add nm_str_buf_append_c_hex() helper --- shared/nm-glib-aux/nm-str-buf.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/shared/nm-glib-aux/nm-str-buf.h b/shared/nm-glib-aux/nm-str-buf.h index a2253ae89a..a8cbc847e0 100644 --- a/shared/nm-glib-aux/nm-str-buf.h +++ b/shared/nm-glib-aux/nm-str-buf.h @@ -211,6 +211,16 @@ nm_str_buf_append_c4 (NMStrBuf *strbuf, strbuf->_priv_str[strbuf->_priv_len++] = ch3; } +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, From 5222f1b5ff0782248426b42d77996c9c7e226654 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sun, 21 Jun 2020 12:11:24 +0200 Subject: [PATCH 07/20] shared: add nm_str_buf_append_required_delimiter() --- shared/nm-glib-aux/nm-str-buf.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/shared/nm-glib-aux/nm-str-buf.h b/shared/nm-glib-aux/nm-str-buf.h index a8cbc847e0..e798e736a5 100644 --- a/shared/nm-glib-aux/nm-str-buf.h +++ b/shared/nm-glib-aux/nm-str-buf.h @@ -286,6 +286,19 @@ 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 gboolean From a5a56565822b892a83273b4444ff866c5cdea112 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 20 Jun 2020 20:17:25 +0200 Subject: [PATCH 08/20] shared: add nm_utils_escaped_tokens_escape_unnecessary() util --- shared/nm-glib-aux/nm-shared-utils.h | 39 +++++++++++++++++----------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/shared/nm-glib-aux/nm-shared-utils.h b/shared/nm-glib-aux/nm-shared-utils.h index 43b8288b0a..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 * From d83908b6a165b9674cfd379f47f8d8a50075ec84 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sun, 21 Jun 2020 12:14:43 +0200 Subject: [PATCH 09/20] shared: add nm_utils_escaped_tokens_escape_strbuf*() helpers --- shared/nm-glib-aux/nm-str-buf.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/shared/nm-glib-aux/nm-str-buf.h b/shared/nm-glib-aux/nm-str-buf.h index e798e736a5..3b472ca557 100644 --- a/shared/nm-glib-aux/nm-str-buf.h +++ b/shared/nm-glib-aux/nm-str-buf.h @@ -301,6 +301,34 @@ nm_str_buf_append_required_delimiter (NMStrBuf *strbuf, /*****************************************************************************/ +/* 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 nm_str_buf_is_initalized (NMStrBuf *strbuf) { From 45b346554a65258f4a26ebf8f9b3200514265270 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sun, 21 Jun 2020 13:32:47 +0200 Subject: [PATCH 10/20] shared: add nm_str_buf_reset() helper --- shared/nm-glib-aux/nm-str-buf.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/shared/nm-glib-aux/nm-str-buf.h b/shared/nm-glib-aux/nm-str-buf.h index 3b472ca557..61246969de 100644 --- a/shared/nm-glib-aux/nm-str-buf.h +++ b/shared/nm-glib-aux/nm-str-buf.h @@ -299,6 +299,24 @@ nm_str_buf_append_required_delimiter (NMStrBuf *strbuf, 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 From f7715c6680d3cae82812e26353208058f082c985 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 20 Jun 2020 20:32:48 +0200 Subject: [PATCH 11/20] libnm: use NMStrBuf in "nm-setting-bridge.c" --- libnm-core/nm-core-internal.h | 4 ---- libnm-core/nm-setting-bridge.c | 35 ++++++++++------------------------ 2 files changed, 10 insertions(+), 29 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-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 #include +#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); } /** From 3be4f38a159928ec9818ebe96b025ecb3b7a3700 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 20 Jun 2020 19:31:58 +0200 Subject: [PATCH 12/20] keyfile: cleanup uses of GString in keyfile code - in _keyfile_key_decode(), don't use GString. We know the maximum string length before, so we can just allocated one buffer. - in qdisc and tfilter writers, reuse the same GString instance. No need to allocate a new temporary string buffer for each iteration. - at other places, replace GString by NMStrBuf. This avoids the heap allocated GString instance. Also, most operations can be inlined. This results in larger code side, but avoids function calls to glib. --- libnm-core/nm-keyfile/nm-keyfile-utils.c | 44 ++-- libnm-core/nm-keyfile/nm-keyfile.c | 249 ++++++++++++----------- 2 files changed, 155 insertions(+), 138 deletions(-) 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 #include +#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 > 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; - if (!array->len) - return; + addr_family = nm_streq (setting_name, NM_SETTING_IP4_CONFIG_SETTING_NAME) + ? AF_INET + : AF_INET6; - 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); - 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; - 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 (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; - } - - 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 = "::"; + addr = nm_ip_address_get_address (address); + plen = nm_ip_address_get_prefix (address); + gw = (i == 0) + ? gateway + : NULL; } - g_string_append_printf (output, ",%s", gw); - if ( is_route - && metric != -1) - g_string_append_printf (output, ",%lu", (unsigned long) metric); - } + 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 = "::"; + } - sprintf (key_name_idx, "%u", i + 1); - nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, output->str); + 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); + } - if (is_route) { - gs_free char *attributes = NULL; + sprintf (key_name_idx, "%u", i + 1); + nm_keyfile_plugin_kf_set_string (file, + setting_name, + key_name, + nm_str_buf_get_str (&output)); - 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); + 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); + } } } } @@ -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; + 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; - string = g_string_new (""); - for (i = 0; i < vlans->len; i++) { - gs_free char *vlan_str = NULL; + for (i = 0; i < vlans->len; i++) { + gs_free char *vlan_str = NULL; - 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); + 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); + } + + nm_keyfile_plugin_kf_set_string (info->keyfile, + nm_setting_get_name (setting), + "vlans", + nm_str_buf_get_str (&string)); } - - nm_keyfile_plugin_kf_set_string (info->keyfile, - nm_setting_get_name (setting), - "vlans", - string->str); - - g_string_free (string, TRUE); } @@ -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; } /*****************************************************************************/ From 936e457cc08d387deba8670282145362716c2b55 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sun, 21 Jun 2020 12:11:38 +0200 Subject: [PATCH 13/20] libnm: use NMStrBuf in nm_ip_routing_rule_to_string() --- libnm-core/nm-setting-ip-config.c | 133 +++++++++++++++--------------- 1 file changed, 67 insertions(+), 66 deletions(-) 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 #include +#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); } /*****************************************************************************/ From 2edb3aa81aa7580fcd62d0ca542ce52ec0ed5304 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sun, 21 Jun 2020 13:17:04 +0200 Subject: [PATCH 14/20] libnm: use NMStrBuf in _nm_utils_uuid_generate_from_strings() --- libnm-core/nm-utils.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index c88afb3238..85effe21a8 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" @@ -3300,30 +3301,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 *); + while (s) { + nm_str_buf_append_len (&str, s, strlen (s) + 1u); + s = va_arg (args, const char *); + } + va_end (args); + + 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); } - va_end (args); - - uuid = nm_utils_uuid_generate_from_string (str->str, str->len, NM_UTILS_UUID_TYPE_VERSION3, NM_UTILS_UUID_NS); - - g_string_free (str, TRUE); - return uuid; } /*****************************************************************************/ From 6adf4b9a560be16bf7b8e7b5c0a7e6d767cbbb67 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sun, 21 Jun 2020 13:10:45 +0200 Subject: [PATCH 15/20] libnm: use NMStrBuf in nm_utils_file_search_in_paths() --- libnm-core/nm-utils.c | 46 +++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 85effe21a8..1c39d94e78 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -3571,9 +3571,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 +3579,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; } From 39454717529c018cea86557962ac10e224557ac5 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sun, 21 Jun 2020 21:48:59 +0200 Subject: [PATCH 16/20] libnm: use nm_streq() in "libnm-core/nm-utils.c" --- libnm-core/nm-utils.c | 66 ++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 1c39d94e78..39e9470bea 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -2068,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); } @@ -2194,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); } @@ -2377,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, ' '); @@ -2469,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) @@ -2525,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, @@ -2671,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; @@ -3750,11 +3751,11 @@ nm_utils_wifi_channel_to_freq (guint32 channel, const char *band) { int i = 0; - if (!strcmp (band, "a")) { + if (nm_streq (band, "a")) { while (a_table[i].chan && (a_table[i].chan != channel)) i++; return a_table[i].freq; - } else if (!strcmp (band, "bg")) { + } else if (nm_streq (band, "bg")) { while (bg_table[i].chan && (bg_table[i].chan != channel)) i++; return bg_table[i].freq; @@ -3776,17 +3777,17 @@ 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); + size_t a_size = G_N_ELEMENTS (a_table); + size_t bg_size = G_N_ELEMENTS (bg_table); struct cf_pair *pair = NULL; - 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) @@ -3826,9 +3827,9 @@ nm_utils_wifi_is_channel_valid (guint32 channel, const char *band) struct cf_pair *table = NULL; int i = 0; - if (!strcmp (band, "a")) + if (nm_streq (band, "a")) table = a_table; - else if (!strcmp (band, "bg")) + else if (nm_streq (band, "bg")) table = bg_table; else return FALSE; @@ -5080,8 +5081,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 +5140,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 +5197,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 +5287,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++) { - 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); - return i; - } - } + gs_free char *tmp_name = NULL; + if (_nm_utils_dns_option_validate (array->pdata[i], &tmp_name, NULL, FALSE, NULL)) { + if (nm_streq (tmp_name, option_name)) + return i; + } } - g_free (option_name); return -1; } From bd7d8b6f3d41247e1c5ec9ea0895b7d106a139b4 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 22 Jun 2020 09:21:06 +0200 Subject: [PATCH 17/20] libnm: don't use assert for validating arguments to nm_utils_wifi_find_next_channel() --- libnm-core/nm-utils.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 39e9470bea..d8713adb31 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -3793,10 +3793,8 @@ nm_utils_wifi_find_next_channel (guint32 channel, int direction, char *band) 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) From 5f202414d9bb42312c4f4875deb2628eadadf5be Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sun, 21 Jun 2020 21:59:32 +0200 Subject: [PATCH 18/20] libnm: refactor wifi frequency handling in libnm - mark global variables as const. This allows the linker to mark the variable as read only. - for nm_utils_wifi_[25]ghz_freqs(), don't generate a list based on bg_table/a_table. Instead, keep static array of frequencies. Since we have unit tests that check the consistency, this has little maintenance effort. - add unit tests --- libnm-core/nm-utils.c | 184 +++++++++++++++++++++----------- libnm-core/tests/test-general.c | 50 +++++++++ 2 files changed, 173 insertions(+), 61 deletions(-) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index d8713adb31..ca6b70ce20 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -3621,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 }, @@ -3668,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 }, @@ -3687,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, }; /** @@ -3704,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; } /** @@ -3749,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; + + g_return_val_if_fail (band, 0); if (nm_streq (band, "a")) { - while (a_table[i].chan && (a_table[i].chan != channel)) - i++; - return a_table[i].freq; - } else if (nm_streq (band, "bg")) { - while (bg_table[i].chan && (bg_table[i].chan != channel)) - i++; - return bg_table[i].freq; + 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; @@ -3779,7 +3856,7 @@ nm_utils_wifi_find_next_channel (guint32 channel, int direction, char *band) { size_t a_size = G_N_ELEMENTS (a_table); size_t bg_size = G_N_ELEMENTS (bg_table); - struct cf_pair *pair = NULL; + const struct cf_pair *pair; if (nm_streq (band, "a")) { if (channel < a_table[0].chan) @@ -3822,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; + guint32 freq; - if (nm_streq (band, "a")) - table = a_table; - else if (nm_streq (band, "bg")) - table = bg_table; - else - return FALSE; + freq = nm_utils_wifi_channel_to_freq (channel, band); - while (table[i].chan && (table[i].chan != channel)) - i++; - - if (table[i].chan != 0) - return TRUE; - else - return FALSE; + return !NM_IN_SET (freq, 0u, (guint32) -1); } -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; - - 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; -} +#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: @@ -3878,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; } /** @@ -3893,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; } /** @@ -5027,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" }, 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); From 652e0c843bfcdf3d59816d0b3c81d4f99a843c81 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sun, 21 Jun 2020 22:03:55 +0200 Subject: [PATCH 19/20] supplicant: use nm_streq() in "nm-supplicant-config.c" --- src/supplicant/nm-supplicant-config.c | 36 +++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/supplicant/nm-supplicant-config.c b/src/supplicant/nm-supplicant-config.c index 058792d026..62c6742458 100644 --- a/src/supplicant/nm-supplicant-config.c +++ b/src/supplicant/nm-supplicant-config.c @@ -11,7 +11,6 @@ #include #include "nm-core-internal.h" - #include "nm-supplicant-settings-verify.h" #include "nm-setting.h" #include "nm-libnm-core-intern/nm-auth-subject.h" @@ -464,9 +463,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 +539,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 +887,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 +913,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 +938,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 +960,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 +971,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 +1135,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 +1153,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; } From 3b4a4bef7b276cbd2ff587d6586ebbce456859eb Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sun, 21 Jun 2020 22:04:59 +0200 Subject: [PATCH 20/20] supplicant: use NMStrBuf in wifi_freqs_to_string() And don't access global data without atomic operations. --- src/supplicant/nm-supplicant-config.c | 42 ++++++++++++++++++--------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/supplicant/nm-supplicant-config.c b/src/supplicant/nm-supplicant-config.c index 62c6742458..1e09697721 100644 --- a/src/supplicant/nm-supplicant-config.c +++ b/src/supplicant/nm-supplicant-config.c @@ -10,6 +10,7 @@ #include +#include "nm-glib-aux/nm-str-buf.h" #include "nm-core-internal.h" #include "nm-supplicant-settings-verify.h" #include "nm-setting.h" @@ -341,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; - str = bg_band ? str_2ghz : str_5ghz; + f_p = bg_band + ? &str_2ghz + : &str_5ghz; - if (G_UNLIKELY (str == NULL)) { - GString *tmp; +again: + f = g_atomic_pointer_get (f_p); + + 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