utf8: automatically determine length of string if SIZE_MAX is specified

Let's make utf8_to_utf16() and utf16_to_utf8() a bit nicer to use by
adding shortcuts for common cases.

This is particularly relevant for utf16_to_utf8() since the
multiplication with 2 is easy to forget.
This commit is contained in:
Lennart Poettering
2023-08-24 13:19:12 +02:00
parent b56ee69233
commit ba091282e5
6 changed files with 30 additions and 9 deletions
+1 -1
View File
@@ -265,7 +265,7 @@ finish:
int efi_set_variable_string(const char *variable, const char *value) {
_cleanup_free_ char16_t *u16 = NULL;
u16 = utf8_to_utf16(value, strlen(value));
u16 = utf8_to_utf16(value, SIZE_MAX);
if (!u16)
return -ENOMEM;
+22 -1
View File
@@ -389,11 +389,23 @@ char *utf16_to_utf8(const char16_t *s, size_t length /* bytes! */) {
const uint8_t *f;
char *r, *t;
if (length == 0)
return new0(char, 1);
assert(s);
if (length == SIZE_MAX) {
length = char16_strlen(s);
if (length > SIZE_MAX/2)
return NULL; /* overflow */
length *= 2;
}
/* Input length is in bytes, i.e. the shortest possible character takes 2 bytes. Each unicode character may
* take up to 4 bytes in UTF-8. Let's also account for a trailing NUL byte. */
if (length * 2 < length)
if (length > (SIZE_MAX - 1) / 2)
return NULL; /* overflow */
r = new(char, length * 2 + 1);
@@ -463,8 +475,17 @@ char16_t *utf8_to_utf16(const char *s, size_t length) {
char16_t *n, *p;
int r;
if (length == 0)
return new0(char16_t, 1);
assert(s);
if (length == SIZE_MAX)
length = strlen(s);
if (length > SIZE_MAX - 1)
return NULL; /* overflow */
n = new(char16_t, length + 1);
if (!n)
return NULL;