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

Reply via email to