libc: setlocale must reject unavailable locales and return a name newlocale accepts - #1477
Open
gburd wants to merge 1 commit into
Open
libc: setlocale must reject unavailable locales and return a name newlocale accepts#1477gburd wants to merge 1 commit into
gburd wants to merge 1 commit into
Conversation
…able name
OSv has no on-disk locale database and provides only the C locale, but its
setlocale() stub returned "C.UTF-8" unconditionally and ignored its
arguments. That is observably wrong in two ways:
- A request for a locale OSv cannot provide (e.g. "en_US.UTF-8") must
return NULL so the caller learns it is unavailable; the stub silently
reported success for a locale that was never in effect.
- setlocale() must return a name newlocale() will accept, because portable
software round-trips the two. PostgreSQL derives a new database's default
collation from setlocale() and feeds it back to newlocale(); the stub
returned "C.UTF-8", which OSv's newlocale() rejects, so a cluster
initialized with LC_COLLATE=C still stamped every CREATE DATABASE with
datcollate="C.UTF-8" and then could not open it ("could not create
locale \"C.UTF-8\": ENOENT"). Any application that creates its own
database at runtime was blocked; initdb-time-baked clusters happened to
avoid it, which hid the bug.
Return the C locale (which newlocale() accepts) and accept only the C-family
names OSv can provide ("", "C", "POSIX", "C.UTF-8"), failing others.
Character-set encoding (e.g. UTF8 in PostgreSQL) is independent of the libc
locale and is unaffected.
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.
Problem
OSv has no on-disk locale database and provides only the C locale, but
setlocale()returned"C.UTF-8"unconditionally and ignored its arguments.That is observably wrong for a portable application in two ways:
A request for a locale OSv cannot provide (for example
"en_US.UTF-8")must return
NULLso the caller learns it is unavailable. The stubsilently reported success for a locale that was never actually in effect.
setlocale()must return a name thatnewlocale()will accept, becauseportable software round-trips the two. PostgreSQL derives a new database's
default collation from
setlocale()and feeds that name back intonewlocale(). The stub returned"C.UTF-8", which OSv'snewlocale()rejects, so a cluster initialized with
LC_COLLATE=Cnonetheless stampedevery
CREATE DATABASEwithdatcollate="C.UTF-8"and then could not openit (
could not create locale "C.UTF-8": ENOENT). Any application thatcreates its own database at runtime was blocked; clusters whose locale was
baked at initdb time happened to avoid it, which hid the bug.
Fix
Replace the stub with a small correct implementation: report the C locale
(which
newlocale()accepts) and accept only the C-family names OSv canactually provide (
"",C,POSIX,C.UTF-8), failing any other request.Character-set encoding (for example UTF8 in PostgreSQL) is independent of the
libc locale and is unaffected.
Testing
Built and booted; a stock PostgreSQL cluster on OSv can now
CREATE DATABASEand open the result, which previously failed with the ENOENT above.