_mbctolower_l - converts multibyte uppercase character to lowercase character, by using specified locale that's passed in.
More information about these methods are available at: https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/mbctolower...
More information about application crash: https://bugs.winehq.org/show_bug.cgi?id=45273
-- v7: msvcrt: Fix error handling in _mbslwr_s_l. msvcrt: Fix error handling in _mbsupr_s_l. msvcrt: Add support for multi-byte characters in _mbctoupper_l. msvcrt: Add support for multi-byte characters in _mbctolower_l. msvcrt: Fix mbcasemap initialization. msvcrt: Add _mbsupr_s_l partial implementation. msvcrt: Add _mbslwr_s_l partial implementation. msvcrt: Add _mbctoupper_l partial implementation. msvcrt: Add _mbctolower_l partial implementation.
From: Bartosz Kosiorek gang65@poczta.onet.pl
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45273 --- dlls/msvcr100/msvcr100.spec | 2 +- dlls/msvcr110/msvcr110.spec | 2 +- dlls/msvcr120/msvcr120.spec | 2 +- dlls/msvcr80/msvcr80.spec | 2 +- dlls/msvcr90/msvcr90.spec | 2 +- dlls/msvcrt/mbcs.c | 16 ++++++++++++---- dlls/msvcrt/msvcrt.spec | 2 +- dlls/ucrtbase/ucrtbase.spec | 2 +- 8 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index c0bbbc5b86d..648092da5a4 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -1088,7 +1088,7 @@ @ cdecl _mbctokata(long) @ stub _mbctokata_l @ cdecl _mbctolower(long) -@ stub _mbctolower_l +@ cdecl _mbctolower_l(long ptr) @ cdecl _mbctombb(long) @ stub _mbctombb_l @ cdecl _mbctoupper(long) diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index a272ae98a1c..03d96e91d86 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -1445,7 +1445,7 @@ @ cdecl _mbctokata(long) @ stub _mbctokata_l @ cdecl _mbctolower(long) -@ stub _mbctolower_l +@ cdecl _mbctolower_l(long ptr) @ cdecl _mbctombb(long) @ stub _mbctombb_l @ cdecl _mbctoupper(long) diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index d16316e7e05..8eb007f3945 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -1456,7 +1456,7 @@ @ cdecl _mbctokata(long) @ stub _mbctokata_l @ cdecl _mbctolower(long) -@ stub _mbctolower_l +@ cdecl _mbctolower_l(long ptr) @ cdecl _mbctombb(long) @ stub _mbctombb_l @ cdecl _mbctoupper(long) diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 371d17ecc21..b0c81808198 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -760,7 +760,7 @@ @ cdecl _mbctokata(long) @ stub _mbctokata_l @ cdecl _mbctolower(long) -@ stub _mbctolower_l +@ cdecl _mbctolower_l(long ptr) @ cdecl _mbctombb(long) @ stub _mbctombb_l @ cdecl _mbctoupper(long) diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index dc9d4ae097b..f0b6e43b33c 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -738,7 +738,7 @@ @ cdecl _mbctokata(long) @ stub _mbctokata_l @ cdecl _mbctolower(long) -@ stub _mbctolower_l +@ cdecl _mbctolower_l(long ptr) @ cdecl _mbctombb(long) @ stub _mbctombb_l @ cdecl _mbctoupper(long) diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c index dc9abca1b44..3230a9fc084 100644 --- a/dlls/msvcrt/mbcs.c +++ b/dlls/msvcrt/mbcs.c @@ -447,16 +447,24 @@ unsigned int CDECL _mbsnextc(const unsigned char* str) }
/********************************************************************* - * _mbctolower(MSVCRT.@) + * _mbctolower_l(MSVCRT.@) */ -unsigned int CDECL _mbctolower(unsigned int c) +unsigned int CDECL _mbctolower_l(unsigned int c, _locale_t locale) { - if (_ismbblead(c)) + if (_ismbblead_l(c, locale)) { FIXME("Handle MBC chars\n"); return c; } - return _tolower_l(c, NULL); /* ASCII CP or SB char */ + return _tolower_l(c, locale); /* ASCII CP or SB char */ +} + +/********************************************************************* + * _mbctolower(MSVCRT.@) + */ +unsigned int CDECL _mbctolower(unsigned int c) +{ + return _mbctolower_l(c, NULL); }
/********************************************************************* diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 3aab3600e1d..4f72b58b4d7 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -705,7 +705,7 @@ @ cdecl _mbctokata(long) # stub _mbctokata_l(long ptr) @ cdecl _mbctolower(long) -# stub _mbctolower_l(long ptr) +@ cdecl _mbctolower_l(long ptr) @ cdecl _mbctombb(long) # stub _mbctombb_l(long ptr) @ cdecl _mbctoupper(long) diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index a4acf724d2f..f85309a7b42 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -603,7 +603,7 @@ @ cdecl _mbctokata(long) @ stub _mbctokata_l @ cdecl _mbctolower(long) -@ stub _mbctolower_l +@ cdecl _mbctolower_l(long ptr) @ cdecl _mbctombb(long) @ stub _mbctombb_l @ cdecl _mbctoupper(long)
From: Bartosz Kosiorek gang65@poczta.onet.pl
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45273 --- dlls/msvcr100/msvcr100.spec | 2 +- dlls/msvcr110/msvcr110.spec | 2 +- dlls/msvcr120/msvcr120.spec | 2 +- dlls/msvcr80/msvcr80.spec | 2 +- dlls/msvcr90/msvcr90.spec | 2 +- dlls/msvcrt/mbcs.c | 16 ++++++++++++---- dlls/msvcrt/msvcrt.spec | 2 +- dlls/ucrtbase/ucrtbase.spec | 2 +- 8 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index 648092da5a4..b3fd1af1ecb 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -1092,7 +1092,7 @@ @ cdecl _mbctombb(long) @ stub _mbctombb_l @ cdecl _mbctoupper(long) -@ stub _mbctoupper_l +@ cdecl _mbctoupper_l(long ptr) @ extern _mbctype MSVCRT_mbctype @ stub _mblen_l @ cdecl _mbsbtype(str long) diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index 03d96e91d86..28e5e047090 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -1449,7 +1449,7 @@ @ cdecl _mbctombb(long) @ stub _mbctombb_l @ cdecl _mbctoupper(long) -@ stub _mbctoupper_l +@ cdecl _mbctoupper_l(long ptr) @ extern _mbctype MSVCRT_mbctype @ stub _mblen_l @ cdecl _mbsbtype(str long) diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index 8eb007f3945..ae4874a7116 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -1460,7 +1460,7 @@ @ cdecl _mbctombb(long) @ stub _mbctombb_l @ cdecl _mbctoupper(long) -@ stub _mbctoupper_l +@ cdecl _mbctoupper_l(long ptr) @ extern _mbctype MSVCRT_mbctype @ stub _mblen_l @ cdecl _mbsbtype(str long) diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index b0c81808198..7b484d8be26 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -764,7 +764,7 @@ @ cdecl _mbctombb(long) @ stub _mbctombb_l @ cdecl _mbctoupper(long) -@ stub _mbctoupper_l +@ cdecl _mbctoupper_l(long ptr) @ extern _mbctype MSVCRT_mbctype @ stub _mblen_l @ cdecl _mbsbtype(str long) diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index f0b6e43b33c..ab1ef139f9a 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -742,7 +742,7 @@ @ cdecl _mbctombb(long) @ stub _mbctombb_l @ cdecl _mbctoupper(long) -@ stub _mbctoupper_l +@ cdecl _mbctoupper_l(long ptr) @ extern _mbctype MSVCRT_mbctype @ stub _mblen_l @ cdecl _mbsbtype(str long) diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c index 3230a9fc084..7073fee5bfd 100644 --- a/dlls/msvcrt/mbcs.c +++ b/dlls/msvcrt/mbcs.c @@ -468,16 +468,24 @@ unsigned int CDECL _mbctolower(unsigned int c) }
/********************************************************************* - * _mbctoupper(MSVCRT.@) + * _mbctoupper_l(MSVCRT.@) */ -unsigned int CDECL _mbctoupper(unsigned int c) +unsigned int CDECL _mbctoupper_l(unsigned int c, _locale_t locale) { - if (_ismbblead(c)) + if (_ismbblead_l(c, locale)) { FIXME("Handle MBC chars\n"); return c; } - return _toupper_l(c, NULL); /* ASCII CP or SB char */ + return _toupper_l(c, locale); /* ASCII CP or SB char */ +} + +/********************************************************************* + * _mbctoupper(MSVCRT.@) + */ +unsigned int CDECL _mbctoupper(unsigned int c) +{ + return _mbctoupper_l(c, NULL); }
/********************************************************************* diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 4f72b58b4d7..e1b14ff2a7e 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -709,7 +709,7 @@ @ cdecl _mbctombb(long) # stub _mbctombb_l(long ptr) @ cdecl _mbctoupper(long) -# stub _mbctoupper_l(long ptr) +@ cdecl _mbctoupper_l(long ptr) @ extern _mbctype MSVCRT_mbctype # stub _mblen_l(str long ptr) @ cdecl _mbsbtype(str long) diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index f85309a7b42..c803799f4cd 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -607,7 +607,7 @@ @ cdecl _mbctombb(long) @ stub _mbctombb_l @ cdecl _mbctoupper(long) -@ stub _mbctoupper_l +@ cdecl _mbctoupper_l(long ptr) @ stub _mblen_l @ cdecl _mbsbtype(str long) @ stub _mbsbtype_l
From: Bartosz Kosiorek gang65@poczta.onet.pl
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45273 --- dlls/msvcr100/msvcr100.spec | 2 +- dlls/msvcr110/msvcr110.spec | 2 +- dlls/msvcr120/msvcr120.spec | 2 +- dlls/msvcr80/msvcr80.spec | 2 +- dlls/msvcr90/msvcr90.spec | 2 +- dlls/msvcrt/mbcs.c | 22 +++++++++++++++++----- dlls/msvcrt/msvcrt.spec | 2 +- dlls/ucrtbase/ucrtbase.spec | 2 +- 8 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index b3fd1af1ecb..90accd39722 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -1122,7 +1122,7 @@ @ cdecl _mbslwr(str) @ stub _mbslwr_l @ cdecl _mbslwr_s(str long) -@ stub _mbslwr_s_l +@ cdecl _mbslwr_s_l(str long ptr) @ cdecl _mbsnbcat(str str long) @ stub _mbsnbcat_l @ cdecl _mbsnbcat_s(str long ptr long) diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index 28e5e047090..5ca3156ab0b 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -1479,7 +1479,7 @@ @ cdecl _mbslwr(str) @ stub _mbslwr_l @ cdecl _mbslwr_s(str long) -@ stub _mbslwr_s_l +@ cdecl _mbslwr_s_l(str long ptr) @ cdecl _mbsnbcat(str str long) @ stub _mbsnbcat_l @ cdecl _mbsnbcat_s(str long ptr long) diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index ae4874a7116..a514febaa21 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -1490,7 +1490,7 @@ @ cdecl _mbslwr(str) @ stub _mbslwr_l @ cdecl _mbslwr_s(str long) -@ stub _mbslwr_s_l +@ cdecl _mbslwr_s_l(str long ptr) @ cdecl _mbsnbcat(str str long) @ stub _mbsnbcat_l @ cdecl _mbsnbcat_s(str long ptr long) diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 7b484d8be26..9c2498781f0 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -794,7 +794,7 @@ @ cdecl _mbslwr(str) @ stub _mbslwr_l @ cdecl _mbslwr_s(str long) -@ stub _mbslwr_s_l +@ cdecl _mbslwr_s_l(str long ptr) @ cdecl _mbsnbcat(str str long) @ stub _mbsnbcat_l @ cdecl _mbsnbcat_s(str long ptr long) diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index ab1ef139f9a..ae1add4cb5f 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -772,7 +772,7 @@ @ cdecl _mbslwr(str) @ stub _mbslwr_l @ cdecl _mbslwr_s(str long) -@ stub _mbslwr_s_l +@ cdecl _mbslwr_s_l(str long ptr) @ cdecl _mbsnbcat(str str long) @ stub _mbsnbcat_l @ cdecl _mbsnbcat_s(str long ptr long) diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c index 7073fee5bfd..b5b4309db54 100644 --- a/dlls/msvcrt/mbcs.c +++ b/dlls/msvcrt/mbcs.c @@ -2065,11 +2065,10 @@ unsigned char* CDECL _mbslwr(unsigned char* s) return ret; }
- /********************************************************************* - * _mbslwr_s(MSVCRT.@) + * _mbslwr_s_l(MSVCRT.@) */ -int CDECL _mbslwr_s(unsigned char* s, size_t len) +int CDECL _mbslwr_s_l(unsigned char* s, size_t len, _locale_t locale) { if (!s && !len) { @@ -2080,12 +2079,13 @@ int CDECL _mbslwr_s(unsigned char* s, size_t len) *_errno() = EINVAL; return EINVAL; } + if (get_mbcinfo()->ismbcodepage) { unsigned int c; for ( ; *s && len > 0; len--) { - c = _mbctolower(_mbsnextc(s)); + c = _mbctolower_l(_mbsnextc_l(s, locale), locale); /* Note that I assume that the size of the character is unchanged */ if (c > 255) { @@ -2095,7 +2095,12 @@ int CDECL _mbslwr_s(unsigned char* s, size_t len) *s++=c; } } - else for ( ; *s && len > 0; s++, len--) *s = _tolower_l(*s, NULL); + else + { + for ( ; *s && len > 0; s++, len--) + *s = _tolower_l(*s, locale); + } + if (*s) { *s = '\0'; @@ -2105,6 +2110,13 @@ int CDECL _mbslwr_s(unsigned char* s, size_t len) return 0; }
+/********************************************************************* + * _mbslwr_s(MSVCRT.@) + */ +int CDECL _mbslwr_s(unsigned char* str, size_t len) +{ + return _mbslwr_s_l(str, len, NULL); +}
/********************************************************************* * _mbsupr(MSVCRT.@) diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index e1b14ff2a7e..07b15ae2d98 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -743,7 +743,7 @@ @ cdecl _mbslwr(str) # stub _mbslwr_l(str ptr) @ cdecl _mbslwr_s(str long) -# stub _mbslwr_s_l(str long ptr) +@ cdecl _mbslwr_s_l(str long ptr) @ cdecl _mbsnbcat(str str long) # stub _mbsnbcat_l(str str long ptr) @ cdecl _mbsnbcat_s(str long ptr long) diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index c803799f4cd..9d22ff00f30 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -637,7 +637,7 @@ @ cdecl _mbslwr(str) @ stub _mbslwr_l @ cdecl _mbslwr_s(str long) -@ stub _mbslwr_s_l +@ cdecl _mbslwr_s_l(str long ptr) @ cdecl _mbsnbcat(str str long) @ stub _mbsnbcat_l @ cdecl _mbsnbcat_s(str long ptr long)
From: Piotr Caban piotr@codeweavers.com
--- dlls/msvcrt/mbcs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c index 23d16ee925d..f1d82b5e268 100644 --- a/dlls/msvcrt/mbcs.c +++ b/dlls/msvcrt/mbcs.c @@ -365,7 +365,7 @@ threadmbcinfo* create_mbcinfo(int cp, LCID lcid, threadmbcinfo *old_mbcinfo) { if(!(mbcinfo->mbctype[i + 1] & _M1)) { - if(mbcinfo->mbctype[i] & (C1_UPPER|C1_LOWER)) + if(mbcinfo->mbctype[i + 1] & (_SBUP | _SBLOW)) mbcinfo->mbcasemap[i] = bufA[charcount]; charcount++; }
From: Bartosz Kosiorek gang65@poczta.onet.pl
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45273 --- dlls/msvcr100/msvcr100.spec | 2 +- dlls/msvcr110/msvcr110.spec | 2 +- dlls/msvcr120/msvcr120.spec | 2 +- dlls/msvcr80/msvcr80.spec | 2 +- dlls/msvcr90/msvcr90.spec | 2 +- dlls/msvcrt/mbcs.c | 23 ++++++++++++++++++----- dlls/msvcrt/msvcrt.spec | 2 +- dlls/ucrtbase/ucrtbase.spec | 2 +- 8 files changed, 25 insertions(+), 12 deletions(-)
diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index 90accd39722..b051cf6a77f 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -1202,7 +1202,7 @@ @ cdecl _mbsupr(str) @ stub _mbsupr_l @ cdecl _mbsupr_s(str long) -@ stub _mbsupr_s_l +@ cdecl _mbsupr_s_l(str long ptr) @ cdecl _mbtowc_l(ptr str long ptr) @ cdecl _memccpy(ptr ptr long long) @ cdecl _memicmp(str str long) diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index 5ca3156ab0b..593df178536 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -1559,7 +1559,7 @@ @ cdecl _mbsupr(str) @ stub _mbsupr_l @ cdecl _mbsupr_s(str long) -@ stub _mbsupr_s_l +@ cdecl _mbsupr_s_l(str long ptr) @ cdecl _mbtowc_l(ptr str long ptr) @ cdecl _memccpy(ptr ptr long long) @ cdecl _memicmp(str str long) diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index a514febaa21..cd92da9a8d7 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -1570,7 +1570,7 @@ @ cdecl _mbsupr(str) @ stub _mbsupr_l @ cdecl _mbsupr_s(str long) -@ stub _mbsupr_s_l +@ cdecl _mbsupr_s_l(str long ptr) @ cdecl _mbtowc_l(ptr str long ptr) @ cdecl _memccpy(ptr ptr long long) @ cdecl _memicmp(str str long) diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 9c2498781f0..de0da8e26e9 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -874,7 +874,7 @@ @ cdecl _mbsupr(str) @ stub _mbsupr_l @ cdecl _mbsupr_s(str long) -@ stub _mbsupr_s_l +@ cdecl _mbsupr_s_l(str long ptr) @ cdecl _mbtowc_l(ptr str long ptr) @ cdecl _memccpy(ptr ptr long long) @ cdecl _memicmp(str str long) diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index ae1add4cb5f..d5f94a65f78 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -852,7 +852,7 @@ @ cdecl _mbsupr(str) @ stub _mbsupr_l @ cdecl _mbsupr_s(str long) -@ stub _mbsupr_s_l +@ cdecl _mbsupr_s_l(str long ptr) @ cdecl _mbtowc_l(ptr str long ptr) @ cdecl _memccpy(ptr ptr long long) @ cdecl _memicmp(str str long) diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c index b5b4309db54..23d16ee925d 100644 --- a/dlls/msvcrt/mbcs.c +++ b/dlls/msvcrt/mbcs.c @@ -2145,11 +2145,10 @@ unsigned char* CDECL _mbsupr(unsigned char* s) return ret; }
- /********************************************************************* - * _mbsupr_s(MSVCRT.@) + * _mbsupr_s_l(MSVCRT.@) */ -int CDECL _mbsupr_s(unsigned char* s, size_t len) +int CDECL _mbsupr_s_l(unsigned char* s, size_t len, _locale_t locale) { if (!s && !len) { @@ -2160,12 +2159,13 @@ int CDECL _mbsupr_s(unsigned char* s, size_t len) *_errno() = EINVAL; return EINVAL; } + if (get_mbcinfo()->ismbcodepage) { unsigned int c; for ( ; *s && len > 0; len--) { - c = _mbctoupper(_mbsnextc(s)); + c = _mbctoupper_l(_mbsnextc_l(s, locale), locale); /* Note that I assume that the size of the character is unchanged */ if (c > 255) { @@ -2175,7 +2175,12 @@ int CDECL _mbsupr_s(unsigned char* s, size_t len) *s++=c; } } - else for ( ; *s && len > 0; s++, len--) *s = _toupper_l(*s, NULL); + else + { + for ( ; *s && len > 0; s++, len--) + *s = _toupper_l(*s, locale); + } + if (*s) { *s = '\0'; @@ -2185,6 +2190,14 @@ int CDECL _mbsupr_s(unsigned char* s, size_t len) return 0; }
+/********************************************************************* + * _mbsupr_s(MSVCRT.@) + */ +int CDECL _mbsupr_s(unsigned char* s, size_t len) +{ + return _mbsupr_s_l(s, len, NULL); +} + /********************************************************************* * _mbsspn_l (MSVCRT.@) */ diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 07b15ae2d98..dab9ae87b5b 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -823,7 +823,7 @@ @ cdecl _mbsupr(str) # stub _mbsupr_l(str ptr) @ cdecl _mbsupr_s(str long) -# stub _mbsupr_s_l(str long ptr) +@ cdecl _mbsupr_s_l(str long ptr) @ cdecl _mbtowc_l(ptr str long ptr) @ cdecl _memccpy(ptr ptr long long) @ cdecl _memicmp(str str long) diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index 9d22ff00f30..3e3fd8d6965 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -717,7 +717,7 @@ @ cdecl _mbsupr(str) @ stub _mbsupr_l @ cdecl _mbsupr_s(str long) -@ stub _mbsupr_s_l +@ cdecl _mbsupr_s_l(str long ptr) @ cdecl _mbtowc_l(ptr str long ptr) @ cdecl _memccpy(ptr ptr long long) @ cdecl _memicmp(str str long)
From: Piotr Caban piotr@codeweavers.com
--- dlls/msvcrt/mbcs.c | 30 ++++++++++++++++++++++++++---- dlls/msvcrt/tests/string.c | 9 +++++++++ 2 files changed, 35 insertions(+), 4 deletions(-)
diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c index f1d82b5e268..1c747ac1573 100644 --- a/dlls/msvcrt/mbcs.c +++ b/dlls/msvcrt/mbcs.c @@ -451,12 +451,34 @@ unsigned int CDECL _mbsnextc(const unsigned char* str) */ unsigned int CDECL _mbctolower_l(unsigned int c, _locale_t locale) { - if (_ismbblead_l(c, locale)) + unsigned char str[2], ret[2]; + pthreadmbcinfo mbcinfo; + + if(!locale) + mbcinfo = get_mbcinfo(); + else + mbcinfo = locale->mbcinfo; + + if (c > 0xff) { - FIXME("Handle MBC chars\n"); - return c; + if (!_ismbblead_l((c >> 8) & 0xff, locale)) + return c; + + str[0] = c >> 8; + str[1] = c; + switch(__crtLCMapStringA(mbcinfo->mblcid, LCMAP_LOWERCASE, + (char*)str, 2, (char*)ret, 2, mbcinfo->mbcodepage, 0)) + { + case 0: + return c; + case 1: + return ret[0]; + default: + return ret[1] + (ret[0] << 8); + } } - return _tolower_l(c, locale); /* ASCII CP or SB char */ + + return mbcinfo->mbctype[c + 1] & _SBUP ? mbcinfo->mbcasemap[c] : c; }
/********************************************************************* diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index 4e525193ced..14c0adf0efc 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -2896,6 +2896,7 @@ static void test__mbslwr_s(void) { errno_t ret; unsigned char buffer[20]; + int cp = _getmbcp();
if (!p_mbslwr_s) { @@ -2946,6 +2947,14 @@ static void test__mbslwr_s(void) ok(!memcmp(buffer, "abcdefgh\0IJKLMNOP", sizeof("abcdefgh\0IJKLMNOP")), "Expected the output buffer to be "abcdefgh\0IJKLMNOP", got "%s"\n", buffer); + + _setmbcp(936); + memcpy(buffer, "\xa2\xf1\xa2\xf2Q", sizeof("\xa2\xf1\xa2\xf2Q")); + ret = p_mbslwr_s(buffer, sizeof(buffer)); + ok(ret == 0, "Expected _mbsupr_s to return 0, got %d\n", ret); + ok(!memcmp(buffer, "\xa2\xa1\xa2\xa2q", sizeof("\xa2\xa1\xa2\xa2q")), + "got %s\n", debugstr_a((char*)buffer)); + _setmbcp(cp); }
static void test__mbstok(void)
From: Piotr Caban piotr@codeweavers.com
--- dlls/msvcrt/mbcs.c | 30 ++++++++++++++++++++++++++---- dlls/msvcrt/tests/string.c | 8 ++++++++ 2 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c index 1c747ac1573..d098f5b23f4 100644 --- a/dlls/msvcrt/mbcs.c +++ b/dlls/msvcrt/mbcs.c @@ -494,12 +494,34 @@ unsigned int CDECL _mbctolower(unsigned int c) */ unsigned int CDECL _mbctoupper_l(unsigned int c, _locale_t locale) { - if (_ismbblead_l(c, locale)) + unsigned char str[2], ret[2]; + pthreadmbcinfo mbcinfo; + + if(!locale) + mbcinfo = get_mbcinfo(); + else + mbcinfo = locale->mbcinfo; + + if (c > 0xff) { - FIXME("Handle MBC chars\n"); - return c; + if (!_ismbblead_l((c >> 8) & 0xff, locale)) + return c; + + str[0] = c >> 8; + str[1] = c; + switch(__crtLCMapStringA(mbcinfo->mblcid, LCMAP_UPPERCASE, + (char*)str, 2, (char*)ret, 2, mbcinfo->mbcodepage, 0)) + { + case 0: + return c; + case 1: + return ret[0]; + default: + return ret[1] + (ret[0] << 8); + } } - return _toupper_l(c, locale); /* ASCII CP or SB char */ + + return mbcinfo->mbctype[c + 1] & _SBLOW ? mbcinfo->mbcasemap[c] : c; }
/********************************************************************* diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index 14c0adf0efc..905607e416d 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -2839,6 +2839,7 @@ static void test__mbsupr_s(void) { errno_t ret; unsigned char buffer[20]; + int cp = _getmbcp();
if (!p_mbsupr_s) { @@ -2890,6 +2891,13 @@ static void test__mbsupr_s(void) "Expected the output buffer to be "ABCDEFGH\0ijklmnop", got "%s"\n", buffer);
+ _setmbcp(936); + memcpy(buffer, "\xa2\xa1\xa2\xa2q", sizeof("\xa2\xa1\xa2\xa2q")); + ret = p_mbsupr_s(buffer, sizeof(buffer)); + ok(ret == 0, "Expected _mbsupr_s to return 0, got %d\n", ret); + ok(!memcmp(buffer, "\xa2\xf1\xa2\xf2Q", sizeof("\xa2\xf1\xa2\xf2Q")), + "got %s\n", debugstr_a((char*)buffer)); + _setmbcp(cp); }
static void test__mbslwr_s(void)
From: Piotr Caban piotr@codeweavers.com
--- dlls/msvcrt/mbcs.c | 15 ++++++--------- dlls/msvcrt/tests/string.c | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c index d098f5b23f4..e275991343d 100644 --- a/dlls/msvcrt/mbcs.c +++ b/dlls/msvcrt/mbcs.c @@ -2194,15 +2194,12 @@ unsigned char* CDECL _mbsupr(unsigned char* s) */ int CDECL _mbsupr_s_l(unsigned char* s, size_t len, _locale_t locale) { + unsigned char *p = s; + if (!s && !len) - { return 0; - } - else if (!s || !len) - { - *_errno() = EINVAL; + if (!MSVCRT_CHECK_PMT(s && len)) return EINVAL; - }
if (get_mbcinfo()->ismbcodepage) { @@ -2225,12 +2222,12 @@ int CDECL _mbsupr_s_l(unsigned char* s, size_t len, _locale_t locale) *s = _toupper_l(*s, locale); }
- if (*s) + if (!MSVCRT_CHECK_PMT(len)) { - *s = '\0'; - *_errno() = EINVAL; + *p = 0; return EINVAL; } + *s = 0; return 0; }
diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index 905607e416d..7a3d4b636b3 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -2879,7 +2879,7 @@ static void test__mbsupr_s(void)
memcpy(buffer, "abcdefgh", sizeof("abcdefgh")); errno = EBADF; - ret = p_mbsupr_s(buffer, 4); + ret = p_mbsupr_s(buffer, sizeof("abcdefgh") - 1); ok(ret == EINVAL, "Expected _mbsupr_s to return EINVAL, got %d\n", ret); ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
From: Piotr Caban piotr@codeweavers.com
--- dlls/msvcrt/mbcs.c | 15 ++++++--------- dlls/msvcrt/tests/string.c | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c index e275991343d..41a46f40495 100644 --- a/dlls/msvcrt/mbcs.c +++ b/dlls/msvcrt/mbcs.c @@ -2114,15 +2114,12 @@ unsigned char* CDECL _mbslwr(unsigned char* s) */ int CDECL _mbslwr_s_l(unsigned char* s, size_t len, _locale_t locale) { + unsigned char *p = s; + if (!s && !len) - { return 0; - } - else if (!s || !len) - { - *_errno() = EINVAL; + if (!MSVCRT_CHECK_PMT(s && len)) return EINVAL; - }
if (get_mbcinfo()->ismbcodepage) { @@ -2145,12 +2142,12 @@ int CDECL _mbslwr_s_l(unsigned char* s, size_t len, _locale_t locale) *s = _tolower_l(*s, locale); }
- if (*s) + if (!MSVCRT_CHECK_PMT(len)) { - *s = '\0'; - *_errno() = EINVAL; + *p = 0; return EINVAL; } + *s = 0; return 0; }
diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index 7a3d4b636b3..df3f5fceef8 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -2944,7 +2944,7 @@ static void test__mbslwr_s(void)
memcpy(buffer, "ABCDEFGH", sizeof("ABCDEFGH")); errno = EBADF; - ret = p_mbslwr_s(buffer, 4); + ret = p_mbslwr_s(buffer, sizeof("ABCDEFGH") - 1); ok(ret == EINVAL, "Expected _mbslwr_s to return EINVAL, got %d\n", ret); ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=125134
Your paranoid android.
=== debian11 (32 bit report) ===
ddraw: ddraw7.c:15663: Test failed: Expected unsynchronised map for flags 0x1000. ddraw7.c:15663: Test failed: Expected unsynchronised map for flags 0x3000.
=== debian11 (build log) ===
Use of uninitialized value $Flaky in addition (+) at /home/testbot/lib/WineTestBot/LogUtils.pm line 720, <$LogFile> line 24740. Use of uninitialized value $Flaky in addition (+) at /home/testbot/lib/WineTestBot/LogUtils.pm line 720, <$LogFile> line 24740. Use of uninitialized value $Flaky in addition (+) at /home/testbot/lib/WineTestBot/LogUtils.pm line 720, <$LogFile> line 24740.
I've pushed a modified version of your patches. I've also added some patches to fix errors found in existing code. Here's a short description of changes: - add missing msvcrt exports - add support for multi-byte characters in _mbctolower_l and _mbctoupper_l - fix error handling in _mbslwr_l and _mbsupr_l (this was done in your patches differently)
I hope it looks good for you.
This merge request was approved by Piotr Caban.
Bartosz Kosiorek (@gang65) commented about dlls/msvcrt/tests/string.c:
ok(ret == EINVAL, "Expected _mbsupr_s to return EINVAL, got %d\n", ret); ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
- // If string length is less than declared buffer length,
- memcpy(buffer, "ABCDEFGH", sizeof("ABCDEFGH"));
- errno = EBADF;
- ret = p_mbsupr_s(buffer, 2);
- ok(ret == EINVAL, "Expected p_mbsupr_s to return EINVAL, got %d\n", ret);
- ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
The method should throw an EINVAL in case:
If numberOfElements is less than the length of the string, the functions also return EINVAL and set errno to EINVAL.
More information is available at: https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strlwr-s-s...
In this change I would like to implement that behaviour.
On Wed Oct 19 13:58:40 2022 +0000, Bartosz Kosiorek wrote:
These methods should throw an EINVAL in case:
If numberOfElements is less than the length of the string, the
functions also return EINVAL and set errno to EINVAL. More information is available at: https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strlwr-s-s... In this change I would like to implement that behaviour (I checked it under Windows/native DLLs) and it is implemented in that way..
There already is a test that cover this case: ``` memcpy(buffer, "abcdefgh", sizeof("abcdefgh")); errno = EBADF; ret = p_mbsupr_s(buffer, sizeof("abcdefgh") - 1); ok(ret == EINVAL, "Expected _mbsupr_s to return EINVAL, got %d\n", ret); ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); ```
or am I missing something? The function uses MSVCRT_CHECK_PMT macro to handle the error (it will return EINVAL in msvcrt and throw exception in newer versions).
On Wed Oct 19 14:00:21 2022 +0000, Piotr Caban wrote:
There already is a test that cover this case:
memcpy(buffer, "abcdefgh", sizeof("abcdefgh")); errno = EBADF; ret = p_mbsupr_s(buffer, sizeof("abcdefgh") - 1); ok(ret == EINVAL, "Expected _mbsupr_s to return EINVAL, got %d\n", ret); ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
or am I missing something? The function uses MSVCRT_CHECK_PMT macro to handle the error (it will return EINVAL in msvcrt and throw exception in newer versions).
yes, true. Thanks for explanation.