From 6ccb4f03f56dda9e9a2616c6e0875a97a8711d72 Mon Sep 17 00:00:00 2001 From: Bertrand Drouvot Date: Tue, 20 Jun 2023 10:26:16 +0000 Subject: [PATCH v1] multibyte truncation for database and user name database_name and user_name truncation done in ProcessStartupPacket() do not take care of multibyte character boundary. In case of multibyte, this somehow breaks the initial goal to avoid lookup failures when overlength names are given. --- src/backend/postmaster/postmaster.c | 48 ++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) 100.0% src/backend/postmaster/ diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 4c49393fc5..72991c4eab 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -1951,6 +1951,7 @@ ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done) char *buf; ProtocolVersion proto; MemoryContext oldcontext; + int client_encoding = -1; pq_startmsgread(); @@ -2238,6 +2239,18 @@ retry1: { port->application_name = pg_clean_ascii(valptr, 0); } + /* Record the client_encoding if we come across it */ + else if (strcmp(nameptr, "client_encoding") == 0) + { + client_encoding = pg_valid_client_encoding(valptr); + + if (client_encoding < 0) + ereport(FATAL, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid value for parameter \"%s\": \"%s\"", + "client_encoding", + valptr))); + } } offset = valoffset + strlen(valptr) + 1; } @@ -2291,13 +2304,40 @@ retry1: } /* - * Truncate given database and user names to length of a Postgres name. - * This avoids lookup failures when overlength names are given. + * Given the client encoding, truncate given database and user names to + * length of a Postgres name. This avoids lookup failures when overlength + * names are given. */ + if (client_encoding < 0) + { + /* + * client_encoding has not been found in the startup packet so let's + * try to get it from locale. + */ + client_encoding = pg_get_encoding_from_locale(NULL, true); + + if (client_encoding < 0) + client_encoding = PG_SQL_ASCII; + } + if (strlen(port->database_name) >= NAMEDATALEN) - port->database_name[NAMEDATALEN - 1] = '\0'; + { + int newlen; + + newlen = pg_encoding_mbcliplen(client_encoding, port->database_name, + strlen(port->database_name), + NAMEDATALEN - 1); + port->database_name[newlen] = '\0'; + } if (strlen(port->user_name) >= NAMEDATALEN) - port->user_name[NAMEDATALEN - 1] = '\0'; + { + int newlen; + + newlen = pg_encoding_mbcliplen(client_encoding, port->user_name, + strlen(port->user_name), + NAMEDATALEN - 1); + port->user_name[newlen] = '\0'; + } if (am_walsender) MyBackendType = B_WAL_SENDER; -- 2.34.1