pg.ddx.io pgsql-bugs@postgresql.org mailing list archive
help / color / mirror / Atom feed[PATCH v3] attempt multibyte-aware truncation of database names
1+ messages / 1 participants
[nested] [flat]
* [PATCH v3] attempt multibyte-aware truncation of database names
@ 2024-11-20 22:30 Nathan Bossart <nathan@postgresql.org>
0 siblings, 0 replies; 1+ messages in thread
From: Nathan Bossart @ 2024-11-20 22:30 UTC (permalink / raw)
---
src/backend/utils/init/postinit.c | 82 +++++++++++++++++++++++++++++--
1 file changed, 79 insertions(+), 3 deletions(-)
100.0% src/backend/utils/init/
inline patch 1: src/backend/utils/init/postinit.c (+79/-3 lines) download inline-1.patch
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 5b657a3f13..ef6fe705c2 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -1003,14 +1003,90 @@ InitPostgres(const char *in_dbname, Oid dboid,
{
HeapTuple tuple;
Form_pg_database dbform;
+ char trunc_dbname[NAMEDATALEN];
+ int curr_len = NAMEDATALEN - 1;
- tuple = GetDatabaseTuple(in_dbname);
+ /* truncate to NAMEDATALEN-1 bytes first */
+ strncpy(trunc_dbname, in_dbname, curr_len);
+ trunc_dbname[curr_len] = '\0';
+
+ tuple = GetDatabaseTuple(trunc_dbname);
+
+ if (HeapTupleIsValid(tuple))
+ strcpy(dbname, trunc_dbname);
+
+ /*
+ * Try shorter lengths to handle potential multibyte character splits.
+ * We only need to check back to NAMEDATALEN - MAX_MULTIBYTE_CHAR_LEN
+ * since no valid multibyte character can be longer than that.
+ */
+ while (curr_len > NAMEDATALEN - MAX_MULTIBYTE_CHAR_LEN)
+ {
+ /*
+ * If we've hit an ASCII byte (high bit clear), we know we can't
+ * be in the middle of a multibyte character, because all bytes of
+ * a multibyte character must have their high bits set.
+ */
+ if (!IS_HIGHBIT_SET(trunc_dbname[curr_len - 1]))
+ break;
+
+ /*
+ * Check if we might be splitting a multibyte char by looking at
+ * the high bits of the current position and the previous byte in
+ * the original string.
+ *
+ * Note: We must check against in_dbname when looking at curr_len
+ * because that byte has been truncated from trunc_dbname.
+ */
+ if (curr_len < strlen(in_dbname) &&
+ IS_HIGHBIT_SET(in_dbname[curr_len]))
+ {
+ HeapTuple tmp;
+
+ /*
+ * Might be splitting a multibyte char, try one byte shorter
+ * to find a possible character boundary.
+ */
+ curr_len--;
+ trunc_dbname[curr_len] = '\0';
+
+ tmp = GetDatabaseTuple(trunc_dbname);
+
+ /*
+ * If we already had a match then the name is ambiguous and we
+ * must fail.
+ */
+ if (HeapTupleIsValid(tmp))
+ {
+ if (HeapTupleIsValid(tuple))
+ ereport(FATAL,
+ (errmsg("ambiguous database name")));
+ tuple = tmp;
+ strcpy(dbname, trunc_dbname);
+ }
+ }
+ else
+ /* not in the middle of a multibyte char */
+ break;
+ }
+
+ /* If we didn't find any valid database name, report an error */
if (!HeapTupleIsValid(tuple))
ereport(FATAL,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database \"%s\" does not exist", in_dbname)));
+
dbform = (Form_pg_database) GETSTRUCT(tuple);
dboid = dbform->oid;
+
+ if (MyProcPort && MyProcPort->database_name &&
+ strcmp(MyProcPort->database_name, dbname) != 0)
+ {
+ pfree(MyProcPort->database_name);
+ MyProcPort->database_name = pstrdup(dbname);
+
+ /* XXX: should we fix process title? */
+ }
}
else if (!OidIsValid(dboid))
{
@@ -1067,12 +1143,12 @@ InitPostgres(const char *in_dbname, Oid dboid,
datform = (Form_pg_database) GETSTRUCT(tuple);
if (!HeapTupleIsValid(tuple) ||
- (in_dbname && namestrcmp(&datform->datname, in_dbname)))
+ (in_dbname && namestrcmp(&datform->datname, dbname)))
{
if (in_dbname)
ereport(FATAL,
(errcode(ERRCODE_UNDEFINED_DATABASE),
- errmsg("database \"%s\" does not exist", in_dbname),
+ errmsg("database \"%s\" does not exist", dbname),
errdetail("It seems to have just been dropped or renamed.")));
else
ereport(FATAL,
--
2.34.1
--1WCno6C1v+Mdlz+A--
^ permalink raw reply [nested|flat] 1+ messages in thread
only message in thread
Thread overview: 1+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2024-11-20 22:30 [PATCH v3] attempt multibyte-aware truncation of database names Nathan Bossart <nathan@postgresql.org>
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox