mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-28 19:10:09 +01:00
glib-aux: merge branch 'th/str-buf-stack-allocated'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1203
This commit is contained in:
commit
c6e41b2df3
13 changed files with 143 additions and 60 deletions
|
|
@ -1553,7 +1553,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);
|
||||
|
|
|
|||
|
|
@ -5113,7 +5113,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');
|
||||
|
|
@ -5127,7 +5127,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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -4374,7 +4374,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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -3814,7 +3814,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, ' '),
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -2998,7 +2998,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;
|
||||
|
|
@ -3165,7 +3165,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 {
|
||||
|
|
@ -5841,10 +5841,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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ typedef struct _NMStrBuf {
|
|||
};
|
||||
|
||||
bool _priv_do_bzero_mem;
|
||||
bool _priv_malloced;
|
||||
} NMStrBuf;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -36,28 +37,55 @@ _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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
#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));
|
||||
|
||||
void _nm_str_buf_ensure_size(NMStrBuf *strbuf, gsize new_size, gboolean reserve_exact);
|
||||
|
||||
|
|
@ -359,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;
|
||||
}
|
||||
|
||||
|
|
@ -463,9 +491,11 @@ 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
|
||||
* length zero), this will return %NULL. */
|
||||
* 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. */
|
||||
static inline char *
|
||||
nm_str_buf_finalize(NMStrBuf *strbuf, gsize *out_len)
|
||||
{
|
||||
|
|
@ -476,6 +506,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';
|
||||
|
||||
|
|
@ -507,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)
|
||||
|
|
@ -517,7 +557,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
|
||||
|
|
|
|||
|
|
@ -917,27 +917,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:
|
||||
strbuf = NM_STR_BUF_INIT(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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue