From 158181810d1a4b6798261ca0523a192dbdfeef86 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Wed, 28 Aug 2024 20:52:04 +1200
Subject: [PATCH] initdb: Reject non-ASCII locale names.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Commit bf03cfd1 started scanning the available BCP 47 locale names on
Windows, but this caused a problem when initdb --locale is given a
name containing non-ASCII characters, such as "Turkish_Türkiye.1254".
The save-restore pattern of setlocale() calls used to check each
locale's encoding also changed the expected encoding of the locale name
itself on the next call, and then Windows' runtime library unhelpfully
aborts.

While master doesn't actually do that setlocale() save-restore anymore
(see 35eeea62), it still seems like a good idea to block non-ASCII
locale names, as their encoding is undefined when stored in PostgreSQL
catalogues.

Back-patch to 16, where bf03cfd1 landed.

Discussion: https://postgr.es/m/PH8PR21MB3902F334A3174C54058F792CE5182%40PH8PR21MB3902.namprd21.prod.outlook.com
---
 src/bin/initdb/initdb.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index f00718a015..807d35b96b 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -2138,6 +2138,9 @@ check_locale_name(int category, const char *locale, char **canonname)
 	if (canonname)
 		*canonname = NULL;		/* in case of failure */
 
+	if (!pg_is_ascii(locale))
+		pg_fatal("locale name \"%s\" contains non-ASCII characters", locale);
+
 	save = setlocale(category, NULL);
 	if (!save)
 		pg_fatal("setlocale() failed");
-- 
2.39.2

