https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d8eeb31b8aed32d079c8d1...
commit d8eeb31b8aed32d079c8d1f30d594e1d5306607e Author: Bișoc George fraizeraust99@gmail.com AuthorDate: Fri May 1 18:36:19 2020 +0200 Commit: Mark Jansen mark.jansen@reactos.org CommitDate: Sun May 3 15:35:11 2020 +0200
[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 <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; diff --git a/sdk/lib/crt/string/wcs.c b/sdk/lib/crt/string/wcs.c index 81adfdb5e46..e056bf593f6 100644 --- a/sdk/lib/crt/string/wcs.c +++ b/sdk/lib/crt/string/wcs.c @@ -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;