[SDK][STDLIB][STRING] Wine-sync wcsrtombs_l and _mbstowcs_l

This is a partial sync of the CRT library with wcsrtombs_l and _mbstowcs_l functions from WINE. The _wctomb_s_l implementation of WINE which is used by _wctomb_s, _wctomb_l and wctomb brings failed results of the wctomb unit testcase and at the same time it crashes the whole testcase after.

Therefore I will not address the wctomb function for the moment being.
This commit is contained in:
Bișoc George 2020-05-01 18:36:19 +02:00 committed by Mark Jansen
parent 4d8a5e921e
commit d8eeb31b8a
2 changed files with 55 additions and 9 deletions

View file

@ -1,7 +1,7 @@
#include <precomp.h>
/*********************************************************************
* _mbstowcs_l
* _mbstowcs_l (MSVCRT.@)
*/
size_t CDECL _mbstowcs_l(wchar_t *wcstr, const char *mbstr,
size_t count, _locale_t locale)
@ -9,11 +9,27 @@ size_t CDECL _mbstowcs_l(wchar_t *wcstr, const char *mbstr,
MSVCRT_pthreadlocinfo locinfo;
size_t i, size;
if(!mbstr) {
_set_errno(EINVAL);
return -1;
}
if(!locale)
locinfo = get_locinfo();
else
locinfo = ((MSVCRT__locale_t)locale)->locinfo;
if(!locinfo->lc_codepage) {
if(!wcstr)
return strlen(mbstr);
for(i=0; i<count; i++) {
wcstr[i] = (unsigned char)mbstr[i];
if(!wcstr[i]) break;
}
return i;
}
/* Ignore count parameter */
if(!wcstr)
return MultiByteToWideChar(locinfo->lc_codepage, 0, mbstr, -1, NULL, 0)-1;
@ -25,10 +41,17 @@ size_t CDECL _mbstowcs_l(wchar_t *wcstr, const char *mbstr,
size += (_isleadbyte_l((unsigned char)mbstr[size], locale) ? 2 : 1);
}
size = MultiByteToWideChar(locinfo->lc_codepage, 0,
mbstr, size, wcstr, count);
if(size) {
size = MultiByteToWideChar(locinfo->lc_codepage, 0,
mbstr, size, wcstr, count);
if(!size) {
if(count) wcstr[0] = '\0';
_set_errno(EILSEQ);
return -1;
}
}
if(size<count && wcstr)
if(size<count)
wcstr[size] = '\0';
return size;

View file

@ -257,7 +257,8 @@ INT CDECL wctomb( char *dst, wchar_t ch )
/*********************************************************************
* wcsrtombs_l (INTERNAL)
*/
static size_t CDECL wcsrtombs_l(char *mbstr, const wchar_t **wcstr, size_t count, _locale_t locale)
static size_t CDECL wcsrtombs_l(char *mbstr, const wchar_t **wcstr,
size_t count, _locale_t locale)
{
MSVCRT_pthreadlocinfo locinfo;
size_t tmp = 0;
@ -268,12 +269,32 @@ static size_t CDECL wcsrtombs_l(char *mbstr, const wchar_t **wcstr, size_t count
else
locinfo = ((MSVCRT__locale_t)locale)->locinfo;
if(!locinfo->lc_codepage) {
size_t i;
if(!mbstr)
return strlenW(*wcstr);
for(i=0; i<count; i++) {
if((*wcstr)[i] > 255) {
_set_errno(EILSEQ);
return -1;
}
mbstr[i] = (*wcstr)[i];
if(!(*wcstr)[i]) break;
}
return i;
}
if(!mbstr) {
tmp = WideCharToMultiByte(locinfo->lc_codepage, WC_NO_BEST_FIT_CHARS,
*wcstr, -1, NULL, 0, NULL, &used_default)-1;
if(used_default)
*wcstr, -1, NULL, 0, NULL, &used_default);
if(!tmp || used_default) {
_set_errno(EILSEQ);
return -1;
return tmp;
}
return tmp-1;
}
while(**wcstr) {
@ -282,8 +303,10 @@ static size_t CDECL wcsrtombs_l(char *mbstr, const wchar_t **wcstr, size_t count
size = WideCharToMultiByte(locinfo->lc_codepage, WC_NO_BEST_FIT_CHARS,
*wcstr, 1, buf, 3, NULL, &used_default);
if(used_default)
if(!size || used_default) {
_set_errno(EILSEQ);
return -1;
}
if(tmp+size > count)
return tmp;