From 4a674b6f84f497718f2e14e38a1ddde64017d0c3 Mon Sep 17 00:00:00 2001 From: "seer-by-sentry[bot]" <157164994+seer-by-sentry[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2026 23:19:21 +0000 Subject: [PATCH] bugfix(compat): Improve WideCharToMultiByte reliability and query mode --- Dependencies/Utility/Utility/wchar_compat.h | 24 ++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/Dependencies/Utility/Utility/wchar_compat.h b/Dependencies/Utility/Utility/wchar_compat.h index a6761905a71..ad619e81ae4 100644 --- a/Dependencies/Utility/Utility/wchar_compat.h +++ b/Dependencies/Utility/Utility/wchar_compat.h @@ -30,5 +30,27 @@ typedef WCHAR* LPWSTR; // MultiByteToWideChar #define CP_ACP 0 #define MultiByteToWideChar(cp, flags, mbstr, cb, wcstr, cch) mbstowcs(wcstr, mbstr, cch) -#define WideCharToMultiByte(cp, flags, wcstr, cch, mbstr, cb, defchar, used) wcstombs(mbstr, wcstr, cb) + +// WideCharToMultiByte replacement: +// The real Windows API supports a "query mode" where mbstr==nullptr and cb==0, which returns +// the required buffer size. wcstombs(nullptr, wcstr, 0) is unreliable on some CRT +// implementations (e.g. Windows CRT via MinGW), so we use an inline function instead. +inline int WideCharToMultiByte(unsigned int /*cp*/, unsigned long /*flags*/, + const wchar_t* wcstr, int /*cch*/, + char* mbstr, int cb, + const char* /*defchar*/, int* /*used*/) +{ + if (!wcstr) + return 0; + if (!mbstr || cb == 0) + { + // Query mode: return the required buffer size (number of bytes including null terminator) + size_t len = wcslen(wcstr); + return static_cast(len + 1); + } + size_t converted = wcstombs(mbstr, wcstr, static_cast(cb)); + if (converted == static_cast(-1)) + return 0; + return static_cast(converted); +}