From 7005725bb2e7b0878060f95d045475ea8616f2a5 Mon Sep 17 00:00:00 2001 From: StackDoubleFlow Date: Fri, 4 Feb 2022 20:48:53 -0600 Subject: [PATCH] Fix implementation of to_utf8 and to_utf16 The current implementation of these functions do not properly convert between the unicode encodings and have caused bugs in the past. This new implementation makes use of std::codecvt and std::wstring_convert. Although these specializations of codecvt are now deprecated in c++20, they will still work until there is a suitable replacement in the standard library, and as far as I know, such a thing does not exist yet. It is recommended to use a proper library for this task. il2cpp has built in methods of performing this conversion, so it may be worth looking into that in the future. --- src/utils/utils.cpp | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp index 4bf7b4a3..77a8712c 100644 --- a/src/utils/utils.cpp +++ b/src/utils/utils.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include "il2cpp-object-internals.h" #include "modloader/shared/modloader.hpp" #include "shared/utils/gc-alloc.hpp" @@ -327,27 +329,12 @@ void setcsstr(Il2CppString* in, std::u16string_view str) { in->chars[in->length] = (Il2CppChar)'\u0000'; } -// Inspired by DaNike std::string to_utf8(std::u16string_view view) { - char* dat = static_cast(calloc(view.length() + 1, sizeof(char))); - std::transform(view.data(), view.data() + view.size(), dat, [](auto utf16_char) { - return static_cast(utf16_char); - }); - dat[view.length()] = '\0'; - std::string out(dat); - free(dat); - return out; + return std::wstring_convert, char16_t>{}.to_bytes(view.data()); } std::u16string to_utf16(std::string_view view) { - char16_t* dat = static_cast(calloc(view.length() + 1, sizeof(char16_t))); - std::transform(view.data(), view.data() + view.size(), dat, [](auto standardChar) { - return static_cast(standardChar); - }); - dat[view.length()] = '\0'; - std::u16string out(dat); - free(dat); - return out; + return std::wstring_convert, char16_t>{}.from_bytes(view.data()); } std::u16string_view csstrtostr(Il2CppString* in)