]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
efi-string: add new xstr16_to_ascii() helper
authorLennart Poettering <lennart@poettering.net>
Tue, 11 Feb 2025 18:22:28 +0000 (19:22 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 21 Feb 2025 09:04:15 +0000 (10:04 +0100)
src/boot/efi-string.c
src/boot/efi-string.h
src/boot/test-efi-string.c

index aee98a81e1a17b5d3b28460b6c33790a1a0fd209..488798b393120b1c6af41beceee64f770f17bd7e 100644 (file)
@@ -188,8 +188,10 @@ static unsigned utf8_to_unichar(const char *utf8, size_t n, char32_t *c) {
 
 /* Convert UTF-8 to UCS-2, skipping any invalid or short byte sequences. */
 char16_t *xstrn8_to_16(const char *str8, size_t n) {
-        if (!str8 || n == 0)
-                return NULL;
+        assert(str8 || n == 0);
+
+        if (n == SIZE_MAX)
+                n = strlen8(str8);
 
         size_t i = 0;
         char16_t *str16 = xnew(char16_t, n + 1);
@@ -209,10 +211,34 @@ char16_t *xstrn8_to_16(const char *str8, size_t n) {
                 }
         }
 
-        str16[i] = '\0';
+        str16[i] = u'\0';
         return str16;
 }
 
+char *xstrn16_to_ascii(const char16_t *str16, size_t n) {
+        assert(str16 || n == 0);
+
+        if (n == SIZE_MAX)
+                n = strlen16(str16);
+
+        _cleanup_free_ char *str8 = xnew(char, n + 1);
+
+        size_t i = 0;
+        while (n > 0 && *str16 != u'\0') {
+
+                if ((uint16_t) *str16 > 127U) /* Not ASCII? Fail! */
+                        return NULL;
+
+                str8[i++] = (char) (uint16_t) *str16;
+
+                str16++;
+                n--;
+        }
+
+        str8[i] = '\0';
+        return TAKE_PTR(str8);
+}
+
 char* startswith8(const char *s, const char *prefix) {
         size_t l;
 
index 9a0f89d904c6754545c3fbd0bdc1fe04ec07ab1e..5c6326b495c7557174debf201bc26fbfcc56f6c6 100644 (file)
@@ -98,7 +98,12 @@ static inline char16_t *xstrdup16(const char16_t *s) {
 
 char16_t *xstrn8_to_16(const char *str8, size_t n);
 static inline char16_t *xstr8_to_16(const char *str8) {
-        return xstrn8_to_16(str8, strlen8(str8));
+        return xstrn8_to_16(str8, SIZE_MAX);
+}
+
+char *xstrn16_to_ascii(const char16_t *str16, size_t n);
+static inline char *xstr16_to_ascii(const char16_t *str16) {
+        return xstrn16_to_ascii(str16, SIZE_MAX);
 }
 
 char* startswith8(const char *s, const char *prefix);
index b71a0c3402591d7e2b422bfa5daab92252877c36..98c92690a7f7087ca523882b91d90fa9d7cdcf3e 100644 (file)
@@ -332,28 +332,68 @@ TEST(xstrdup16) {
 TEST(xstrn8_to_16) {
         char16_t *s = NULL;
 
-        assert_se(xstrn8_to_16(NULL, 1) == NULL);
-        assert_se(xstrn8_to_16("a", 0) == NULL);
+        assert_se(s = xstrn8_to_16(NULL, 0));
+        ASSERT_TRUE(streq16(s, u""));
+        free(s);
+
+        assert_se(s = xstrn8_to_16("", 0));
+        ASSERT_TRUE(streq16(s, u""));
+        free(s);
+
+        assert_se(s = xstrn8_to_16("a", 0));
+        ASSERT_TRUE(streq16(s, u""));
+        free(s);
 
         assert_se(s = xstrn8_to_16("", 1));
-        assert_se(streq16(s, u""));
+        ASSERT_TRUE(streq16(s, u""));
         free(s);
 
         assert_se(s = xstrn8_to_16("1", 1));
-        assert_se(streq16(s, u"1"));
+        ASSERT_TRUE(streq16(s, u"1"));
         free(s);
 
         assert_se(s = xstr8_to_16("abcxyzABCXYZ09 .,-_#*!\"§$%&/()=?`~"));
-        assert_se(streq16(s, u"abcxyzABCXYZ09 .,-_#*!\"§$%&/()=?`~"));
+        ASSERT_TRUE(streq16(s, u"abcxyzABCXYZ09 .,-_#*!\"§$%&/()=?`~"));
         free(s);
 
         assert_se(s = xstr8_to_16("ÿⱿ𝇉 😺"));
-        assert_se(streq16(s, u"ÿⱿ "));
+        ASSERT_TRUE(streq16(s, u"ÿⱿ "));
         free(s);
 
         assert_se(s = xstrn8_to_16("¶¶", 3));
-        assert_se(streq16(s, u"¶"));
+        ASSERT_TRUE(streq16(s, u"¶"));
+        free(s);
+}
+
+TEST(xstrn16_to_ascii) {
+        char *s;
+
+        assert_se(s = xstrn16_to_ascii(NULL, 0));
+        ASSERT_TRUE(streq8(s, ""));
         free(s);
+
+        assert_se(s = xstrn16_to_ascii(u"", 0));
+        ASSERT_TRUE(streq8(s, ""));
+        free(s);
+
+        assert_se(s = xstrn16_to_ascii(u"a", 0));
+        ASSERT_TRUE(streq8(s, ""));
+        free(s);
+
+        assert_se(s = xstrn16_to_ascii(u"", 1));
+        ASSERT_TRUE(streq8(s, ""));
+        free(s);
+
+        assert_se(s = xstrn16_to_ascii(u"1", 1));
+        ASSERT_TRUE(streq8(s, "1"));
+        free(s);
+
+        assert_se(s = xstr16_to_ascii(u"abcxyzABCXYZ09 .,-_#*!\"$%&/()=?`~"));
+        ASSERT_TRUE(streq8(s, "abcxyzABCXYZ09 .,-_#*!\"$%&/()=?`~"));
+        free(s);
+
+        assert_se(!xstr16_to_ascii(u"ÿⱿ𝇉 😺"));
+        assert_se(!xstr16_to_ascii(u"¶¶"));
 }
 
 TEST(startswith8) {