From d8eeb31b8aed32d079c8d1f30d594e1d5306607e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bi=C8=99oc=20George?= Date: Fri, 1 May 2020 18:36:19 +0200 Subject: [PATCH] [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. --- sdk/lib/crt/stdlib/mbstowcs.c | 31 +++++++++++++++++++++++++++---- sdk/lib/crt/string/wcs.c | 33 ++++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/sdk/lib/crt/stdlib/mbstowcs.c b/sdk/lib/crt/stdlib/mbstowcs.c index 1fe9917f332..79c0f199c93 100644 --- a/sdk/lib/crt/stdlib/mbstowcs.c +++ b/sdk/lib/crt/stdlib/mbstowcs.c @@ -1,7 +1,7 @@ #include /********************************************************************* - * _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; ilc_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(sizelocinfo; + if(!locinfo->lc_codepage) { + size_t i; + + if(!mbstr) + return strlenW(*wcstr); + + for(i=0; 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;