From: Lennart Poettering Date: Tue, 11 Feb 2025 18:22:28 +0000 (+0100) Subject: efi-string: add new xstr16_to_ascii() helper X-Git-Tag: v258-rc1~1280^2~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d9d3e9d6c14e1ffc2d5fb03c66a24a3e20f9bc1d;p=thirdparty%2Fsystemd.git efi-string: add new xstr16_to_ascii() helper --- diff --git a/src/boot/efi-string.c b/src/boot/efi-string.c index aee98a81e1a..488798b3931 100644 --- a/src/boot/efi-string.c +++ b/src/boot/efi-string.c @@ -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; diff --git a/src/boot/efi-string.h b/src/boot/efi-string.h index 9a0f89d904c..5c6326b495c 100644 --- a/src/boot/efi-string.h +++ b/src/boot/efi-string.h @@ -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); diff --git a/src/boot/test-efi-string.c b/src/boot/test-efi-string.c index b71a0c34025..98c92690a7f 100644 --- a/src/boot/test-efi-string.c +++ b/src/boot/test-efi-string.c @@ -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) {