From 5a3ffffe7453bf0fcde97e14f0cc7a2d85e8bce8 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 6 May 2019 10:04:16 +0200 Subject: [PATCH] auth-chain: don't copy ChainData tag All callers pass a C string literal as the user-data tag of NMAuthChain. It makes little sense otherwise because you usually know which user data you need in advance. So don't bother with copying the string. Just reference the defacto static string. Rename nm_auth_chain_set_data() to nm_auth_chain_set_data_unsafe() to indicate that the lifetime of the tag string is now the caller's responsibility. The nm_auth_chain_set_data() macro now ensures that the tag argument is a C string literal. In fact, all callers that we had did that already. --- src/nm-auth-utils.c | 52 ++++++++++++++++++++++----------------------- src/nm-auth-utils.h | 11 ++++++---- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/nm-auth-utils.c b/src/nm-auth-utils.c index 2e61ad2060..81ea66a2ab 100644 --- a/src/nm-auth-utils.c +++ b/src/nm-auth-utils.c @@ -115,37 +115,18 @@ _find_auth_call (NMAuthChain *self, const char *permission) typedef struct { CList data_lst; + const char *tag; gpointer data; GDestroyNotify destroy; - char tag[]; } ChainData; -static ChainData * -chain_data_new_stale (const char *tag, - gpointer data, - GDestroyNotify destroy) -{ - ChainData *chain_data; - gsize l_p_1; - - nm_assert (tag); - nm_assert (data); - - l_p_1 = strlen (tag) + 1; - chain_data = g_malloc (sizeof (ChainData) + l_p_1); - chain_data->data = data; - chain_data->destroy = destroy; - memcpy (&chain_data->tag[0], tag, l_p_1); - return chain_data; -} - static void chain_data_free (ChainData *chain_data) { c_list_unlink_stale (&chain_data->data_lst); if (chain_data->destroy) chain_data->destroy (chain_data->data); - g_free (chain_data); + g_slice_free (ChainData, chain_data); } static ChainData * @@ -204,11 +185,25 @@ nm_auth_chain_steal_data (NMAuthChain *self, const char *tag) return value; } +/** + * nm_auth_chain_set_data_unsafe: + * @self: the #NMAuthChain + * @tag: the tag for referencing the attached data. + * @data: the data to attach. If %NULL, this call has no effect + * and nothing is attached. + * @data_destroy: (allow-none): the destroy function for the data pointer. + * + * @tag string is not cloned and must outlife @self. That is why + * the function is "unsafe". Use nm_auth_chain_set_data() with a C literal + * instead. + * + * It is a bug to add the same tag more than once. + */ void -nm_auth_chain_set_data (NMAuthChain *self, - const char *tag, - gpointer data, - GDestroyNotify data_destroy) +nm_auth_chain_set_data_unsafe (NMAuthChain *self, + const char *tag, + gpointer data, + GDestroyNotify data_destroy) { ChainData *chain_data; @@ -232,7 +227,12 @@ nm_auth_chain_set_data (NMAuthChain *self, return; } - chain_data = chain_data_new_stale (tag, data, data_destroy); + chain_data = g_slice_new (ChainData); + *chain_data = (ChainData) { + .tag = tag, + .data = data, + .destroy = data_destroy, + }; /* we assert that no duplicate tags are added. But still, add the new * element to the front, so that it would shadow the duplicate element diff --git a/src/nm-auth-utils.h b/src/nm-auth-utils.h index e482af7f58..ebc7d0a9d1 100644 --- a/src/nm-auth-utils.h +++ b/src/nm-auth-utils.h @@ -44,10 +44,13 @@ gpointer nm_auth_chain_get_data (NMAuthChain *chain, const char *tag); gpointer nm_auth_chain_steal_data (NMAuthChain *chain, const char *tag); -void nm_auth_chain_set_data (NMAuthChain *chain, - const char *tag, - gpointer data, - GDestroyNotify data_destroy); +void nm_auth_chain_set_data_unsafe (NMAuthChain *chain, + const char *tag, + gpointer data, + GDestroyNotify data_destroy); + +#define nm_auth_chain_set_data(chain, tag, data, data_destroy) \ + nm_auth_chain_set_data_unsafe ((chain), ""tag"", (data), (data_destroy)) NMAuthCallResult nm_auth_chain_get_result (NMAuthChain *chain, const char *permission);