ProcessStartupPacket(): database_name and user_name truncation - Mailing list pgsql-hackers
From | Drouvot, Bertrand |
---|---|
Subject | ProcessStartupPacket(): database_name and user_name truncation |
Date | |
Msg-id | 07436793-1426-29b2-f924-db7422a05fb7@gmail.com Whole thread Raw |
Responses |
Re: ProcessStartupPacket(): database_name and user_name truncation
|
List | pgsql-hackers |
Hi hackers, Please find attached a patch to truncate (in ProcessStartupPacket()) the port->database_name and port->user_name in such a way to not break multibyte character boundary. Indeed, currently, one could create a database that way: postgres=# create database ääääääääääääääääääääääääääääääää; NOTICE: identifier "ääääääääääääääääääääääääääääääää" will be truncated to "äääääääääääääääääääääääääääääää" CREATE DATABASE The database name has been truncated from 64 bytes to 62 bytes thanks to pg_mbcliplen() which ensures to not break multibyte character boundary. postgres=# select datname, OCTET_LENGTH(datname),encoding from pg_database; datname | octet_length | encoding ---------------------------------+--------------+---------- äääääääääääääääääääääääääääääää | 62 | 6 Trying to connect with the 64 bytes name: $ psql -d ääääääääääääääääääääääääääääääää psql: error: connection to server on socket "/tmp/.s.PGSQL.55448" failed: FATAL: database "äääääääääääääääääääääääääääääää"does not exist It fails because the truncation done in ProcessStartupPacket(): " if (strlen(port→database_name) >= NAMEDATALEN) port→database_name[NAMEDATALEN - 1] = '\0'; " does not take care about multibyte character boundary. On the other hand it works with non multibyte character involved: postgres=# create database abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijke; NOTICE: identifier "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijke" will be truncated to "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk" CREATE DATABASE postgres=# select datname, OCTET_LENGTH(datname),encoding from pg_database; datname | octet_length | encoding -----------------------------------------------------------------+--------------+---------- abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk | 63 | 6 The database name is truncated to 63 bytes and then using the 64 bytes name would work: $ psql -d abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijke psql (16beta1) Type "help" for help. The comment in ProcessStartupPacket() states: " /* * Truncate given database and user names to length of a Postgres name. * This avoids lookup failures when overlength names are given. */ " The last sentence is not right in case of mutlibyte character (as seen in the first example). About the patch: As the database encoding is not known yet in ProcessStartupPacket() ( and we are even not sure the database provided does exist), the proposed patch does not rely on pg_mbcliplen() but on pg_encoding_mbcliplen(). The proposed patch does use the client encoding that it retrieves that way: - use the one requested in the startup packet (if we come across it) - use the one from the locale (if we did not find a client encoding request in the startup packet) - use PG_SQL_ASCII (if none of the above have been satisfied) Happy to discuss any other thoughts or suggestions if any. With the proposed patch in place, using the first example above (and the 64 bytes name) we would get: $ PGCLIENTENCODING=LATIN1 psql -d ääääääääääääääääääääääääääääääää psql: error: connection to server on socket "/tmp/.s.PGSQL.55448" failed: FATAL: database "äääääääääääääääääääääääääääääää"does not exist but this one would allow us to connect: $ PGCLIENTENCODING=UTF8 psql -d ääääääääääääääääääääääääääääääää psql (16beta1) Type "help" for help. The patch does not provide documentation update or related TAP test (but could be added if we feel the need). Looking forward to your feedback, Regards, -- Bertrand Drouvot PostgreSQL Contributors Team RDS Open Source Databases Amazon Web Services: https://aws.amazon.com
Attachment
pgsql-hackers by date: