This patch series fixes test failures for C95 conversion functions with crtdll.dll and msvcrt10.dll.
- Kirill Makurin
From cb7b0acd1b3fd8cf7abca9298cd7de4c1398f510 Mon Sep 17 00:00:00 2001 From: Kirill Makurin <[email protected]> Date: Sat, 6 Sep 2025 17:49:41 +0900 Subject: [PATCH 1/4] tests: use explicit code pages instead of ACP in calls to setlocale setlocale in old CRTs does not support ACP/OCP strings to specify code page in the locale string. This results in test failures. To avoid this, explicitly specify code page in locale strings passed to setlocale. Signed-off-by: Kirill Makurin <[email protected]> --- mingw-w64-crt/testcases/t_btowc.c | 4 ++-- mingw-w64-crt/testcases/t_mbrlen.c | 4 ++-- mingw-w64-crt/testcases/t_mbrtowc.c | 2 +- mingw-w64-crt/testcases/t_mbsrtowcs.c | 4 ++-- mingw-w64-crt/testcases/t_wcrtomb.c | 2 +- mingw-w64-crt/testcases/t_wcsrtombs.c | 4 ++-- mingw-w64-crt/testcases/t_wctob.c | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/mingw-w64-crt/testcases/t_btowc.c b/mingw-w64-crt/testcases/t_btowc.c index 7adcedd08..8137a8274 100644 --- a/mingw-w64-crt/testcases/t_btowc.c +++ b/mingw-w64-crt/testcases/t_btowc.c @@ -36,7 +36,7 @@ int main (void) { /** * Test SBCS code page */ - assert (setlocale (LC_ALL, "English_United States.ACP") != NULL); + assert (setlocale (LC_ALL, "English_United States.1252") != NULL); assert (MB_CUR_MAX == 1); /** @@ -56,7 +56,7 @@ int main (void) { /** * Test DBCS code page */ - assert (setlocale (LC_ALL, "Japanese_Japan.ACP") != NULL); + assert (setlocale (LC_ALL, "Japanese_Japan.932") != NULL); assert (MB_CUR_MAX == 2); /** diff --git a/mingw-w64-crt/testcases/t_mbrlen.c b/mingw-w64-crt/testcases/t_mbrlen.c index b66e277c0..62051d6ee 100644 --- a/mingw-w64-crt/testcases/t_mbrlen.c +++ b/mingw-w64-crt/testcases/t_mbrlen.c @@ -73,7 +73,7 @@ int main (void) { /** * Test SBCS code page */ - assert (setlocale (LC_ALL, "English_United States.ACP") != NULL); + assert (setlocale (LC_ALL, "English_United States.1252") != NULL); assert (MB_CUR_MAX == 1); /** @@ -92,7 +92,7 @@ int main (void) { /** * Test DBCS code page */ - assert (setlocale (LC_ALL, "Japanese_Japan.ACP") != NULL); + assert (setlocale (LC_ALL, "Japanese_Japan.932") != NULL); assert (MB_CUR_MAX == 2); /** diff --git a/mingw-w64-crt/testcases/t_mbrtowc.c b/mingw-w64-crt/testcases/t_mbrtowc.c index e37986d3d..0e58946c1 100644 --- a/mingw-w64-crt/testcases/t_mbrtowc.c +++ b/mingw-w64-crt/testcases/t_mbrtowc.c @@ -104,7 +104,7 @@ int main (void) { /** * Test DBCS code page */ - assert (setlocale (LC_ALL, "Japanese_Japan.ACP") != NULL); + assert (setlocale (LC_ALL, "Japanese_Japan.932") != NULL); assert (MB_CUR_MAX == 2); /** diff --git a/mingw-w64-crt/testcases/t_mbsrtowcs.c b/mingw-w64-crt/testcases/t_mbsrtowcs.c index 9cfd9c968..d53103f0f 100644 --- a/mingw-w64-crt/testcases/t_mbsrtowcs.c +++ b/mingw-w64-crt/testcases/t_mbsrtowcs.c @@ -134,7 +134,7 @@ int main (void) { /** * Test SBCS code page */ - assert (setlocale (LC_ALL, "English_United States.ACP") != NULL); + assert (setlocale (LC_ALL, "English_United States.1252") != NULL); assert (MB_CUR_MAX == 1); /* Test SBCS input */ @@ -196,7 +196,7 @@ int main (void) { /** * Test DBCS code page */ - assert (setlocale (LC_ALL, "Japanese_Japan.ACP") != NULL); + assert (setlocale (LC_ALL, "Japanese_Japan.932") != NULL); assert (MB_CUR_MAX == 2); /* Test ASCII input */ diff --git a/mingw-w64-crt/testcases/t_wcrtomb.c b/mingw-w64-crt/testcases/t_wcrtomb.c index 83a89d90e..d6e7c05ef 100644 --- a/mingw-w64-crt/testcases/t_wcrtomb.c +++ b/mingw-w64-crt/testcases/t_wcrtomb.c @@ -152,7 +152,7 @@ int main (void) { /** * Test DBCS code page */ - assert (setlocale (LC_ALL, "Japanese_Japan.ACP") != NULL); + assert (setlocale (LC_ALL, "Japanese_Japan.932") != NULL); assert (MB_CUR_MAX == 2); /** diff --git a/mingw-w64-crt/testcases/t_wcsrtombs.c b/mingw-w64-crt/testcases/t_wcsrtombs.c index b5f744f83..87fbe9695 100644 --- a/mingw-w64-crt/testcases/t_wcsrtombs.c +++ b/mingw-w64-crt/testcases/t_wcsrtombs.c @@ -191,7 +191,7 @@ int main (void) { /** * Test SBCS code page */ - assert (setlocale (LC_ALL, "English_United States.ACP") != NULL); + assert (setlocale (LC_ALL, "English_United States.1252") != NULL); assert (MB_CUR_MAX == 1); /* Test ASCII input */ @@ -354,7 +354,7 @@ int main (void) { /** * Test DBCS code page */ - assert (setlocale (LC_ALL, "Japanese_Japan.ACP") != NULL); + assert (setlocale (LC_ALL, "Japanese_Japan.932") != NULL); assert (MB_CUR_MAX == 2); /* Test ASCII input */ diff --git a/mingw-w64-crt/testcases/t_wctob.c b/mingw-w64-crt/testcases/t_wctob.c index 6177223a7..a89064bc5 100644 --- a/mingw-w64-crt/testcases/t_wctob.c +++ b/mingw-w64-crt/testcases/t_wctob.c @@ -65,7 +65,7 @@ int main (void) { /** * Test DBCS code page */ - assert (setlocale (LC_ALL, "Japanese_Japan.ACP") != NULL); + assert (setlocale (LC_ALL, "Japanese_Japan.932") != NULL); assert (MB_CUR_MAX == 2); /** -- 2.51.0.windows.1
From 0a865e49946ef20cf79a571f14f2f198e9fcefc3 Mon Sep 17 00:00:00 2001 From: Kirill Makurin <[email protected]> Date: Sat, 6 Sep 2025 18:43:40 +0900 Subject: [PATCH 2/4] tests: disable tests for DBCS code pages with msvcrt10.dll Calling msvcrt10.dll's setlocale with locale string which requests DBCS code page results in runtime error. Signed-off-by: Kirill Makurin <[email protected]> --- mingw-w64-crt/testcases/t_btowc.c | 10 +++++++++- mingw-w64-crt/testcases/t_mbrlen.c | 10 +++++++++- mingw-w64-crt/testcases/t_mbrtowc.c | 10 +++++++++- mingw-w64-crt/testcases/t_mbsrtowcs.c | 10 +++++++++- mingw-w64-crt/testcases/t_wcrtomb.c | 10 +++++++++- mingw-w64-crt/testcases/t_wcsrtombs.c | 10 +++++++++- mingw-w64-crt/testcases/t_wctob.c | 10 +++++++++- 7 files changed, 63 insertions(+), 7 deletions(-) diff --git a/mingw-w64-crt/testcases/t_btowc.c b/mingw-w64-crt/testcases/t_btowc.c index 8137a8274..cb71973c8 100644 --- a/mingw-w64-crt/testcases/t_btowc.c +++ b/mingw-w64-crt/testcases/t_btowc.c @@ -53,6 +53,14 @@ int main (void) { assert (btowc (c) != WEOF); } + /** + * Disable tests for DBCS code pages with msvcrt10.dll since it does not + * support multibyte characters. + * + * Calling setlocale with locale string which requests DBCS code page + * result in runtime error. + */ +#if __MSVCRT_VERSION__ != 0x0100 /** * Test DBCS code page */ @@ -74,7 +82,7 @@ int main (void) { assert (btowc (c) == WEOF); } } - +#endif #ifdef _UCRT /** * Test UTF-8 diff --git a/mingw-w64-crt/testcases/t_mbrlen.c b/mingw-w64-crt/testcases/t_mbrlen.c index 62051d6ee..e1691078c 100644 --- a/mingw-w64-crt/testcases/t_mbrlen.c +++ b/mingw-w64-crt/testcases/t_mbrlen.c @@ -89,6 +89,14 @@ int main (void) { } } + /** + * Disable tests for DBCS code pages with msvcrt10.dll since it does not + * support multibyte characters. + * + * Calling setlocale with locale string which requests DBCS code page + * result in runtime error. + */ +#if __MSVCRT_VERSION__ != 0x0100 /** * Test DBCS code page */ @@ -139,6 +147,6 @@ int main (void) { assert (mbrlen ((char *) InvalidMultibyte, MB_CUR_MAX, &state) == (size_t) -1); assert (mbsinit (&state)); assert (errno == EILSEQ); - +#endif return 0; } diff --git a/mingw-w64-crt/testcases/t_mbrtowc.c b/mingw-w64-crt/testcases/t_mbrtowc.c index 0e58946c1..c33cc223d 100644 --- a/mingw-w64-crt/testcases/t_mbrtowc.c +++ b/mingw-w64-crt/testcases/t_mbrtowc.c @@ -101,6 +101,14 @@ int main (void) { } } + /** + * Disable tests for DBCS code pages with msvcrt10.dll since it does not + * support multibyte characters. + * + * Calling setlocale with locale string which requests DBCS code page + * result in runtime error. + */ +#if __MSVCRT_VERSION__ != 0x0100 /** * Test DBCS code page */ @@ -164,6 +172,6 @@ int main (void) { assert (wc == WEOF); assert (mbsinit (&state)); assert (errno == EILSEQ); - +#endif return 0; } diff --git a/mingw-w64-crt/testcases/t_mbsrtowcs.c b/mingw-w64-crt/testcases/t_mbsrtowcs.c index d53103f0f..e85719e4d 100644 --- a/mingw-w64-crt/testcases/t_mbsrtowcs.c +++ b/mingw-w64-crt/testcases/t_mbsrtowcs.c @@ -193,6 +193,14 @@ int main (void) { assert (errno == 0); assert (buffer[8] == WEOF); + /** + * Disable tests for DBCS code pages with msvcrt10.dll since it does not + * support multibyte characters. + * + * Calling setlocale with locale string which requests DBCS code page + * result in runtime error. + */ +#if __MSVCRT_VERSION__ != 0x0100 /** * Test DBCS code page */ @@ -372,6 +380,6 @@ int main (void) { assert (errno == EILSEQ); /* This assertion fails with CRT's version */ assert (buffer[0] != WEOF && buffer[1] != WEOF && buffer[2] == WEOF); - +#endif return 0; } diff --git a/mingw-w64-crt/testcases/t_wcrtomb.c b/mingw-w64-crt/testcases/t_wcrtomb.c index d6e7c05ef..99329f2f7 100644 --- a/mingw-w64-crt/testcases/t_wcrtomb.c +++ b/mingw-w64-crt/testcases/t_wcrtomb.c @@ -149,6 +149,14 @@ int main (void) { } } + /** + * Disable tests for DBCS code pages with msvcrt10.dll since it does not + * support multibyte characters. + * + * Calling setlocale with locale string which requests DBCS code page + * result in runtime error. + */ +#if __MSVCRT_VERSION__ != 0x0100 /** * Test DBCS code page */ @@ -202,6 +210,6 @@ int main (void) { break; } } - +#endif return 0; } diff --git a/mingw-w64-crt/testcases/t_wcsrtombs.c b/mingw-w64-crt/testcases/t_wcsrtombs.c index 87fbe9695..2a78c7882 100644 --- a/mingw-w64-crt/testcases/t_wcsrtombs.c +++ b/mingw-w64-crt/testcases/t_wcsrtombs.c @@ -351,6 +351,14 @@ int main (void) { // reset errno _set_errno (0); + /** + * Disable tests for DBCS code pages with msvcrt10.dll since it does not + * support multibyte characters. + * + * Calling setlocale with locale string which requests DBCS code page + * result in runtime error. + */ +#if __MSVCRT_VERSION__ != 0x0100 /** * Test DBCS code page */ @@ -565,6 +573,6 @@ int main (void) { // reset errno _set_errno (0); - +#endif return 0; } diff --git a/mingw-w64-crt/testcases/t_wctob.c b/mingw-w64-crt/testcases/t_wctob.c index a89064bc5..00f10abf5 100644 --- a/mingw-w64-crt/testcases/t_wctob.c +++ b/mingw-w64-crt/testcases/t_wctob.c @@ -62,6 +62,14 @@ int main (void) { } } + /** + * Disable tests for DBCS code pages with msvcrt10.dll since it does not + * support multibyte characters. + * + * Calling setlocale with locale string which requests DBCS code page + * result in runtime error. + */ +#if __MSVCRT_VERSION__ != 0x0100 /** * Test DBCS code page */ @@ -96,7 +104,7 @@ int main (void) { break; } } - +#endif #ifdef _UCRT /** * Test UTF-8 -- 2.51.0.windows.1
From ef3cabc962684354c7742f1781d648d7a50f73dd Mon Sep 17 00:00:00 2001 From: Kirill Makurin <[email protected]> Date: Sat, 6 Sep 2025 18:46:08 +0900 Subject: [PATCH 3/4] crt: avoid sign-extension of argument to isleadbyte in mbrtowc Passing an argument of type `char` to isleadbyte may result in sign-extension of its argument. crtdll.dll's isleadbyte does not handle sign-extended input properly, which result in incorrect behavior of mbrlen and mbrtowc functions. Add cast to `unsigned char` to avoid this. Signed-off-by: Kirill Makurin <[email protected]> --- mingw-w64-crt/misc/mbrtowc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mingw-w64-crt/misc/mbrtowc.c b/mingw-w64-crt/misc/mbrtowc.c index 75c9f98f0..ba0b9c09e 100644 --- a/mingw-w64-crt/misc/mbrtowc.c +++ b/mingw-w64-crt/misc/mbrtowc.c @@ -75,7 +75,7 @@ size_t mbrtowc ( conversion_state.bytes[1] = mbs[0]; bytes_consumed = 1; length = 2; - } else if (mb_cur_max == 2 && isleadbyte (mbs[0])) { + } else if (mb_cur_max == 2 && isleadbyte ((unsigned char) mbs[0])) { conversion_state.bytes[0] = mbs[0]; /* We need to examine mbs[1] */ -- 2.51.0.windows.1
From 0319383f90fbf6cb3e67fd390c2b8e1a8ae54136 Mon Sep 17 00:00:00 2001 From: Kirill Makurin <[email protected]> Date: Sat, 6 Sep 2025 19:00:37 +0900 Subject: [PATCH 4/4] tests: clarify that tests for C95 conversion functions are skipped for UCRT Signed-off-by: Kirill Makurin <[email protected]> --- mingw-w64-crt/testcases/t_mbrlen.c | 10 ++++++++++ mingw-w64-crt/testcases/t_mbrtowc.c | 10 ++++++++++ mingw-w64-crt/testcases/t_mbsrtowcs.c | 10 ++++++++++ mingw-w64-crt/testcases/t_wcrtomb.c | 10 ++++++++++ mingw-w64-crt/testcases/t_wcsrtombs.c | 10 ++++++++++ 5 files changed, 50 insertions(+) diff --git a/mingw-w64-crt/testcases/t_mbrlen.c b/mingw-w64-crt/testcases/t_mbrlen.c index e1691078c..4b1c46ce9 100644 --- a/mingw-w64-crt/testcases/t_mbrlen.c +++ b/mingw-w64-crt/testcases/t_mbrlen.c @@ -9,6 +9,16 @@ #include <stdlib.h> #include <wchar.h> +/** + * This test is for mingw-w64's implementation of mbrlen function. + * + * This implementation is used with all msvcr*.dll CRTs, but not UCRT. + * This test is skipped for UCRT. + * + * Also note that mingw-w64's implementation only works with SBCS and DBCS + * code pages (MB_CUR_MAX == 1 || MB_CUR_MAX == 2). + */ + static void set_conversion_state (mbstate_t *state, int bytes) { #ifdef _UCRT state->_Wchar = bytes; diff --git a/mingw-w64-crt/testcases/t_mbrtowc.c b/mingw-w64-crt/testcases/t_mbrtowc.c index c33cc223d..4d97b9095 100644 --- a/mingw-w64-crt/testcases/t_mbrtowc.c +++ b/mingw-w64-crt/testcases/t_mbrtowc.c @@ -9,6 +9,16 @@ #include <stdlib.h> #include <wchar.h> +/** + * This test is for mingw-w64's implementation of mbrtowc function. + * + * This implementation is used with all msvcr*.dll CRTs, but not UCRT. + * This test is skipped for UCRT. + * + * Also note that mingw-w64's implementation only works with SBCS and DBCS + * code pages (MB_CUR_MAX == 1 || MB_CUR_MAX == 2). + */ + static void set_conversion_state (mbstate_t *state, int bytes) { #ifdef _UCRT state->_Wchar = bytes; diff --git a/mingw-w64-crt/testcases/t_mbsrtowcs.c b/mingw-w64-crt/testcases/t_mbsrtowcs.c index e85719e4d..e9f60ec55 100644 --- a/mingw-w64-crt/testcases/t_mbsrtowcs.c +++ b/mingw-w64-crt/testcases/t_mbsrtowcs.c @@ -9,6 +9,16 @@ #include <stdlib.h> #include <wchar.h> +/** + * This test is for mingw-w64's implementation of mbsrtowcs function. + * + * This implementation is used with all msvcr*.dll CRTs, but not UCRT. + * This test is skipped for UCRT. + * + * Also note that mingw-w64's implementation only works with SBCS and DBCS + * code pages (MB_CUR_MAX == 1 || MB_CUR_MAX == 2). + */ + /* ASCII text */ char AsciiText[] = "Simple English string."; /* SBCS text (code page 1252) */ diff --git a/mingw-w64-crt/testcases/t_wcrtomb.c b/mingw-w64-crt/testcases/t_wcrtomb.c index 99329f2f7..f9d1a8d00 100644 --- a/mingw-w64-crt/testcases/t_wcrtomb.c +++ b/mingw-w64-crt/testcases/t_wcrtomb.c @@ -9,6 +9,16 @@ #include <stdlib.h> #include <wchar.h> +/** + * This test is for mingw-w64's implementation of wcrtomb function. + * + * This implementation is used with all msvcr*.dll CRTs, but not UCRT. + * This test is skipped for UCRT. + * + * Also note that mingw-w64's implementation only works with SBCS and DBCS + * code pages (MB_CUR_MAX == 1 || MB_CUR_MAX == 2). + */ + #define WIN32_LEAN_AND_MEAN #include <windows.h> diff --git a/mingw-w64-crt/testcases/t_wcsrtombs.c b/mingw-w64-crt/testcases/t_wcsrtombs.c index 2a78c7882..705cdc27e 100644 --- a/mingw-w64-crt/testcases/t_wcsrtombs.c +++ b/mingw-w64-crt/testcases/t_wcsrtombs.c @@ -10,6 +10,16 @@ #include <string.h> #include <wchar.h> +/** + * This test is for mingw-w64's implementation of wcsrtombs function. + * + * This implementation is used with all msvcr*.dll CRTs, but not UCRT. + * This test is skipped for UCRT. + * + * Also note that mingw-w64's implementation only works with SBCS and DBCS + * code pages (MB_CUR_MAX == 1 || MB_CUR_MAX == 2). + */ + wchar_t AsciiText[] = L"Simple English text."; wchar_t SBCSText[] = L"Sömè fÃnnÿ têxt"; wchar_t DBCSText[] = L"æ¥æ¬èªãã¯ã¹ã"; -- 2.51.0.windows.1
_______________________________________________ Mingw-w64-public mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
