@@ -18,6 +18,7 @@ const char* kOdbcEncoding = "utf-16-le"; // ODBC uses UTF-16LE for SQLWCHAR
1818const size_t kUcsLength = 2 ; // SQLWCHAR is 2 bytes on all platforms
1919
2020// Function to convert SQLWCHAR strings to std::wstring on macOS
21+ // THREAD-SAFE: Uses thread_local converter to avoid std::wstring_convert race conditions
2122std::wstring SQLWCHARToWString (const SQLWCHAR* sqlwStr, size_t length = SQL_NTS) {
2223 if (!sqlwStr) {
2324 return std::wstring ();
@@ -40,9 +41,13 @@ std::wstring SQLWCHARToWString(const SQLWCHAR* sqlwStr, size_t length = SQL_NTS)
4041
4142 // Convert UTF-16LE to std::wstring (UTF-32 on macOS)
4243 try {
43- // Use C++11 codecvt to convert between UTF-16LE and wstring
44- std::wstring_convert<std::codecvt_utf8_utf16<wchar_t , 0x10ffff , std::little_endian>>
44+ // CRITICAL FIX: Use thread_local to make std::wstring_convert thread-safe
45+ // std::wstring_convert is NOT thread-safe and its use is deprecated in C++17
46+ // Each thread gets its own converter instance, eliminating race conditions
47+ thread_local std::wstring_convert<
48+ std::codecvt_utf8_utf16<wchar_t , 0x10ffff , std::little_endian>>
4549 converter;
50+
4651 std::wstring result = converter.from_bytes (
4752 reinterpret_cast <const char *>(utf16Bytes.data ()),
4853 reinterpret_cast <const char *>(utf16Bytes.data () + utf16Bytes.size ()));
@@ -59,11 +64,16 @@ std::wstring SQLWCHARToWString(const SQLWCHAR* sqlwStr, size_t length = SQL_NTS)
5964}
6065
6166// Function to convert std::wstring to SQLWCHAR array on macOS
67+ // THREAD-SAFE: Uses thread_local converter to avoid std::wstring_convert race conditions
6268std::vector<SQLWCHAR> WStringToSQLWCHAR (const std::wstring& str) {
6369 try {
64- // Convert wstring (UTF-32 on macOS) to UTF-16LE bytes
65- std::wstring_convert<std::codecvt_utf8_utf16<wchar_t , 0x10ffff , std::little_endian>>
70+ // CRITICAL FIX: Use thread_local to make std::wstring_convert thread-safe
71+ // std::wstring_convert is NOT thread-safe and its use is deprecated in C++17
72+ // Each thread gets its own converter instance, eliminating race conditions
73+ thread_local std::wstring_convert<
74+ std::codecvt_utf8_utf16<wchar_t , 0x10ffff , std::little_endian>>
6675 converter;
76+
6777 std::string utf16Bytes = converter.to_bytes (str);
6878
6979 // Convert the bytes to SQLWCHAR array
0 commit comments