Skip to content

Comments

_Locinfo: Use _wsetlocale to query and restore locales#5781

Open
lb90 wants to merge 13 commits intomicrosoft:mainfrom
lb90:fix-issue-5780
Open

_Locinfo: Use _wsetlocale to query and restore locales#5781
lb90 wants to merge 13 commits intomicrosoft:mainfrom
lb90:fix-issue-5780

Conversation

@lb90
Copy link

@lb90 lb90 commented Oct 14, 2025

_Locinfo changes the locale temporarily and then reverts to the previous locale on destruction. The sequence of setlocale calls are as follows:

  1. oldlocname = setlocale(LC_ALL, nullptr) to query the locale string
  2. setlocale(LC_ALL, newlocname) to set the temporary locale
  3. setlocale(LC_ALL, oldlocname) to restore the previous locale

However there's a catch here: the fully-qualified locale names returned by setlocale are not always ASCII strings (more on that below). This creates challenges because the oldlocname is encoded depending on the "outer" locale, while the setlocale call at point 3) expects an encoding which follows the "inner" locale, and the two may not match.

To solve this issue, use the wide variant of setlocale: _wsetlocale. This way all strings are UTF-16 and there's no issue with varying narrow string encodings.

Addendum:

Actually, the C RunTime library does its best to use ASCII strings! It queries the english name of the locale using GetLocaleInfoEx. MSDN says that the returned string is always ASCII [1], but that's not always the case [2].

Fixes #5780

References:

  1. https://learn.microsoft.com/en-us/windows/win32/intl/locale-senglish-constants
  2. https://developercommunity.visualstudio.com/t/GetLocaleInfoEx-w-LOCALE_SENGLISHLANGUA/10981789

I made a similar change in libc++: llvm/llvm-project#160479

_LocInfo changes the locale temporarily and then reverts to the
previous locale on destruction. The sequence of setlocale calls
look as follows:

1. oldlocname = setlocale(LC_ALL, nullptr) to query the locale string
2. setlocale(LC_ALL, newlocname) to set the temporary locale
3. setlocale(LC_ALL, oldlocname) to restore the previous locale

However there's a catch here: the fully-qualified locale names
returned by setlocale are not always ASCII strings (more on that
below). This creates challenges because the oldlocname is encoded
depending on the "outer" locale, while the setlocale call at point
3) expects an encoding which depend on the "inner" locale, and the
two may not match.

To solve this issue, use the wide variant of setlocale: _wsetlocale.
This way all strings are UTF-16 and there's no issue with varying
narrow string encodings.

Addendum:

Actually, the C RunTime library does its best to use ASCII strings!
It queries the english name of the locale using GetLocaleInfoEx.
MSDN says that the returned string is always ASCII [1], but that's
not always the case [2].

Fixes microsoft#5780

References:
 1. https://learn.microsoft.com/en-us/windows/win32/intl/locale-senglish-constants
 2. https://developercommunity.visualstudio.com/t/GetLocaleInfoEx-w-LOCALE_SENGLISHLANGUA/10981789
@lb90 lb90 requested a review from a team as a code owner October 14, 2025 12:17
@github-project-automation github-project-automation bot moved this to Initial Review in STL Code Reviews Oct 14, 2025
@github-project-automation github-project-automation bot moved this from Initial Review to Work In Progress in STL Code Reviews Oct 14, 2025
@StephanTLavavej

This comment was marked as resolved.

@StephanTLavavej StephanTLavavej added the bug Something isn't working label Oct 14, 2025
@muellerj2

This comment was marked as resolved.

@frederick-vs-ja

This comment was marked as resolved.

@lb90

This comment was marked as resolved.

@StephanTLavavej StephanTLavavej changed the title _LocInfo: Use _wsetlocale to query and restore locales _Locinfo: Use _wsetlocale to query and restore locales Oct 16, 2025
@lb90 lb90 force-pushed the fix-issue-5780 branch 2 times, most recently from 12632f1 to 8f157f4 Compare October 17, 2025 17:10
@StephanTLavavej

This comment was marked as resolved.

@StephanTLavavej StephanTLavavej self-assigned this Oct 22, 2025
@StephanTLavavej StephanTLavavej moved this from Work In Progress to Initial Review in STL Code Reviews Oct 22, 2025
@lb90

This comment was marked as resolved.

@AlexGuteniev

This comment was marked as resolved.

@StephanTLavavej

This comment was marked as resolved.

@StephanTLavavej

This comment was marked as resolved.

@lb90

This comment was marked as resolved.

@StephanTLavavej StephanTLavavej removed their assignment Nov 14, 2025
@mikekaganski

This comment was marked as resolved.

@lb90

This comment was marked as resolved.

@StephanTLavavej StephanTLavavej moved this from Initial Review to Ready To Merge in STL Code Reviews Feb 18, 2026
@StephanTLavavej
Copy link
Member

Thank you! 😻 (And apologies for taking so long to review this, <flat_meow> took a while.) I am cautious because locales/iostreams burned me repeatedly at the beginning of my career, but this looks like a solid fix and if it goes wrong it'll be in a surprising way which is all I can ask for. 😹

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

Status: Ready To Merge

Development

Successfully merging this pull request may close these issues.

<iostream>: Printing with std::cout changes the global locale permanently

7 participants