Hello,

When Pali sent patches which added __mingw_isleadbyte_cp, I suggested we use it 
in __mingw_mbrtowc_cp instead of CRT's isleadbyte. These two patches do it.

Second patch moves __mingw_mbrtowc_cp and __mingw_wcrtomb_cp from import 
libraries to libmingwx, which I think is a good idea. This allows us to use 
them in any mingw-w64 code; their primary limitation right now is that they 
only handles conversions using SBCS and DBCS code pages.

- Kirill Makurin
From 5dd1fa6d5ab6afe626b610c0b80952b69106e6de Mon Sep 17 00:00:00 2001
From: Kirill Makurin <[email protected]>
Date: Thu, 12 Feb 2026 14:51:00 +0900
Subject: [PATCH 1/2] crt: call __mingw_isleadbyte_cp from __mingw_mbrtowc_cp

Previously, `__mingw_mbrtowc_cp` called CRT's `isleadbyte` to determine
whether first byte pointed to by `mbs` is a DBCS leading byte.

While `__mingw_mbrtowc_cp` explicitly takes code page to operate on,
CRT's `isleadbyte` depends on active locale set with `setlocale`.

Using `__mingw_isleadbyte_cp` instead has the following advantages:

1. This removes dependency on CRT state, making it possible to call
`__mingw_mbrtowc_cp` with any SBCS and DBCS code page regardless of thread's
active locale.

2. This removes a possible race condition when either of `mbrlen`, `mbrtowc` or
`mbsrtowcs` obtained code page information from CRT, but then another thread
changed global locale before `__mingw_mbrtowc_cp` has called `isleadbyte`,
leading to incorrect results.

Signed-off-by: Kirill Makurin <[email protected]>
---
 mingw-w64-crt/misc/__mingw_mbrtowc_cp.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/mingw-w64-crt/misc/__mingw_mbrtowc_cp.c 
b/mingw-w64-crt/misc/__mingw_mbrtowc_cp.c
index d079465c6..22bbb062d 100644
--- a/mingw-w64-crt/misc/__mingw_mbrtowc_cp.c
+++ b/mingw-w64-crt/misc/__mingw_mbrtowc_cp.c
@@ -26,8 +26,8 @@
  *    ___mb_cur_max_func
  *
  *  - for double-byte code pages, we need to recognize leading bytes in order
- *    to correctly convert multibyte characters; this can be done with Win32
- *    function IsDBCSLeadByteEx or CRT function isleadbyte
+ *    to correctly convert multibyte characters; use mingw-w64's portable
+ *    __mingw_isleadbyte_cp for this
  *
  * crtdll.dll's ___lc_codepage_func is quite expensive as it obtains this
  * information by parsing return value of setlocale(LC_CTYPE, NULL). Using
@@ -93,7 +93,7 @@ size_t __mingw_mbrtowc_cp (
     conversion_state.bytes[1] = mbs[0];
     bytes_consumed = 1;
     length = 2;
-  } else if (mb_cur_max == 2 && isleadbyte ((unsigned char) mbs[0])) {
+  } else if (mb_cur_max == 2 && __mingw_isleadbyte_cp ((unsigned char) mbs[0], 
cp)) {
     conversion_state.bytes[0] = mbs[0];
 
     /* We need to examine mbs[1] */
-- 
2.51.0.windows.1
From e6e5955cccb2d9e00cb1c69c7ce7db3267b02161 Mon Sep 17 00:00:00 2001
From: Kirill Makurin <[email protected]>
Date: Thu, 12 Feb 2026 14:52:10 +0900
Subject: [PATCH 2/2] crt: move __mingw_{mbrtowc,wcrtomb}_cp functions to
 libmingwex.a

Previously, these two functions were in import libraries for all CRTs
except for UCRT. They were used only as underlying implementation for
C95 functions `mbrlen`, `mbrtowc`, `mbsrtowcs`, `wcrtomb` and `wcsrtombs`.

This change makes these functions available to all CRTs, making it safe
to call them from mignw-w64's code. This also removes duplicating object
code from import libraries.

Note that while UCRT's `mbstate_t` is a structure, compared to all other
CRTs where it is an `int`, both __mingw_{mbrtowc,wcrtomb}_cp access it
as an `int` which allows to use them with UCRT's `mbstate_t` as well.

Signed-off-by: Kirill Makurin <[email protected]>
---
 mingw-w64-crt/Makefile.am | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index e10cfe12e..81143a01a 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -171,8 +171,6 @@ src_msvcrt_common=\
   include/msvcrt.h \
   include/msvcrt_or_emu_glue.h \
   include/mingw-wchar.h \
-  misc/__mingw_mbrtowc_cp.c \
-  misc/__mingw_wcrtomb_cp.c \
   misc/_onexit.c \
   misc/mbrlen.c \
   misc/mbrtowc.c \
@@ -1284,6 +1282,7 @@ src_libmingwex=\
   misc/wmemset.c         misc/mingw-access.c \
   misc/ftw32.c           misc/ftw32i64.c            misc/ftw64.c            
misc/ftw64i32.c \
   misc/__mingw_filename_cp.c misc/__mingw_isleadbyte_cp.c \
+  misc/__mingw_mbrtowc_cp.c  misc/__mingw_wcrtomb_cp.c \
   \
   ssp/chk_fail.c         ssp/gets_chk.c             ssp/memcpy_chk.c        
ssp/memmove_chk.c \
   ssp/mempcpy_chk.c \
-- 
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