luna: Make Utf8StringEncoder short-circuit instead of failing when hitting the length limit
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
apio 2023-01-14 12:07:08 +01:00
parent e3ef29e80d
commit d0600f5714
Signed by: apio
GPG Key ID: B8A7D06E42258954

View File

@ -2,8 +2,6 @@
#include <luna/CString.h>
#include <luna/Utf8.h>
// FIXME: Not enough space for a sequence is not an error. (mbstowcs(3) and wcstombs(3), case 2 when buf is not NULL)
static_assert(WCHAR_MAX > 0x10ffff);
static Result<usize> utf8_char_length(char c)
@ -32,31 +30,31 @@ static inline usize wide_char_length_as_utf8_unchecked(wchar_t c)
return 4;
}
static Result<void> encode_wide_char_as_utf8(wchar_t c, char* result, usize& len)
static Result<bool> encode_wide_char_as_utf8(wchar_t c, char* result, usize& len)
{
const usize utf8_len = TRY(wide_char_length_as_utf8(c));
if (utf8_len > len) { return err(EILSEQ); }
if (utf8_len > len) { return false; } // Not enough space
u8* buf = (u8*)result;
if (len == 1)
{
buf[0] = c & 0x7f;
return {};
return true;
}
if (len == 2)
{
buf[0] = 0b11000000 | ((c & 0x7c0) >> 6);
buf[1] = 0b10000000 | (c & 0x3f);
return {};
return true;
}
if (len == 3)
{
buf[0] = 0b11100000 | ((c & 0xf000) >> 12);
buf[1] = 0b10000000 | ((c & 0xfc0) >> 6);
buf[2] = 0b10000000 | (c & 0x3f);
return {};
return true;
}
if (len == 4)
{
@ -64,7 +62,7 @@ static Result<void> encode_wide_char_as_utf8(wchar_t c, char* result, usize& len
buf[1] = 0b10000000 | ((c & 0x3f000) >> 12);
buf[2] = 0b10000000 | ((c & 0xfc0) >> 6);
buf[3] = 0b10000000 | (c & 0x3f);
return {};
return true;
}
unreachable();
@ -197,7 +195,8 @@ Result<usize> Utf8StringEncoder::encode(char* buf, usize max) const
while (*it && max > 1)
{
usize len = max - 1;
TRY(encode_wide_char_as_utf8(*it, buf, len));
bool ok = TRY(encode_wide_char_as_utf8(*it, buf, len));
if (!ok) break;
buf += len;
max -= len;
it++;