Skip to content

Commit b3bfc90

Browse files
author
chromium
committed
shared: replace ToNarrow/ToWide wuth utfcpp for runtime safety and portability
1 parent 45860b1 commit b3bfc90

File tree

6 files changed

+51
-5
lines changed

6 files changed

+51
-5
lines changed

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,6 @@
109109
[submodule "vendor/eastl"]
110110
path = vendor/eastl
111111
url = https://github.com/electronicarts/EASTL.git
112+
[submodule "vendor/utfcpp"]
113+
path = vendor/utfcpp
114+
url = https://github.com/nemtrif/utfcpp.git

code/client/shared/Utils.cpp

+27-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <sstream>
1111
#include <iomanip>
1212
#include <mutex>
13+
#include <utf8.h>
1314
#include "Error.h"
1415

1516
static STATIC InitFunctionBase* g_initFunctions;
@@ -349,12 +350,34 @@ bool UrlDecode(const std::string& in, std::string& out)
349350

350351
std::string ToNarrow(const std::wstring& wide)
351352
{
352-
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> g_converter;
353-
return g_converter.to_bytes(wide);
353+
// TODO: replace with something faster if needed
354+
std::vector<char> outVec;
355+
outVec.reserve(wide.size());
356+
357+
#ifdef _WIN32
358+
utf8::utf16to8(wide.begin(), wide.end(), std::back_inserter(outVec));
359+
#else
360+
utf8::utf32to8(wide.begin(), wide.end(), std::back_inserter(outVec));
361+
#endif
362+
363+
return std::string(outVec.begin(), outVec.end());
354364
}
355365

356366
std::wstring ToWide(const std::string& narrow)
357367
{
358-
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> g_converter;
359-
return g_converter.from_bytes(narrow);
368+
std::vector<uint8_t> cleanVec;
369+
cleanVec.reserve(narrow.size());
370+
371+
utf8::replace_invalid(narrow.begin(), narrow.end(), std::back_inserter(cleanVec));
372+
373+
std::vector<wchar_t> outVec;
374+
outVec.reserve(cleanVec.size());
375+
376+
#ifdef _WIN32
377+
utf8::utf8to16(cleanVec.begin(), cleanVec.end(), std::back_inserter(outVec));
378+
#else
379+
utf8::utf8to32(cleanVec.begin(), cleanVec.end(), std::back_inserter(outVec));
380+
#endif
381+
382+
return std::wstring(outVec.begin(), outVec.end());
360383
}

code/client/shared/premake5.lua

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
else
1414
add_dependencies { 'vendor:fmtlib' }
1515
end
16+
17+
add_dependencies { 'vendor:utfcpp' }
1618

1719
if os.is('windows') then
1820
links { libc and 'fmtlib-crt' or 'fmtlib' }

code/vendor/config.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,5 @@ vendor_component 'openssl_crypto'
4848
vendor_component 'openssl_ssl'
4949
vendor_component 'minizip'
5050
vendor_component 'glm'
51-
51+
vendor_component 'utfcpp'
5252
vendor_component 'eastl'

code/vendor/utfcpp.lua

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
return {
2+
include = function()
3+
includedirs {
4+
"../vendor/utfcpp/source/"
5+
}
6+
end,
7+
8+
run = function()
9+
targetname 'utfcpp_dummy'
10+
language 'C'
11+
kind 'StaticLib'
12+
13+
files {
14+
'vendor/dummy.c'
15+
}
16+
end
17+
}

vendor/utfcpp

Submodule utfcpp added at 60c490b

0 commit comments

Comments
 (0)