]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-id128: parse UUID URNs
authordongshengyuan <545258830@qq.com>
Fri, 31 Jul 2026 07:23:47 +0000 (15:23 +0800)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 2 Aug 2026 10:17:03 +0000 (19:17 +0900)
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.

TODO.md
man/sd_id128_to_string.xml
src/libsystemd/sd-id128/sd-id128.c
src/libsystemd/sd-id128/test-id128.c

diff --git a/TODO.md b/TODO.md
index 1697add812fa53611e5585be8754b1da3181bb44..d0659553aee715508d0c4ffa1bd4475ccf433eb9 100644 (file)
--- 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 +
index f5b6c9490ff2b9abe96892a7b28f66bc34c664c1..f52f41c5baa3571c2b8fdee0308b43ea3ebf1391 100644 (file)
     character string with 32 hexadecimal digits (either lowercase or uppercase, terminated by
     <constant>NUL</constant>) and parses them back into a 128-bit ID returned in
     <parameter>ret</parameter>. Alternatively, this call can also parse a 37-character string with a 128-bit
-    ID formatted as RFC UUID. If <parameter>ret</parameter> is passed as <constant>NULL</constant> the
-    function will validate the passed ID string, but not actually return it in parsed form.</para>
+    ID formatted as RFC UUID, and a 46-character string consisting of the 9-character
+    <literal>urn:uuid:</literal> prefix, a 36-character RFC UUID, and a terminating
+    <constant>NUL</constant>. If <parameter>ret</parameter> is passed as <constant>NULL</constant> the function
+    will validate the passed ID string, but not actually return it in parsed form.</para>
 
     <para>Note that when formatting and parsing 36 character UUIDs this is done strictly in Big Endian byte order,
     i.e. according to <ulink url="https://tools.ietf.org/html/rfc4122">RFC4122</ulink> Variant 1 rules, even
index ba3e47dd8d5c1bda9dcedded75a9e1f7e355dffc..3caae11805cb2a6863e8a43693ce11d11904096b 100644 (file)
@@ -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;
 
index 9c28e82f5ca1f6820d1587a43ad4d19a042a06d1..ded8eb586978fafbc98faa3166239fc528156aef 100644 (file)
@@ -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));