diff --git a/core/libs/prx/libc/src/RuneLocale.cpp b/core/libs/prx/libc/src/RuneLocale.cpp index 4f3b67a702..da1e4ace53 100644 --- a/core/libs/prx/libc/src/RuneLocale.cpp +++ b/core/libs/prx/libc/src/RuneLocale.cpp @@ -1,4 +1,5 @@ #include "prx/libc/include/general/VabiMacros.hpp" +#include #include #include #include @@ -148,7 +149,10 @@ std::uint32_t APS5_VABI towupper_nid_postfix(std::uint32_t c) { std::uint32_t APS5_VABI btowc_nid_postfix(int c) { const auto byte = static_cast(c); - return c == -1 || byte >= 0x80 ? GuestRune::Weof : byte; + if (c == -1) return GuestRune::Weof; + if (byte < 0x80) return byte; + if (byte < 0xc0 || byte >= 0xf0) errno = 86; + return GuestRune::Weof; } int APS5_VABI wctob_nid_postfix(std::uint32_t c) { diff --git a/core/libs/tests/GuestRuneLocale.cpp b/core/libs/tests/GuestRuneLocale.cpp index 5d801f27ac..ff51720da5 100644 --- a/core/libs/tests/GuestRuneLocale.cpp +++ b/core/libs/tests/GuestRuneLocale.cpp @@ -149,5 +149,15 @@ int main() { } errno = 0; Require(towctrans_nid_postfix('A', 0) == 'A' && towctrans_nid_postfix('a', 3) == 'a' && errno == 0); + for (int c = -300; c < 0x1200; ++c) { + const auto byte = static_cast(c); + errno = 0; + const std::uint32_t wide = btowc_nid_postfix(c); + const bool invalidLead = c != -1 && ((byte >= 0x80 && byte < 0xc0) || byte >= 0xf0); + Require(wide == (c != -1 && byte < 0x80 ? byte : 0xffffffffu) && errno == (invalidLead ? 86 : 0)); + } + errno = 7; + Require(btowc_nid_postfix(0xc3) == 0xffffffff && btowc_nid_postfix(0xef) == 0xffffffff && btowc_nid_postfix(-1) == 0xffffffff && errno == 7); + Require(btowc_nid_postfix(0x41) == 'A' && errno == 7); return 0; }