since-v3.diff.txt

text/plain

Filename: since-v3.diff.txt
Type: text/plain
Part: 0
Message: Re: [PATCH] Log details for client certificate failures
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 5318719acb..1394ecaa2b 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -1116,7 +1116,7 @@ prepare_cert_name(char *name)
 
 #undef MAXLEN
 
-	return pg_clean_ascii(truncated);
+	return pg_clean_ascii(truncated, 0);
 }
 
 /*
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 5e8cd770c0..52fb2e52f1 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -2284,7 +2284,7 @@ retry1:
 				 */
 				if (strcmp(nameptr, "application_name") == 0)
 				{
-					port->application_name = pg_clean_ascii(valptr);
+					port->application_name = pg_clean_ascii(valptr, 0);
 				}
 			}
 			offset = valoffset + strlen(valptr) + 1;
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 60400752e5..2f99fe9a6d 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -12479,9 +12479,18 @@ assign_maintenance_io_concurrency(int newval, void *extra)
 static bool
 check_application_name(char **newval, void **extra, GucSource source)
 {
+	char	   *clean;
+
 	/* Only allow clean ASCII chars in the application name */
-	*newval = guc_strdup(ERROR, pg_clean_ascii(*newval));
+	clean = pg_clean_ascii(*newval, MCXT_ALLOC_NO_OOM);
+	if (!clean)
+		return false;
+
+	clean = guc_strdup(WARNING, clean);
+	if (!clean)
+		return false;
 
+	*newval = clean;
 	return true;
 }
 
@@ -12495,9 +12504,18 @@ assign_application_name(const char *newval, void *extra)
 static bool
 check_cluster_name(char **newval, void **extra, GucSource source)
 {
+	char	   *clean;
+
 	/* Only allow clean ASCII chars in the cluster name */
-	*newval = guc_strdup(ERROR, pg_clean_ascii(*newval));
+	clean = pg_clean_ascii(*newval, MCXT_ALLOC_NO_OOM);
+	if (!clean)
+		return false;
+
+	clean = guc_strdup(WARNING, clean);
+	if (!clean)
+		return false;
 
+	*newval = clean;
 	return true;
 }
 
diff --git a/src/common/string.c b/src/common/string.c
index db15324c62..97b3d45d36 100644
--- a/src/common/string.c
+++ b/src/common/string.c
@@ -62,7 +62,10 @@ strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
 /*
  * pg_clean_ascii -- Replace any non-ASCII chars with a "\xXX" string
  *
- * Makes a palloc'd copy of the string passed in, which must be '\0'-terminated.
+ * Makes a newly allocated copy of the string passed in, which must be
+ * '\0'-terminated. In the backend, additional alloc_flags may be provided and
+ * will be passed as-is to palloc_extended(); in the frontend, alloc_flags is
+ * ignored and the copy is malloc'd.
  *
  * This function exists specifically to deal with filtering out
  * non-ASCII characters in a few places where the client can provide an almost
@@ -80,23 +83,46 @@ strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
  * for now.
  */
 char *
-pg_clean_ascii(const char *str)
+pg_clean_ascii(const char *str, int alloc_flags)
 {
-	StringInfoData buf;
-	const char   *p;
+	size_t		dstlen;
+	char	   *dst;
+	const char *p;
+	size_t		i = 0;
 
-	initStringInfo(&buf);
+	/* Worst case, each byte can become four bytes, plus a null terminator. */
+	dstlen = strlen(str) * 4 + 1;
+
+#ifdef FRONTEND
+	dst = malloc(dstlen);
+#else
+	dst = palloc_extended(dstlen, alloc_flags);
+#endif
+
+	if (!dst)
+		return NULL;
 
 	for (p = str; *p != '\0'; p++)
 	{
+
 		/* Only allow clean ASCII chars in the string */
 		if (*p < 32 || *p > 126)
-			appendStringInfo(&buf, "\\x%02x", (unsigned char) *p);
+		{
+			Assert(i < (dstlen - 3));
+			snprintf(&dst[i], dstlen - i, "\\x%02x", (unsigned char) *p);
+			i += 4;
+		}
 		else
-			appendStringInfoChar(&buf, *p);
+		{
+			Assert(i < dstlen);
+			dst[i] = *p;
+			i++;
+		}
 	}
 
-	return buf.data;
+	Assert(i < dstlen);
+	dst[i] = '\0';
+	return dst;
 }
 
 
diff --git a/src/include/common/string.h b/src/include/common/string.h
index d10d0c9cbf..3d59172151 100644
--- a/src/include/common/string.h
+++ b/src/include/common/string.h
@@ -24,7 +24,7 @@ typedef struct PromptInterruptContext
 extern bool pg_str_endswith(const char *str, const char *end);
 extern int	strtoint(const char *pg_restrict str, char **pg_restrict endptr,
 					 int base);
-extern char *pg_clean_ascii(const char *str);
+extern char *pg_clean_ascii(const char *str, int alloc_flags);
 extern int	pg_strip_crlf(char *str);
 extern bool pg_is_ascii(const char *str);