From c331e4a9b5c305d963e80101c99dcabd49265f4a Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 29 Apr 2022 19:01:22 +0200 Subject: [PATCH 1/3] glib-aux: add support for starting with stack-allocated buffer in NMStrBuf Allow to initialize NMStrBuf with an externally allocated array. Usually a stack buffer. If the NMStrBuf grows beyond the size of that initial buffer, then it would switch using malloc. The idea is to support the common case where the result is small enough to fit on the stack. I always wanted to do such optimization because the main purpose of NMStrBuf is to put it on the stack and ad-hoc construct a string. I just figured, it would complicate the implementation and add a runtime overhead. But turns out, it doesn't really. The biggest question is how NMStrBuf should behave with a pre-allocated buffer? Turns out, most choices can be made in a rather obvious way. The only non-obvious thing is that nm_str_buf_finalize() would malloc() a buffer, but that too seems consistent and what a user would probably expect. As such, this doesn't seem to add unexpected semantics to the API. (cherry picked from commit 13d25f9d0b2fbd9283acb8f4a72c2790e14f88c3) (cherry picked from commit 51393413b45b767e9a9f4bff956d0a06e59747d8) --- src/libnm-glib-aux/nm-shared-utils.c | 20 ++++-- src/libnm-glib-aux/nm-str-buf.h | 69 ++++++++++++++++--- .../tests/test-shared-general.c | 59 ++++++++++++---- 3 files changed, 120 insertions(+), 28 deletions(-) diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c index 2d21113345..c166eca347 100644 --- a/src/libnm-glib-aux/nm-shared-utils.c +++ b/src/libnm-glib-aux/nm-shared-utils.c @@ -5808,10 +5808,22 @@ _nm_str_buf_ensure_size(NMStrBuf *strbuf, gsize new_size, gboolean reserve_exact new_size = nm_utils_get_next_realloc_size(!strbuf->_priv_do_bzero_mem, new_size); } - strbuf->_priv_str = nm_secret_mem_realloc(strbuf->_priv_str, - strbuf->_priv_do_bzero_mem, - strbuf->_priv_allocated, - new_size); + if (strbuf->_priv_malloced) { + strbuf->_priv_str = nm_secret_mem_realloc(strbuf->_priv_str, + strbuf->_priv_do_bzero_mem, + strbuf->_priv_allocated, + new_size); + } else { + char *old = strbuf->_priv_str; + + strbuf->_priv_str = g_malloc(new_size); + if (strbuf->_priv_len > 0) { + memcpy(strbuf->_priv_str, old, strbuf->_priv_len); + if (strbuf->_priv_do_bzero_mem) + nm_explicit_bzero(old, strbuf->_priv_len); + } + strbuf->_priv_malloced = TRUE; + } strbuf->_priv_allocated = new_size; } diff --git a/src/libnm-glib-aux/nm-str-buf.h b/src/libnm-glib-aux/nm-str-buf.h index d7a2b3557f..80cb310f07 100644 --- a/src/libnm-glib-aux/nm-str-buf.h +++ b/src/libnm-glib-aux/nm-str-buf.h @@ -26,6 +26,7 @@ typedef struct _NMStrBuf { }; bool _priv_do_bzero_mem; + bool _priv_malloced; } NMStrBuf; /*****************************************************************************/ @@ -36,21 +37,56 @@ _nm_str_buf_assert(const NMStrBuf *strbuf) nm_assert(strbuf); nm_assert((!!strbuf->_priv_str) == (strbuf->_priv_allocated > 0)); nm_assert(strbuf->_priv_len <= strbuf->_priv_allocated); + nm_assert(!strbuf->_priv_malloced || strbuf->_priv_str); +} + +static inline NMStrBuf +NM_STR_BUF_INIT_FULL(char *str, + gsize len, + gsize allocated, + gboolean malloced, + gboolean do_bzero_mem) +{ + NMStrBuf strbuf = { + ._priv_str = allocated > 0 ? str : NULL, + ._priv_allocated = allocated, + ._priv_len = len, + ._priv_do_bzero_mem = do_bzero_mem, + ._priv_malloced = allocated > 0 && malloced, + }; + + _nm_str_buf_assert(&strbuf); + + return strbuf; } static inline NMStrBuf NM_STR_BUF_INIT(gsize allocated, gboolean do_bzero_mem) { - NMStrBuf strbuf = { - ._priv_str = allocated ? g_malloc(allocated) : NULL, - ._priv_allocated = allocated, - ._priv_len = 0, - ._priv_do_bzero_mem = do_bzero_mem, - }; - - return strbuf; + return NM_STR_BUF_INIT_FULL(allocated > 0 ? g_malloc(allocated) : NULL, + 0, + allocated, + allocated > 0, + do_bzero_mem); } +#define NM_STR_BUF_INIT_A(size, do_bzero_mem) \ + NM_STR_BUF_INIT_FULL( \ + g_alloca(size), \ + 0, \ + NM_STATIC_ASSERT_EXPR_1((size) > 0 && (size) <= NM_UTILS_GET_NEXT_REALLOC_SIZE_488) \ + ? (size) \ + : 0, \ + FALSE, \ + (do_bzero_mem)); + +#define NM_STR_BUF_INIT_ARR(arr, do_bzero_mem) \ + NM_STR_BUF_INIT_FULL((arr), \ + 0, \ + NM_STATIC_ASSERT_EXPR_1(sizeof(arr) > sizeof(char *)) ? sizeof(arr) : 0, \ + FALSE, \ + (do_bzero_mem)); + static inline void nm_str_buf_init(NMStrBuf *strbuf, gsize len, bool do_bzero_mem) { @@ -465,7 +501,9 @@ nm_str_buf_get_char(const NMStrBuf *strbuf, gsize index) * is afterwards in undefined state, though it can be * reused after nm_str_buf_init(). * Note that if no string is allocated yet (after nm_str_buf_init() with - * length zero), this will return %NULL. */ + * length zero), this will return %NULL. + * + * If the buffer was not malloced before, it will be malloced now. */ static inline char * nm_str_buf_finalize(NMStrBuf *strbuf, gsize *out_len) { @@ -476,6 +514,16 @@ nm_str_buf_finalize(NMStrBuf *strbuf, gsize *out_len) if (!strbuf->_priv_str) return NULL; + if (!strbuf->_priv_malloced) { + char *str = g_steal_pointer(&strbuf->_priv_str); + char *result; + + result = g_strndup(str, strbuf->_priv_len); + if (strbuf->_priv_do_bzero_mem) + nm_explicit_bzero(str, strbuf->_priv_len); + return result; + } + nm_str_buf_maybe_expand(strbuf, 1, TRUE); strbuf->_priv_str[strbuf->_priv_len] = '\0'; @@ -517,7 +565,8 @@ nm_str_buf_destroy(NMStrBuf *strbuf) _nm_str_buf_assert(strbuf); if (strbuf->_priv_do_bzero_mem) nm_explicit_bzero(strbuf->_priv_str, strbuf->_priv_len); - g_free(strbuf->_priv_str); + if (strbuf->_priv_malloced) + g_free(strbuf->_priv_str); /* the buffer is in invalid state afterwards, however, we clear it * so far, that nm_auto_str_buf is happy when calling diff --git a/src/libnm-glib-aux/tests/test-shared-general.c b/src/libnm-glib-aux/tests/test-shared-general.c index 1fc9b6f0c9..a6c0c5ce56 100644 --- a/src/libnm-glib-aux/tests/test-shared-general.c +++ b/src/libnm-glib-aux/tests/test-shared-general.c @@ -916,27 +916,58 @@ test_nm_str_buf(void) { guint i_run; - for (i_run = 0; TRUE; i_run++) { - nm_auto_str_buf NMStrBuf strbuf = {}; - nm_auto_free_gstring GString *gstr = NULL; + for (i_run = 0; i_run < 1000; i_run++) { + char stack_buf[1024]; + nm_auto_str_buf NMStrBuf strbuf; + nm_auto_free_gstring GString *gstr = NULL; int i, j, k; int c; - nm_str_buf_init(&strbuf, nmtst_get_rand_uint32() % 200u + 1u, nmtst_get_rand_bool()); + switch (nmtst_get_rand_uint32() % 10) { + case 0: + memset(&strbuf, 0, sizeof(strbuf)); + break; + case 1 ... 4: + strbuf = NM_STR_BUF_INIT_FULL(stack_buf, + 0, + nmtst_get_rand_uint32() % sizeof(stack_buf), + FALSE, + nmtst_get_rand_bool()); + break; + default: + nm_str_buf_init(&strbuf, nmtst_get_rand_uint32() % 200u + 1u, nmtst_get_rand_bool()); + break; + } - if (i_run < 1000) { - c = nmtst_get_rand_word_length(NULL); - for (i = 0; i < c; i++) - nm_str_buf_append_c(&strbuf, '0' + (i % 10)); - gstr = g_string_new(nm_str_buf_get_str(&strbuf)); - j = nmtst_get_rand_uint32() % (strbuf.len + 1); - k = nmtst_get_rand_uint32() % (strbuf.len - j + 2) - 1; + c = nmtst_get_rand_word_length(NULL); + for (i = 0; i < c; i++) + nm_str_buf_append_c(&strbuf, '0' + (i % 10)); + gstr = g_string_new(nm_str_buf_get_str(&strbuf)); + j = nmtst_get_rand_uint32() % (strbuf.len + 1); + k = nmtst_get_rand_uint32() % (strbuf.len - j + 2) - 1; - nm_str_buf_erase(&strbuf, j, k, nmtst_get_rand_bool()); - g_string_erase(gstr, j, k); + nm_str_buf_erase(&strbuf, j, k, nmtst_get_rand_bool()); + g_string_erase(gstr, j, k); + if (gstr->str[0]) g_assert_cmpstr(gstr->str, ==, nm_str_buf_get_str(&strbuf)); + else + g_assert(NM_IN_STRSET(nm_str_buf_get_str(&strbuf), NULL, "")); + } + + for (i_run = 0; i_run < 50; i_run++) { + char stack_buf[20]; + nm_auto_str_buf NMStrBuf strbuf = NM_STR_BUF_INIT_ARR(stack_buf, nmtst_get_rand_bool()); + + nm_str_buf_append_c_len(&strbuf, 'a', nmtst_get_rand_uint32() % (sizeof(stack_buf) * 2)); + if (strbuf.len <= sizeof(stack_buf)) { + g_assert(stack_buf == nm_str_buf_get_str_unsafe(&strbuf)); } else - return; + g_assert(stack_buf != nm_str_buf_get_str_unsafe(&strbuf)); + + if (strbuf.len < sizeof(stack_buf)) { + g_assert(stack_buf == nm_str_buf_get_str(&strbuf)); + } else + g_assert(stack_buf != nm_str_buf_get_str(&strbuf)); } } From e7acc59e848348cf1643399a6f7c05b15489ed98 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 29 Apr 2022 21:57:39 +0200 Subject: [PATCH 2/3] glib-aux: drop nm_str_buf_init() for NM_STR_BUF_INIT() NM_STR_BUF_INIT() and nm_str_buf_init() were pretty much redundant. Drop one of them. Usually our pattern is that we don't have functions that return structs. But NM_STR_BUF_INIT() returns a struct, because it's convenient to use with nm_auto_str_buf NMStrBuf strbuf = NM_STR_BUF_INIT(...); So use that variant instead. (cherry picked from commit 532f3e34a86667cc7e6e7c773484e4050df9f3e1) (cherry picked from commit 90255a8aa89d4022040982121289cfd045499da9) --- src/core/devices/ovs/nm-ovsdb.c | 2 +- src/core/nm-core-utils.c | 4 ++-- src/libnm-core-impl/nm-keyfile-utils.c | 6 +++--- src/libnm-core-impl/nm-keyfile.c | 2 +- src/libnm-core-impl/nm-setting-bridge.c | 2 +- src/libnm-core-impl/nm-setting-ip-config.c | 2 +- src/libnm-glib-aux/nm-enum-utils.c | 2 +- src/libnm-glib-aux/nm-shared-utils.c | 4 ++-- src/libnm-glib-aux/nm-str-buf.h | 14 +++----------- src/libnm-glib-aux/tests/test-shared-general.c | 2 +- src/libnm-log-core/nm-logging.c | 2 +- src/libnm-std-aux/nm-std-utils.h | 4 ++-- src/libnmc-base/nm-polkit-listener.c | 5 ++--- 13 files changed, 21 insertions(+), 30 deletions(-) diff --git a/src/core/devices/ovs/nm-ovsdb.c b/src/core/devices/ovs/nm-ovsdb.c index 34ce9f0c48..4af5e7cc69 100644 --- a/src/core/devices/ovs/nm-ovsdb.c +++ b/src/core/devices/ovs/nm-ovsdb.c @@ -1545,7 +1545,7 @@ _external_ids_to_string(const GArray *arr) if (!arr) return g_strdup("empty"); - nm_str_buf_init(&strbuf, NM_UTILS_GET_NEXT_REALLOC_SIZE_104, FALSE); + strbuf = NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_104, FALSE); nm_str_buf_append(&strbuf, "["); for (i = 0; i < arr->len; i++) { const NMUtilsNamedValue *n = &g_array_index(arr, NMUtilsNamedValue, i); diff --git a/src/core/nm-core-utils.c b/src/core/nm-core-utils.c index e05638e43c..f95469a674 100644 --- a/src/core/nm-core-utils.c +++ b/src/core/nm-core-utils.c @@ -5101,7 +5101,7 @@ nm_utils_spawn_helper(const char *const *args, fcntl(info->child_stdout, F_SETFL, fd_flags | O_NONBLOCK); /* Watch process stdin */ - nm_str_buf_init(&info->out_buffer, 32, TRUE); + info->out_buffer = NM_STR_BUF_INIT(32, TRUE); for (arg = args; *arg; arg++) { nm_str_buf_append(&info->out_buffer, *arg); nm_str_buf_append_c(&info->out_buffer, '\0'); @@ -5115,7 +5115,7 @@ nm_utils_spawn_helper(const char *const *args, g_source_attach(info->output_source, g_main_context_get_thread_default()); /* Watch process stdout */ - nm_str_buf_init(&info->in_buffer, NM_UTILS_GET_NEXT_REALLOC_SIZE_1000, FALSE); + info->in_buffer = NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_1000, FALSE); info->input_source = nm_g_unix_fd_source_new(info->child_stdout, G_IO_IN | G_IO_ERR | G_IO_HUP, G_PRIORITY_DEFAULT, diff --git a/src/libnm-core-impl/nm-keyfile-utils.c b/src/libnm-core-impl/nm-keyfile-utils.c index c599aefa7b..95073bcc93 100644 --- a/src/libnm-core-impl/nm-keyfile-utils.c +++ b/src/libnm-core-impl/nm-keyfile-utils.c @@ -210,7 +210,7 @@ nm_keyfile_plugin_kf_set_integer_list_uint(GKeyFile *kf, g_return_if_fail(group && group[0]); g_return_if_fail(key && key[0]); - nm_str_buf_init(&strbuf, length * 4u + 2u, FALSE); + strbuf = NM_STR_BUF_INIT(length * 4u + 2u, FALSE); for (i = 0; i < length; i++) nm_str_buf_append_printf(&strbuf, "%u;", data[i]); nm_keyfile_plugin_kf_set_value(kf, group, key, nm_str_buf_get_str(&strbuf)); @@ -231,7 +231,7 @@ nm_keyfile_plugin_kf_set_integer_list_uint8(GKeyFile *kf, g_return_if_fail(group && group[0]); g_return_if_fail(key && key[0]); - nm_str_buf_init(&strbuf, length * 4u + 2u, FALSE); + strbuf = NM_STR_BUF_INIT(length * 4u + 2u, FALSE); for (i = 0; i < length; i++) nm_str_buf_append_printf(&strbuf, "%u;", (guint) data[i]); nm_keyfile_plugin_kf_set_value(kf, group, key, nm_str_buf_get_str(&strbuf)); @@ -542,7 +542,7 @@ _keyfile_key_encode(const char *name, char **out_to_free) len = i + strlen(&name[i]); nm_assert(len == strlen(name)); - nm_str_buf_init(&str, len + 15u, FALSE); + str = NM_STR_BUF_INIT(len + 15u, FALSE); if (name[0] == ' ') { nm_assert(i == 0); diff --git a/src/libnm-core-impl/nm-keyfile.c b/src/libnm-core-impl/nm-keyfile.c index dce53ae27e..f0a3933296 100644 --- a/src/libnm-core-impl/nm-keyfile.c +++ b/src/libnm-core-impl/nm-keyfile.c @@ -4332,7 +4332,7 @@ nm_keyfile_utils_create_filename(const char *name, gboolean with_extension) g_return_val_if_fail(name && name[0], NULL); - nm_str_buf_init(&str, 0, FALSE); + str = NM_STR_BUF_INIT(0, FALSE); len = strlen(name); diff --git a/src/libnm-core-impl/nm-setting-bridge.c b/src/libnm-core-impl/nm-setting-bridge.c index 41cd6632f2..fab6e4762e 100644 --- a/src/libnm-core-impl/nm-setting-bridge.c +++ b/src/libnm-core-impl/nm-setting-bridge.c @@ -435,7 +435,7 @@ nm_bridge_vlan_to_str(const NMBridgeVlan *vlan, GError **error) * future if more parameters are added to the object that could * make it invalid. */ - nm_str_buf_init(&string, NM_UTILS_GET_NEXT_REALLOC_SIZE_32, FALSE); + string = NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_32, FALSE); if (vlan->vid_start == vlan->vid_end) nm_str_buf_append_printf(&string, "%u", vlan->vid_start); diff --git a/src/libnm-core-impl/nm-setting-ip-config.c b/src/libnm-core-impl/nm-setting-ip-config.c index 52aa651570..ba89d42709 100644 --- a/src/libnm-core-impl/nm-setting-ip-config.c +++ b/src/libnm-core-impl/nm-setting-ip-config.c @@ -3812,7 +3812,7 @@ nm_ip_routing_rule_to_string(const NMIPRoutingRule *self, } } - nm_str_buf_init(&str, NM_UTILS_GET_NEXT_REALLOC_SIZE_32, FALSE); + str = NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_32, FALSE); if (self->priority_has) { nm_str_buf_append_printf(nm_str_buf_append_required_delimiter(&str, ' '), diff --git a/src/libnm-glib-aux/nm-enum-utils.c b/src/libnm-glib-aux/nm-enum-utils.c index 3b9b7e8d13..b7f7a3f6cc 100644 --- a/src/libnm-glib-aux/nm-enum-utils.c +++ b/src/libnm-glib-aux/nm-enum-utils.c @@ -142,7 +142,7 @@ _nm_utils_enum_to_str_full(GType type, flags_separator = flags_separator ?: " "; - nm_str_buf_init(&strbuf, 16, FALSE); + strbuf = NM_STR_BUF_INIT(16, FALSE); for (; value_infos && value_infos->nick; value_infos++) { nm_assert(_enum_is_valid_flags_nick(value_infos->nick)); diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c index c166eca347..17827b9422 100644 --- a/src/libnm-glib-aux/nm-shared-utils.c +++ b/src/libnm-glib-aux/nm-shared-utils.c @@ -2996,7 +2996,7 @@ nm_utils_buf_utf8safe_unescape(const char *str, return str; } - nm_str_buf_init(&strbuf, len + 1u, FALSE); + strbuf = NM_STR_BUF_INIT(len + 1u, FALSE); nm_str_buf_append_len(&strbuf, str, s - str); str = s; @@ -3160,7 +3160,7 @@ nm_utils_buf_utf8safe_escape(gconstpointer buf, return str; } - nm_str_buf_init(&strbuf, buflen + 5, NM_FLAGS_HAS(flags, NM_UTILS_STR_UTF8_SAFE_FLAG_SECRET)); + strbuf = NM_STR_BUF_INIT(buflen + 5, NM_FLAGS_HAS(flags, NM_UTILS_STR_UTF8_SAFE_FLAG_SECRET)); s = str; do { diff --git a/src/libnm-glib-aux/nm-str-buf.h b/src/libnm-glib-aux/nm-str-buf.h index 80cb310f07..57c5e2c792 100644 --- a/src/libnm-glib-aux/nm-str-buf.h +++ b/src/libnm-glib-aux/nm-str-buf.h @@ -87,14 +87,6 @@ NM_STR_BUF_INIT(gsize allocated, gboolean do_bzero_mem) FALSE, \ (do_bzero_mem)); -static inline void -nm_str_buf_init(NMStrBuf *strbuf, gsize len, bool do_bzero_mem) -{ - nm_assert(strbuf); - *strbuf = NM_STR_BUF_INIT(len, do_bzero_mem); - _nm_str_buf_assert(strbuf); -} - void _nm_str_buf_ensure_size(NMStrBuf *strbuf, gsize new_size, gboolean reserve_exact); static inline void @@ -499,8 +491,8 @@ nm_str_buf_get_char(const NMStrBuf *strbuf, gsize index) * Returns: (transfer full): the string of the buffer * which must be freed by the caller. The @strbuf * is afterwards in undefined state, though it can be - * reused after nm_str_buf_init(). - * Note that if no string is allocated yet (after nm_str_buf_init() with + * reused after resetting with NM_STR_BUF_INIT(). + * Note that if no string is allocated yet (after NM_STR_BUF_INIT() with * length zero), this will return %NULL. * * If the buffer was not malloced before, it will be malloced now. */ @@ -555,7 +547,7 @@ nm_str_buf_finalize_to_gbytes(NMStrBuf *strbuf) * * Frees the associated memory of @strbuf. The buffer * afterwards is in undefined state, but can be re-initialized - * with nm_str_buf_init(). + * with NM_STR_BUF_INIT(). */ static inline void nm_str_buf_destroy(NMStrBuf *strbuf) diff --git a/src/libnm-glib-aux/tests/test-shared-general.c b/src/libnm-glib-aux/tests/test-shared-general.c index a6c0c5ce56..21df3ddca1 100644 --- a/src/libnm-glib-aux/tests/test-shared-general.c +++ b/src/libnm-glib-aux/tests/test-shared-general.c @@ -935,7 +935,7 @@ test_nm_str_buf(void) nmtst_get_rand_bool()); break; default: - nm_str_buf_init(&strbuf, nmtst_get_rand_uint32() % 200u + 1u, nmtst_get_rand_bool()); + strbuf = NM_STR_BUF_INIT(nmtst_get_rand_uint32() % 200u + 1u, nmtst_get_rand_bool()); break; } diff --git a/src/libnm-log-core/nm-logging.c b/src/libnm-log-core/nm-logging.c index f464ef296d..5cce508daf 100644 --- a/src/libnm-log-core/nm-logging.c +++ b/src/libnm-log-core/nm-logging.c @@ -468,7 +468,7 @@ _domains_to_string(gboolean include_level_override, * nm_logging_setup(), because we want to expand "DEFAULT" and "ALL". */ - nm_str_buf_init(&sbuf, NM_UTILS_GET_NEXT_REALLOC_SIZE_40, FALSE); + sbuf = NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_40, FALSE); for (diter = &domain_desc[0]; diter->name; diter++) { /* If it's set for any lower level, it will also be set for LOGL_ERR */ diff --git a/src/libnm-std-aux/nm-std-utils.h b/src/libnm-std-aux/nm-std-utils.h index 0d864af9d9..6aa787eb6a 100644 --- a/src/libnm-std-aux/nm-std-utils.h +++ b/src/libnm-std-aux/nm-std-utils.h @@ -14,12 +14,12 @@ * certain buffer sizes. * * The use of these defines is to get favorable allocation sequences. - * For example, nm_str_buf_init() asks for an initial allocation size. Note that + * For example, NM_STR_BUF_INIT() asks for an initial allocation size. Note that * it reserves the exactly requested amount, under the assumption that the * user may know how many bytes will be required. However, often the caller * doesn't know in advance, and NMStrBuf grows exponentially by calling * nm_utils_get_next_realloc_size(). - * Imagine you call nm_str_buf_init() with an initial buffer size 100, and you + * Imagine you call NM_STR_BUF_INIT() with an initial buffer size 100, and you * add one character at a time. Then the first reallocation will increase the * buffer size only from 100 to 104. * If you however start with an initial buffer size of 104, then the next reallocation diff --git a/src/libnmc-base/nm-polkit-listener.c b/src/libnmc-base/nm-polkit-listener.c index 39a06bc6d4..e7972faa48 100644 --- a/src/libnmc-base/nm-polkit-listener.c +++ b/src/libnmc-base/nm-polkit-listener.c @@ -393,7 +393,7 @@ queue_string_to_helper(AuthRequest *request, const char *response) g_return_if_fail(response); if (!nm_str_buf_is_initalized(&request->out_buffer)) - nm_str_buf_init(&request->out_buffer, strlen(response) + 2u, TRUE); + request->out_buffer = NM_STR_BUF_INIT(strlen(response) + 2u, TRUE); nm_str_buf_append(&request->out_buffer, response); nm_str_buf_ensure_trailing_c(&request->out_buffer, '\n'); @@ -587,10 +587,9 @@ create_request(NMPolkitListener *listener, .cookie = g_strdup(cookie), .request_any_response = FALSE, .request_is_completed = FALSE, + .in_buffer = NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_1000, FALSE), }; - nm_str_buf_init(&request->in_buffer, NM_UTILS_GET_NEXT_REALLOC_SIZE_1000, FALSE); - c_list_link_tail(&listener->request_lst_head, &request->request_lst); return request; } From 84a0ba74698b239ba6b3384fa295c1393272444c Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 29 Apr 2022 22:00:17 +0200 Subject: [PATCH 3/3] glib-aux: avoid #if in "nm-str-buf.h" NM_MORE_ASSERT is a compile time constant. The compiler can optimize it away just fine. (cherry picked from commit 560feecb4c70f40367f18581c9734946de473e02) (cherry picked from commit de6da97e9d90158b37e122af0483be254a8c3606) --- src/libnm-glib-aux/nm-str-buf.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libnm-glib-aux/nm-str-buf.h b/src/libnm-glib-aux/nm-str-buf.h index 57c5e2c792..9a3c5baf42 100644 --- a/src/libnm-glib-aux/nm-str-buf.h +++ b/src/libnm-glib-aux/nm-str-buf.h @@ -387,10 +387,10 @@ static inline gboolean nm_str_buf_is_initalized(NMStrBuf *strbuf) { nm_assert(strbuf); -#if NM_MORE_ASSERTS - if (strbuf->_priv_str) - _nm_str_buf_assert(strbuf); -#endif + if (NM_MORE_ASSERTS > 0) { + if (strbuf->_priv_str) + _nm_str_buf_assert(strbuf); + } return !!strbuf->_priv_str; }