diff options
author | Davide Beatrici <git@davidebeatrici.dev> | 2020-11-04 22:32:32 +0300 |
---|---|---|
committer | Davide Beatrici <git@davidebeatrici.dev> | 2020-11-04 22:32:32 +0300 |
commit | 68873e5ed0eddf87df331bb841e8d2903cbd459a (patch) | |
tree | e56b5501084a8c4902cf39b3a6bbd7da39a08bb7 /plugins | |
parent | 13098748a9badf85f1faac65574570c3e9be3478 (diff) |
FIX(positional-audio): Wrong character size used for wide strings
"wchar_t" is usually 4 bytes big. That's not the case on Windows, where it's 2 bytes instead.
We cannot rely on that type on Linux because the target process could be native or running through Wine.
Also, it's possible that a game uses the same size for "wchar_t" on both Linux and Windows.
This commit introduces two variants of utf16ToUtf8():
1. Accepts std::u16string, for Windows processes.
2. Accepts std::u32string, for Linux processes.
The old variant, which accepted std::wstring, is removed to prevent misuses.
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/mumble_plugin_utils.h | 34 | ||||
-rw-r--r-- | plugins/ut99/ut99.cpp | 15 |
2 files changed, 33 insertions, 16 deletions
diff --git a/plugins/mumble_plugin_utils.h b/plugins/mumble_plugin_utils.h index 4c690b169..fb82cbca1 100644 --- a/plugins/mumble_plugin_utils.h +++ b/plugins/mumble_plugin_utils.h @@ -28,14 +28,36 @@ union SingleSplit4Bytes { constexpr SingleSplit4Bytes(const uint32_t value) : single(value) {} }; -static inline std::string utf16ToUtf8(const std::wstring &wstr) { - std::wstring_convert< std::codecvt_utf8_utf16< wchar_t > > conv; - return conv.to_bytes(wstr); +/// Converts from UTF-8 to UTF-16. +static inline std::wstring utf8ToUtf16(const std::string &str) { + try { + std::wstring_convert< std::codecvt_utf8_utf16< wchar_t > > conv; + return conv.from_bytes(str); + } catch (std::range_error &) { + return {}; + } } -static inline std::wstring utf8ToUtf16(const std::string &str) { - std::wstring_convert< std::codecvt_utf8_utf16< wchar_t > > conv; - return conv.from_bytes(str); +/// Converts from UTF-16 to UTF-8. +/// Meant to be used when "wchar_t" is 2 bytes, usually with Windows processes. +static inline std::string utf16ToUtf8(const std::u16string &str) { + try { + std::wstring_convert< std::codecvt_utf8_utf16< char16_t >, char16_t > conv; + return conv.to_bytes(str); + } catch (std::range_error &) { + return {}; + } +} + +/// Converts from UTF-16 to UTF-8. +/// Meant to be used when "wchar_t" is 4 bytes, usually with Linux processes. +static inline std::string utf16ToUtf8(const std::u32string &str) { + try { + std::wstring_convert< std::codecvt_utf8_utf16< char32_t >, char32_t > conv; + return conv.to_bytes(str); + } catch (std::range_error &) { + return {}; + } } // escape lossily converts the given diff --git a/plugins/ut99/ut99.cpp b/plugins/ut99/ut99.cpp index 691a78d50..004becbf0 100644 --- a/plugins/ut99/ut99.cpp +++ b/plugins/ut99/ut99.cpp @@ -143,20 +143,15 @@ static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, floa procptr_t cptr1 = peekProcPtr(cptr0 + 0x73C); procptr_t cptr2 = peekProcPtr(cptr1 + 0x244); - - wchar_t wservername[60]; - - ok = peekProc((procptr_t) cptr2, wservername); - if (!ok) + std::u16string servername; + servername.resize(60); + if (!peekProc(cptr2, &servername[0], servername.size())) { return false; - - wservername[sizeof(wservername) / sizeof(wservername[0]) - 1] = '\0'; - - const std::string servername = utf16ToUtf8(wservername); + } std::ostringstream contextss; contextss << "{" - << "\"servername\":\"" << servername << "\"" + << "\"servername\":\"" << utf16ToUtf8(servername) << "\"" << "}"; context = contextss.str(); |