1
0
mirror of https://github.com/postgres/postgres.git synced 2025-12-16 16:42:29 +03:00

Fix pg_isblank()

There was a pg_isblank() function that claimed to be a replacement for
the standard isblank() function, which was thought to be "not very
portable yet".  We can now assume that it's portable (it's in C99).

But pg_isblank() actually diverged from the standard isblank() by also
accepting '\r', while the standard one only accepts space and tab.
This was added to support parsing pg_hba.conf under Windows.  But the
hba parsing code now works completely differently and already handles
line endings before we get to pg_isblank().  The other user of
pg_isblank() is for ident protocol message parsing, which also handles
'\r' separately.  So this behavior is now obsolete and confusing.

To improve clarity, I separated those concerns.  The ident parsing now
gets its own function that hardcodes the whitespace characters
mentioned by the relevant RFC.  pg_isblank() is now static in hba.c
and is a wrapper around the standard isblank(), with some extra logic
to ensure robust treatment of non-ASCII characters.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://www.postgresql.org/message-id/flat/170308e6-a7a3-4484-87b2-f960bb564afa%40eisentraut.org
This commit is contained in:
Peter Eisentraut
2025-11-28 07:53:12 +01:00
parent e68b6adad9
commit 8b3e2c622a
3 changed files with 16 additions and 11 deletions

View File

@@ -1580,6 +1580,15 @@ pg_SSPI_make_upn(char *accountname,
*----------------------------------------------------------------
*/
/*
* Per RFC 1413, space and tab are whitespace in ident messages.
*/
static bool
is_ident_whitespace(const char c)
{
return c == ' ' || c == '\t';
}
/*
* Parse the string "*ident_response" as a response from a query to an Ident
* server. If it's a normal response indicating a user name, return true
@@ -1613,14 +1622,14 @@ interpret_ident_response(const char *ident_response,
int i; /* Index into *response_type */
cursor++; /* Go over colon */
while (pg_isblank(*cursor))
while (is_ident_whitespace(*cursor))
cursor++; /* skip blanks */
i = 0;
while (*cursor != ':' && *cursor != '\r' && !pg_isblank(*cursor) &&
while (*cursor != ':' && *cursor != '\r' && !is_ident_whitespace(*cursor) &&
i < (int) (sizeof(response_type) - 1))
response_type[i++] = *cursor++;
response_type[i] = '\0';
while (pg_isblank(*cursor))
while (is_ident_whitespace(*cursor))
cursor++; /* skip blanks */
if (strcmp(response_type, "USERID") != 0)
return false;
@@ -1643,7 +1652,7 @@ interpret_ident_response(const char *ident_response,
else
{
cursor++; /* Go over colon */
while (pg_isblank(*cursor))
while (is_ident_whitespace(*cursor))
cursor++; /* skip blanks */
/* Rest of line is user name. Copy it over. */
i = 0;