Repository navigation
Conversation
gdrosa
force-pushed
the
fix/libc-guest-locale-conversions
branch
from
October 8, 2026 17:13
6f4939f to
aa83621
Compare
This was referenced Oct 8, 2026
frvnzz
approved these changes
Oct 9, 2026
frvnzz
left a comment
There was a problem hiding this comment.
Reviewed aa83621. The fix is correct, and the regression test fails on main for the reason the PR states.
Production change
_Mbtowcxand_Wctombxnow go through the guestmbrtowcandwcrtombinMultibyte.cpp, so they map bytes 0–255 one-to-one, asmbrtowc,wcsrtombs_sand the rest of the guest C locale already do. The localextern "C"declarations match the definitions inMultibyte.cpp, and both are in the samelibctarget.- On
main, the host's C locale decides the result. glibc's C locale is 7-bit:gconv_simple.csends any byte above0x7ftoSTANDARD_FROM_LOOP_ERR_HANDLER(glibc bug 19932). So on Linux,_Wctombx(0xE9)and_Mbtowcx("\xE9")throw where the guest converts. The new 0–255 loop catches exactly that.
Tests
- They check errno: it is unchanged after a successful conversion and 86 after an invalid unit. They also check that no output bytes are written on failure, and that
C3 A9is decoded as two units. That covers both the WindowsEILSEQ(42) problem and the UTF-8 problem from the description. setlocaleruns afterCheckGuestCallshas joined its threads, so the global locale switch can't race with them. The saved locale is restored afterwards.
Verified independently
- The branch is 175 commits behind
mainbut merges cleanly. It also merges cleanly together with the other open PRs touchingLocaleSupport.cpp(#1982, #1993). - The linked fork run 37814520846 checks out
aa83621exactly, andguest_localepasses in all three repetitions.
Nits, optional
*dst = static_cast<std::uint16_t>(converted);:convertedis alreadystd::uint16_t, so the cast can go.- With the guest
mbrtowc,_Mbtowcxcan no longer return-1,-2or more thanINT_MAXoncecount == 0and nullsrcare rejected. Keeping the throws as guards for a future multibyte locale is fine. Mentioning it only in case you prefer to drop the dead branches. - On a host without
C.UTF-8or.UTF8, the UTF-8 half is skipped with only a log line, so ctest still reports a pass. That's acceptable for CI images that have the locale; just noting the coverage depends on it.
LGTM.
Review written with AI assistance; the merges and the CI log check above were run for this review.
10 tasks done
Contributor
|
Tested on Windows 10 (19045), MinGW-w64 GCC 15.2.0 (WinLibs r7), Release: this PR merged onto
Not tested: Linux, a console, a title run. AI-assisted (Claude Code). |
11 tasks done
Collaborator
|
Closing: no title is known to reach this. With the queue at 700+ open PRs, please hold off on new PRs that don't name a title needing the change until it's down. If a title stops on this on current main, reopen with the title ID and the log line. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
_Mbtowcxand_Wctombxcurrently use host CRT conversions despite the guest's single-byte C locale.On a UTF-8 host, U+00E9 is encoded as
C3 A9instead ofE9, while valid guest bytes may be rejected or combined into multibyte sequences. Invalid wide characters can also expose the Windows hostEILSEQvalue (42) instead of the guest value (86).Changes
mbrtowc_nid_postfixandwcrtomb_nid_postfiximplementations using a 16-bit temporary.guest_localeregression coverage to include all 256 input bytes, independent decoding ofC3 A9, errno preservation, output canaries, rejected wide units, and both C and available UTF-8 host locales.Only
LocaleSupport.cppandGuestLocale.cppare modified: 6 insertions and 4 deletions in production code, plus regression tests.This fix is independent of #1507.
Tested
Initial verification baseline:
4d03ecf4dee14407b8f388883ceaedee944c8fbeInitial tested contribution:
6f4939f25abae6f451a67c626f353bc17b7837d5Windows x64 — GCC 15.2.0 (WinLibs UCRT POSIX SEH r7), Release
09a17e963aa075e1576abc4bcb3f2e5c3219e4e7), zero with the fix. Verified the loaded DLL paths.SIZE_MAX, null/zero arguments, errno, opaque state, output canaries, and protected page boundaries.Ubuntu 24.04 x86-64 — GCC 13.3.0, CMake 4.4.4, Ninja 1.13.0, Release
--repeat until-fail:3.Additional checks
-Wtype-limits -Werror=type-limits.git diff --checkpassed.CI note
The original Linux verification recorded a stale
guest_formatting_testsentry in the test-registration checker. That issue was fixed upstream by #1603. This branch is now rebased ontomainat7995d6578d289310c25b8e104119c8bbfabb14f9; the refreshed contribution isaa83621aa00b4d85a833e7697c8f8997d5911f32. No checker or build-configuration changes are included in this PR.On the refreshed branch, the Windows libc build and all 34 component CTests pass again; the real-DLL harness passes all 660,017 assertions. The test-registration check passes on both Windows and Linux.
The refreshed Linux run verifies this exact contribution commit and passes every workflow step, with no
continue-on-error. It uses CMake/Ninja in a virtualenv, GCC 13.3.0, Release and SPIRV-Tools enabled; it performs no system-package installation. Results:Upstream pull-request workflows still await maintainer approval (
action_required, no jobs); the independent fork results above do not populate the PR's checks.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository