From: dongshengyuan <545258830@qq.com>
Date: Fri, 31 Jul 2026 07:23:47 +0000 (+0800)
Subject: sd-id128: parse UUID URNs
X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3bb3c54f3da45cd62893194de2bd2ab3c7d84f63;p=thirdparty%2Fsystemd.git
sd-id128: parse UUID URNs
Accept RFC4122 UUID URN strings with the `urn:uuid:` prefix in
sd_id128_from_string(), while keeping plain 128-bit IDs and regular
UUID strings working as before.
---
diff --git a/TODO.md b/TODO.md
index 1697add812f..d0659553aee 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1262,8 +1262,6 @@ SPDX-License-Identifier: LGPL-2.1-or-later
- in pid1: include ExecStart= cmdlines (and other Exec*= cmdlines) in polkit
request, so that policies can match against command lines.
-- in sd-id128: also parse UUIDs in RFC4122 URN syntax (i.e. chop off urn:uuid: prefix)
-
- in sd-stub: optionally add support for a new PE section .keyring or so that
contains additional certificates to include in the Mok keyring, extending
what shim might have placed there. why? let's say I use "ukify" to build +
diff --git a/man/sd_id128_to_string.xml b/man/sd_id128_to_string.xml
index f5b6c9490ff..f52f41c5baa 100644
--- a/man/sd_id128_to_string.xml
+++ b/man/sd_id128_to_string.xml
@@ -78,8 +78,10 @@
character string with 32 hexadecimal digits (either lowercase or uppercase, terminated by
NUL) and parses them back into a 128-bit ID returned in
ret. Alternatively, this call can also parse a 37-character string with a 128-bit
- ID formatted as RFC UUID. If ret is passed as NULL the
- function will validate the passed ID string, but not actually return it in parsed form.
+ ID formatted as RFC UUID, and a 46-character string consisting of the 9-character
+ urn:uuid: prefix, a 36-character RFC UUID, and a terminating
+ NUL. If ret is passed as NULL the function
+ will validate the passed ID string, but not actually return it in parsed form.
Note that when formatting and parsing 36 character UUIDs this is done strictly in Big Endian byte order,
i.e. according to RFC4122 Variant 1 rules, even
diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c
index ba3e47dd8d5..3caae11805c 100644
--- a/src/libsystemd/sd-id128/sd-id128.c
+++ b/src/libsystemd/sd-id128/sd-id128.c
@@ -16,6 +16,7 @@
#include "path-util.h"
#include "random-util.h"
#include "stat-util.h"
+#include "string-util.h"
#include "user-util.h"
_public_ char *sd_id128_to_string(sd_id128_t id, char s[static SD_ID128_STRING_MAX]) {
@@ -63,6 +64,12 @@ _public_ int sd_id128_from_string(const char *s, sd_id128_t *ret) {
assert_return(s, -EINVAL);
+ const char *u = startswith_no_case(s, "urn:uuid:");
+ if (u) {
+ s = u;
+ is_guid = true;
+ }
+
for (n = 0, i = 0; n < sizeof(sd_id128_t);) {
int a, b;
diff --git a/src/libsystemd/sd-id128/test-id128.c b/src/libsystemd/sd-id128/test-id128.c
index 9c28e82f5ca..ded8eb58697 100644
--- a/src/libsystemd/sd-id128/test-id128.c
+++ b/src/libsystemd/sd-id128/test-id128.c
@@ -20,6 +20,7 @@
#define ID128_WALDI SD_ID128_MAKE(01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f, 10)
#define STR_WALDI "0102030405060708090a0b0c0d0e0f10"
#define UUID_WALDI "01020304-0506-0708-090a-0b0c0d0e0f10"
+#define UUID_URN_WALDI "urn:uuid:01020304-0506-0708-090a-0b0c0d0e0f10"
#define STR_NULL "00000000000000000000000000000000"
TEST(id128) {
@@ -70,18 +71,30 @@ TEST(id128) {
ASSERT_OK(sd_id128_from_string(UUID_WALDI, &id));
ASSERT_EQ_ID128(id, ID128_WALDI);
+ ASSERT_OK(sd_id128_from_string(UUID_URN_WALDI, &id));
+ ASSERT_EQ_ID128(id, ID128_WALDI);
+
+ ASSERT_OK(sd_id128_from_string("URN:UUID:01020304-0506-0708-090a-0b0c0d0e0f10", &id));
+ ASSERT_EQ_ID128(id, ID128_WALDI);
+
ASSERT_FAIL(sd_id128_from_string("", &id));
ASSERT_FAIL(sd_id128_from_string("01020304-0506-0708-090a-0b0c0d0e0f101", &id));
ASSERT_FAIL(sd_id128_from_string("01020304-0506-0708-090a-0b0c0d0e0f10-", &id));
ASSERT_FAIL(sd_id128_from_string("01020304-0506-0708-090a0b0c0d0e0f10", &id));
ASSERT_FAIL(sd_id128_from_string("010203040506-0708-090a-0b0c0d0e0f10", &id));
+ ASSERT_FAIL(sd_id128_from_string("urn:uuid:0102030405060708090a0b0c0d0e0f10", &id));
+ ASSERT_FAIL(sd_id128_from_string("urn:uuid:01020304-0506-0708-090a0b0c0d0e0f10", &id));
ASSERT_OK(id128_from_string_nonzero(STR_WALDI, &id));
+ ASSERT_OK(id128_from_string_nonzero(UUID_URN_WALDI, &id));
ASSERT_ERROR(id128_from_string_nonzero(STR_NULL, &id), ENXIO);
+ ASSERT_ERROR(id128_from_string_nonzero("urn:uuid:00000000-0000-0000-0000-000000000000", &id),
+ ENXIO);
ASSERT_FAIL(id128_from_string_nonzero("01020304-0506-0708-090a-0b0c0d0e0f101", &id));
ASSERT_FAIL(id128_from_string_nonzero("01020304-0506-0708-090a-0b0c0d0e0f10-", &id));
ASSERT_FAIL(id128_from_string_nonzero("01020304-0506-0708-090a0b0c0d0e0f10", &id));
ASSERT_FAIL(id128_from_string_nonzero("010203040506-0708-090a-0b0c0d0e0f10", &id));
+ ASSERT_FAIL(id128_from_string_nonzero("urn:uuid:0102030405060708090a0b0c0d0e0f10", &id));
ASSERT_TRUE(id128_is_valid(STR_WALDI));
ASSERT_TRUE(id128_is_valid(UUID_WALDI));