@@ -127,10 +127,13 @@ bool convert_string_from_utf16( _In_ SQLSRV_ENCODING encoding, _In_reads_bytes_(
127127 flags = WC_ERR_INVALID_CHARS ;
128128 }
129129
130- // calculate the number of characters needed
131130#ifndef _WIN32
132- cchOutLen = SystemLocale::FromUtf16Strict ( encoding, inString, cchInLen, NULL , 0 );
131+ // Allocate enough space to hold the largest possible number of bytes for UTF-8 conversion
132+ // instead of calling FromUtf16, for performance reasons
133+ cchOutLen = 4 *cchInLen;
133134#else
135+ // Calculate the number of output bytes required - no performance hit here because
136+ // WideCharToMultiByte is highly optimised
134137 cchOutLen = WideCharToMultiByte ( encoding, flags,
135138 inString, cchInLen,
136139 NULL , 0 , NULL , NULL );
@@ -142,9 +145,10 @@ bool convert_string_from_utf16( _In_ SQLSRV_ENCODING encoding, _In_reads_bytes_(
142145
143146 // Create a buffer to fit the encoded string
144147 char * newString = reinterpret_cast <char *>( sqlsrv_malloc ( cchOutLen + 1 /* NULL char*/ ));
148+ memset (newString, ' \0 ' , cchOutLen+1 );
145149
146150#ifndef _WIN32
147- int rc = SystemLocale::FromUtf16 ( encoding, inString, cchInLen, newString, static_cast <int >(cchOutLen));
151+ int rc = SystemLocale::FromUtf16Strict ( encoding, inString, cchInLen, newString, static_cast <int >(cchOutLen));
148152#else
149153 int rc = WideCharToMultiByte ( encoding, flags, inString, cchInLen, newString, static_cast <int >(cchOutLen), NULL , NULL );
150154#endif // !_WIN32
@@ -153,9 +157,13 @@ bool convert_string_from_utf16( _In_ SQLSRV_ENCODING encoding, _In_reads_bytes_(
153157 sqlsrv_free ( newString );
154158 return false ;
155159 }
160+ char * newString2 = reinterpret_cast <char *>( sqlsrv_malloc ( rc + 1 /* NULL char*/ ));
161+ memset (newString2, ' \0 ' , rc+1 );
162+ memcpy_s (newString2, rc, newString, rc);
163+ sqlsrv_free ( newString );
156164
157- *outString = newString ;
158- newString[ cchOutLen] = ' \0 ' ; // null terminate the encoded string
165+ *outString = newString2 ;
166+ cchOutLen = rc;
159167
160168 return true ;
161169}
0 commit comments