From 560ac90ba059f663f5d9221c619355051d20678f Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Mon, 4 Jan 2021 13:51:22 +0100 Subject: [PATCH] msvcr100: Use LC_TIME code page when converting strftime data. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50151 Signed-off-by: Piotr Caban Signed-off-by: Alexandre Julliard --- dlls/msvcrt/time.c | 24 +++++++++++++++++++----- dlls/ucrtbase/tests/misc.c | 9 +++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/dlls/msvcrt/time.c b/dlls/msvcrt/time.c index 60b8c8575d3..327d8e086e0 100644 --- a/dlls/msvcrt/time.c +++ b/dlls/msvcrt/time.c @@ -22,6 +22,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include #include #include #include @@ -1437,6 +1438,7 @@ static size_t strftime_helper(char *str, size_t max, const char *format, #else wchar_t *s, *fmt; size_t len; + int cp; TRACE("(%p %Iu %s %p %p %p)\n", str, max, format, mstm, time_data, loc); @@ -1445,15 +1447,27 @@ static size_t strftime_helper(char *str, size_t max, const char *format, *str = 0; if (!MSVCRT_CHECK_PMT(format != NULL)) return 0; - len = _mbstowcs_l( NULL, format, 0, loc ) + 1; - if (!len || !(fmt = malloc( len*sizeof(wchar_t) ))) return 0; - _mbstowcs_l(fmt, format, len, loc); + cp = (loc ? loc->locinfo : get_locinfo())->lc_id[LC_TIME].wCodePage; + + len = MultiByteToWideChar( cp, 0, format, -1, NULL, 0 ); + if (!len) + { + *_errno() = EILSEQ; + return 0; + } + fmt = malloc( len*sizeof(wchar_t) ); + if (!fmt) return 0; + MultiByteToWideChar( cp, 0, format, -1, fmt, len ); if ((s = malloc( max*sizeof(wchar_t) ))) { len = strftime_impl( s, max, fmt, mstm, time_data, loc ); if (len) - len = _wcstombs_l( str, s, max, loc ); + { + len = WideCharToMultiByte( cp, 0, s, -1, str, max, NULL, NULL ); + if (len) len--; + else *_errno() = EILSEQ; + } free( s ); } else len = 0; @@ -1478,7 +1492,7 @@ size_t CDECL _strftime_l( char *str, size_t max, const char *format, * _Strftime (MSVCRT.@) */ size_t CDECL _Strftime(char *str, size_t max, const char *format, - const struct tm *mstm, __lc_time_data *time_data) + const struct tm *mstm, void *time_data) { return strftime_helper(str, max, format, mstm, time_data, NULL); } diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c index f15585369cb..5fcec2e2bb5 100644 --- a/dlls/ucrtbase/tests/misc.c +++ b/dlls/ucrtbase/tests/misc.c @@ -1112,6 +1112,15 @@ static void test_strftime(void) ok(ret == 8, "ret = %d\n", ret); ok(!strcmp(buf, "00:00:00"), "buf = \"%s\", expected \"%s\"\n", buf, "00:00:00"); setlocale(LC_ALL, "C"); + + if(!setlocale(LC_TIME, "Japanese_Japan.932")) { + win_skip("Japanese_Japan.932 locale not available\n"); + return; + } + ret = strftime(buf, sizeof(buf), "%a", &epoch); + ok(ret == 2 || broken(ret == 1), "ret = %d\n", ret); + ok(!strcmp(buf, "\x96\xd8"), "buf = %s, expected \"\\x96\\xd8\"\n", wine_dbgstr_an(buf, 2)); + setlocale(LC_ALL, "C"); } static LONG* get_failures_counter(HANDLE *map)