0003-Fix-pg_isblank.patch
text/plain
Patch
Format: format-patch
Series: patch 0003
Subject: Fix pg_isblank()
| File | + | − |
|---|---|---|
| src/backend/libpq/auth.c | 13 | 4 |
| src/backend/libpq/hba.c | 2 | 13 |
| src/include/libpq/hba.h | 0 | 1 |
From cd7e6fa5d2e0145bf961be55b3aed25faa3d7637 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 21 Nov 2025 13:59:28 +0100
Subject: [PATCH 3/4] 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. The hba parsing uses the standard
isblank(). pg_isblank() is removed.
---
src/backend/libpq/auth.c | 17 +++++++++++++----
src/backend/libpq/hba.c | 15 ++-------------
src/include/libpq/hba.h | 1 -
3 files changed, 15 insertions(+), 18 deletions(-)
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index ec4dbacf015..5854a2433bb 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -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;
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 97a3586000b..787aee49d24 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -138,17 +138,6 @@ static int regexec_auth_token(const char *match, AuthToken *token,
static void tokenize_error_callback(void *arg);
-/*
- * isblank() exists in the ISO C99 spec, but it's not very portable yet,
- * so provide our own version.
- */
-bool
-pg_isblank(const char c)
-{
- return c == ' ' || c == '\t' || c == '\r';
-}
-
-
/*
* Grab one token out of the string pointed to by *lineptr.
*
@@ -198,7 +187,7 @@ next_token(char **lineptr, StringInfo buf,
*terminating_comma = false;
/* Move over any whitespace and commas preceding the next token */
- while ((c = (*(*lineptr)++)) != '\0' && (pg_isblank(c) || c == ','))
+ while ((c = (*(*lineptr)++)) != '\0' && (isblank((unsigned char) c) || c == ','))
;
/*
@@ -206,7 +195,7 @@ next_token(char **lineptr, StringInfo buf,
* unquoted whitespace.
*/
while (c != '\0' &&
- (!pg_isblank(c) || in_quote))
+ (!isblank((unsigned char) c) || in_quote))
{
/* skip comments to EOL */
if (c == '#' && !in_quote)
diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h
index e3748d3c8c9..7b93ba4a709 100644
--- a/src/include/libpq/hba.h
+++ b/src/include/libpq/hba.h
@@ -181,7 +181,6 @@ extern int check_usermap(const char *usermap_name,
bool case_insensitive);
extern HbaLine *parse_hba_line(TokenizedAuthLine *tok_line, int elevel);
extern IdentLine *parse_ident_line(TokenizedAuthLine *tok_line, int elevel);
-extern bool pg_isblank(const char c);
extern FILE *open_auth_file(const char *filename, int elevel, int depth,
char **err_msg);
extern void free_auth_file(FILE *file, int depth);
--
2.51.0