Re: BUG #18711: Attempting a connection with a database name longer than 63 characters now fails

Bruce Momjian <bruce@momjian.us>

From: Bruce Momjian <bruce@momjian.us>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>, Nathan Bossart <nathandbossart@gmail.com>, adam@labkey.com, pgsql-bugs@lists.postgresql.org
Date: 2024-11-23T17:50:53Z
Lists: pgsql-bugs
On Fri, Nov 22, 2024 at 02:23:47PM -0500, Tom Lane wrote:
> +	if (strlen(dbname) < NAMEDATALEN)
> +	{
> +		/* Typical, easy case: no truncation needed */
> +		tuple = GetDatabaseTupleInternal(relation, dbname);
> +	}
> +	else if (!IS_HIGHBIT_SET(dbname[NAMEDATALEN - 1]) ||
> +			 !IS_HIGHBIT_SET(dbname[NAMEDATALEN - 2]))
> +	{
> +		/* Also easy: truncation at NAMEDATALEN - 1 cannot break an MB char */
> +		memcpy(tname, dbname, sizeof(tname));
> +		tname[NAMEDATALEN - 1] = '\0';
> +		tuple = GetDatabaseTupleInternal(relation, tname);

I had some time to think about this issue and I now realize the test
above is correct, but I couldn't figure out why it was correct before.
If we want to use this test, which I now think is fine, I suggest the
following comment:

	If we put a NULL byte at byte offset NAMEDATALEN - 1, we don't want
	to break a multi-byte character when doing this.  If byte offset
	NAMEDATALEN - 1 does not have its high bit set, we can be sure
	we will not break a multi-byte character during the overwrite.
	Also, if NAMEDATALEN - 2 does not have its high bit set, then
	NAMEDATALEN - 1 is either a single-byte non-ASCII character,
	or is the _start_ of a multi-byte character, so it is also safe
	to overwrite it without breaking a multi-byte character.

Sorry I did not figure this out earlier.

-- 
  Bruce Momjian  <bruce@momjian.us>        https://momjian.us
  EDB                                      https://enterprisedb.com

  When a patient asks the doctor, "Am I going to die?", he means 
  "Am I going to die soon?"



Commits

  1. Revert "Don't truncate database and user names in startup packets."

  2. Don't truncate database and user names in startup packets.

  3. Truncate incoming username and database name to NAMEDATALEN-1 characters