summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2022-10-11 09:06:29 +0200
committerThomas Haller <thaller@redhat.com>2022-10-11 09:06:29 +0200
commite99889f9776e55ce74f18c81609722e86b6fd2cc (patch)
tree8e5cb97748f652f83b6a2af79dda5244558b3119
parenta9bc3ec08b0bce54cc661ffe01a47a1b2b35c81b (diff)
parent2d8651ba91dc1fd30f08f7ebc2cb0f8bab4d958d (diff)
downloadNetworkManager-e99889f9776e55ce74f18c81609722e86b6fd2cc.tar.gz
glib-aux: merge branch 'th/uuid-generate-strv-null'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1417
-rw-r--r--src/core/devices/nm-device-ethernet.c10
-rw-r--r--src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c3
-rw-r--r--src/libnm-core-impl/nm-keyfile.c5
-rw-r--r--src/libnm-core-impl/tests/test-general.c105
-rw-r--r--src/libnm-glib-aux/nm-uuid.c40
-rw-r--r--src/libnm-glib-aux/nm-uuid.h19
-rw-r--r--src/nm-initrd-generator/nmi-ibft-reader.c14
7 files changed, 139 insertions, 57 deletions
diff --git a/src/core/devices/nm-device-ethernet.c b/src/core/devices/nm-device-ethernet.c
index dff6466a2e..414bfa7b4b 100644
--- a/src/core/devices/nm-device-ethernet.c
+++ b/src/core/devices/nm-device-ethernet.c
@@ -1725,12 +1725,10 @@ new_default_connection(NMDevice *self)
/* Create a stable UUID. The UUID is also the Network_ID for stable-privacy addr-gen-mode,
* thus when it changes we will also generate different IPv6 addresses. */
- uuid = nm_uuid_generate_from_strings(NM_UUID_TYPE_VERSION3,
- &nm_uuid_ns_1,
- "default-wired",
- nm_utils_machine_id_str(),
- defname,
- perm_hw_addr ?: iface);
+ uuid = nm_uuid_generate_from_strings_old("default-wired",
+ nm_utils_machine_id_str(),
+ defname,
+ perm_hw_addr ?: iface);
g_object_set(setting,
NM_SETTING_CONNECTION_ID,
diff --git a/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c b/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c
index eec529ce6c..28923ae6e1 100644
--- a/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c
+++ b/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c
@@ -2296,8 +2296,7 @@ test_read_missing_id_uuid(void)
gs_free char *expected_uuid = NULL;
const char *FILENAME = TEST_KEYFILES_DIR "/Test_Missing_ID_UUID";
- expected_uuid =
- nm_uuid_generate_from_strings(NM_UUID_TYPE_VERSION3, &nm_uuid_ns_1, "keyfile", FILENAME);
+ expected_uuid = nm_uuid_generate_from_strings_old("keyfile", FILENAME);
connection = keyfile_read_connection_from_file(FILENAME);
diff --git a/src/libnm-core-impl/nm-keyfile.c b/src/libnm-core-impl/nm-keyfile.c
index d8dd27821f..ae6d892c28 100644
--- a/src/libnm-core-impl/nm-keyfile.c
+++ b/src/libnm-core-impl/nm-keyfile.c
@@ -3800,10 +3800,7 @@ nm_keyfile_read_ensure_uuid(NMConnection *connection, const char *fallback_uuid_
if (nm_setting_connection_get_uuid(s_con))
return FALSE;
- hashed_uuid = nm_uuid_generate_from_strings(NM_UUID_TYPE_VERSION3,
- &nm_uuid_ns_1,
- "keyfile",
- fallback_uuid_seed);
+ hashed_uuid = nm_uuid_generate_from_strings_old("keyfile", fallback_uuid_seed);
g_object_set(s_con, NM_SETTING_CONNECTION_UUID, hashed_uuid, NULL);
return TRUE;
}
diff --git a/src/libnm-core-impl/tests/test-general.c b/src/libnm-core-impl/tests/test-general.c
index 904d89f337..6a85fe4c79 100644
--- a/src/libnm-core-impl/tests/test-general.c
+++ b/src/libnm-core-impl/tests/test-general.c
@@ -7946,16 +7946,50 @@ test_nm_utils_uuid_generate_from_string(void)
/*****************************************************************************/
static void
-_check_uuid(NMUuidType uuid_type,
- const NMUuid *type_arg,
- const char *expected_uuid,
- const char *str,
- gssize slen,
- char *uuid_test)
-{
+_check_uuid(NMUuidType uuid_type,
+ const NMUuid *type_arg,
+ const char *expected_uuid,
+ const char *str,
+ gssize slen,
+ const char *const *strv,
+ gssize strv_len)
+{
+ gs_free char *uuid_test = NULL;
+ gs_free char *uuid_test2 = NULL;
+ gboolean uuid_test2_valid = TRUE;
+
+ g_assert(str);
+ g_assert(strv_len < 0 || strv);
+
+ uuid_test = nm_uuid_generate_from_strings_strv(uuid_type, type_arg, strv, strv_len);
+
g_assert(uuid_test);
g_assert(nm_uuid_is_normalized(uuid_test));
- g_assert(str);
+
+ if (strv_len < 0 && strv) {
+ uuid_test2 =
+ nm_uuid_generate_from_strings_strv(uuid_type, type_arg, strv, NM_PTRARRAY_LEN(strv));
+ } else if (strv_len >= 0) {
+ gssize l = nm_strv_find_first(strv, strv_len, NULL);
+ gs_free const char **strv2 = nm_strv_dup_packed(strv, l < 0 ? strv_len : l);
+
+ uuid_test2 = nm_uuid_generate_from_strings_strv(uuid_type,
+ type_arg,
+ strv2 ?: NM_STRV_EMPTY_CC(),
+ -1);
+ if (l >= 0) {
+ /* there are NULL strings. The result won't be match. */
+ uuid_test2_valid = FALSE;
+ }
+ }
+ if (uuid_test2) {
+ if (uuid_test2_valid)
+ g_assert_cmpstr(uuid_test, ==, uuid_test2);
+ else {
+ g_assert(nm_uuid_is_normalized(uuid_test));
+ g_assert_cmpstr(uuid_test, !=, uuid_test2);
+ }
+ }
if (!nm_streq(uuid_test, expected_uuid)) {
g_error("UUID test failed (1): text=%s, len=%lld, expected=%s, uuid_test=%s",
@@ -7978,24 +8012,19 @@ _check_uuid(NMUuidType uuid_type,
expected_uuid,
uuid_test);
}
- g_free(uuid_test);
}
-#define check_uuid(uuid_type, type_arg, expected_uuid, str, ...) \
- ({ \
- const NMUuidType _uuid_type = (uuid_type); \
- const NMUuid *_type_arg = type_arg; \
- const char *_expected_uuid = (expected_uuid); \
- const char *_str = (str); \
- const gsize _strlen = NM_STRLEN(str); \
- \
- _check_uuid( \
- _uuid_type, \
- _type_arg, \
- _expected_uuid, \
- _str, \
- _strlen, \
- nm_uuid_generate_from_strings_strv(_uuid_type, _type_arg, NM_MAKE_STRV(__VA_ARGS__))); \
+#define check_uuid(uuid_type, type_arg, expected_uuid, str, ...) \
+ ({ \
+ const NMUuidType _uuid_type = (uuid_type); \
+ const NMUuid *_type_arg = type_arg; \
+ const char *_expected_uuid = (expected_uuid); \
+ const char *_str = (str); \
+ const gsize _strlen = NM_STRLEN(str); \
+ const char *const *_strv = NM_MAKE_STRV(__VA_ARGS__); \
+ const gssize _strv_len = NM_NARG(__VA_ARGS__); \
+ \
+ _check_uuid(_uuid_type, _type_arg, _expected_uuid, _str, _strlen, _strv, _strv_len); \
})
static void
@@ -8023,12 +8052,9 @@ test_nm_utils_uuid_generate_from_strings(void)
"457229f4-fe49-32f5-8b09-c531d81f44d9",
"x",
1,
- nm_uuid_generate_from_strings_strv(NM_UUID_TYPE_VERSION3, &nm_uuid_ns_1, NULL));
- check_uuid(NM_UUID_TYPE_VERSION3,
- &nm_uuid_ns_1,
- "b07c334a-399b-32de-8d50-58e4e08f98e3",
- "",
- NULL);
+ NULL,
+ -1);
+ check_uuid(NM_UUID_TYPE_VERSION3, &nm_uuid_ns_1, "b07c334a-399b-32de-8d50-58e4e08f98e3", "");
check_uuid(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
"b8a426cb-bcb5-30a3-bd8f-6786fea72df9",
@@ -8036,6 +8062,11 @@ test_nm_utils_uuid_generate_from_strings(void)
"");
check_uuid(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
+ "9232afda-85fc-3b8f-8736-4f99c8d5db9c",
+ "_n",
+ NULL);
+ check_uuid(NM_UUID_TYPE_VERSION3,
+ &nm_uuid_ns_1,
"12a4a982-7aae-39e1-951e-41aeb1250959",
"a\0",
"a");
@@ -8076,6 +8107,13 @@ test_nm_utils_uuid_generate_from_strings(void)
"a");
check_uuid(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
+ "f36cec99-1db8-3baa-8c3f-13e13d980318",
+ "a\0a\0001_1n",
+ "a",
+ NULL,
+ "a");
+ check_uuid(NM_UUID_TYPE_VERSION3,
+ &nm_uuid_ns_1,
"fd698d86-1b60-3ebe-855f-7aada9950a8d",
"aa\0a\0",
"aa",
@@ -8117,6 +8155,13 @@ test_nm_utils_uuid_generate_from_strings(void)
"\0b\0",
"",
"b");
+ check_uuid(NM_UUID_TYPE_VERSION5,
+ _uuid(NM_UUID_NS_URL),
+ "db3dfd17-c785-509d-a0ca-740fdd68dc68",
+ "\0b\00011_n",
+ "",
+ "b",
+ NULL);
check_uuid(NM_UUID_TYPE_VERSION3,
_uuid(NM_UUID_NS_URL),
"916dcdd8-5042-3b9b-9763-4312a31e5735",
diff --git a/src/libnm-glib-aux/nm-uuid.c b/src/libnm-glib-aux/nm-uuid.c
index ae0f7233e7..cdfa5f629e 100644
--- a/src/libnm-glib-aux/nm-uuid.c
+++ b/src/libnm-glib-aux/nm-uuid.c
@@ -12,7 +12,7 @@
const NMUuid nm_uuid_ns_zero =
NM_UUID_INIT(00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00);
-/* arbitrarily chosen namespace UUID for some uses of nm_uuid_generate_from_strings().
+/* arbitrarily chosen namespace UUID for some uses of nm_uuid_generate_from_strings_old().
* Try not to re-use this namespace, instead, generate a unique one. */
const NMUuid nm_uuid_ns_1 =
NM_UUID_INIT(b4, 25, e9, fb, 75, 98, 44, b4, 9e, 3b, 5a, 2e, 3a, aa, 49, 05);
@@ -413,6 +413,10 @@ nm_uuid_generate_from_string_str(const char *s,
* @type_args: the namespace UUID.
* @strv: (allow-none): the strv list to hash. Can be NULL, in which
* case the result is different from an empty array.
+ * @len: if negative, @strv is a NULL terminated array. Otherwise,
+ * it is the length of the strv array. In the latter case it may
+ * also contain NULL strings. The result hashes differently depending
+ * on whether we have a NULL terminated strv array or given length.
*
* Returns a @uuid_type UUID based on the concatenated C strings.
* It does not simply concatenate them, but also includes the
@@ -425,13 +429,43 @@ nm_uuid_generate_from_string_str(const char *s,
char *
nm_uuid_generate_from_strings_strv(NMUuidType uuid_type,
const NMUuid *type_args,
- const char *const *strv)
+ const char *const *strv,
+ gssize len)
{
nm_auto_str_buf NMStrBuf str = NM_STR_BUF_INIT_A(NM_UTILS_GET_NEXT_REALLOC_SIZE_232, TRUE);
gsize slen;
const char *s;
- if (!strv) {
+ if (len >= 0) {
+ gboolean has_nulls = FALSE;
+ gssize i;
+
+ nm_assert(len == 0 || strv);
+
+ for (i = 0; i < len; i++) {
+ if (strv[i])
+ nm_str_buf_append_len(&str, strv[i], strlen(strv[i]) + 1u);
+ else
+ has_nulls = TRUE;
+ }
+ if (has_nulls) {
+ /* We either support a NULL terminated strv array, or a ptr array of fixed
+ * length (@len argument).
+ *
+ * If there are no NULLs within the first @len strings, then the result
+ * is the same. If there are any NULL strings, we need to encode that
+ * in a unique way. We do that by appending a bitmap of the elements
+ * whether they were set, plus one 'n' character (without NUL termination).
+ * None of the other branches below hashes to that, so this will uniquely
+ * encoded the NULL strings.
+ */
+ for (i = 0; i < len; i++)
+ nm_str_buf_append_c(&str, strv[i] ? '1' : '_');
+ nm_str_buf_append_c(&str, 'n');
+ }
+ slen = str.len;
+ s = nm_str_buf_get_str_unsafe(&str);
+ } else if (!strv) {
/* NULL is treated differently from an empty strv. We achieve that
* by using a non-empty, non-NUL terminated string (which cannot happen
* in the other cases). */
diff --git a/src/libnm-glib-aux/nm-uuid.h b/src/libnm-glib-aux/nm-uuid.h
index 770d7af1ae..d26616cf4f 100644
--- a/src/libnm-glib-aux/nm-uuid.h
+++ b/src/libnm-glib-aux/nm-uuid.h
@@ -125,10 +125,21 @@ char *nm_uuid_generate_from_string_str(const char *s,
char *nm_uuid_generate_from_strings_strv(NMUuidType uuid_type,
const NMUuid *type_args,
- const char *const *strv);
-
-#define nm_uuid_generate_from_strings(uuid_type, type_args, ...) \
- nm_uuid_generate_from_strings_strv((uuid_type), (type_args), NM_MAKE_STRV(__VA_ARGS__))
+ const char *const *strv,
+ gssize len);
+
+#define nm_uuid_generate_from_strings(uuid_type, type_args, ...) \
+ nm_uuid_generate_from_strings_strv((uuid_type), \
+ (type_args), \
+ NM_MAKE_STRV(__VA_ARGS__), \
+ NM_NARG(__VA_ARGS__))
+
+/* Legacy function. Don't use for new code. */
+#define nm_uuid_generate_from_strings_old(uuid_type, type_args, ...) \
+ nm_uuid_generate_from_strings_strv(NM_UUID_TYPE_VERSION3, \
+ &nm_uuid_ns_1, \
+ NM_MAKE_STRV(__VA_ARGS__), \
+ -1)
/*****************************************************************************/
diff --git a/src/nm-initrd-generator/nmi-ibft-reader.c b/src/nm-initrd-generator/nmi-ibft-reader.c
index c0915a8f01..2a3bbdfbcb 100644
--- a/src/nm-initrd-generator/nmi-ibft-reader.c
+++ b/src/nm-initrd-generator/nmi-ibft-reader.c
@@ -307,14 +307,12 @@ connection_setting_add(GHashTable *nic,
s_index ? " " : "",
s_index ? s_index : "");
- uuid = nm_uuid_generate_from_strings(NM_UUID_TYPE_VERSION3,
- &nm_uuid_ns_1,
- "ibft",
- s_hwaddr,
- s_vlanid ? "V" : "v",
- s_vlanid ? s_vlanid : "",
- s_ipaddr ? "A" : "DHCP",
- s_ipaddr ? s_ipaddr : "");
+ uuid = nm_uuid_generate_from_strings_old("ibft",
+ s_hwaddr,
+ s_vlanid ? "V" : "v",
+ s_vlanid ? s_vlanid : "",
+ s_ipaddr ? "A" : "DHCP",
+ s_ipaddr ? s_ipaddr : "");
s_con = (NMSetting *) nm_connection_get_setting_connection(connection);
if (!s_con) {