https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d8eeb31b8aed32d079c8d…
commit d8eeb31b8aed32d079c8d1f30d594e1d5306607e
Author: Bișoc George <fraizeraust99(a)gmail.com>
AuthorDate: Fri May 1 18:36:19 2020 +0200
Commit: Mark Jansen <mark.jansen(a)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;