From ffeadb09e8ab55b5a677716c6f7ebdafba778d38 Mon Sep 17 00:00:00 2001
From: Nikita Glukhov <n.gluhov@postgrespro.ru>
Date: Mon, 29 Aug 2022 23:53:06 +0300
Subject: [PATCH v9 1/9] Add safe input function for bool

---
 src/backend/utils/adt/bool.c | 33 +++++++++++++++++++++------------
 src/include/utils/builtins.h |  1 +
 2 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/src/backend/utils/adt/bool.c b/src/backend/utils/adt/bool.c
index cd7335287f9..2494f441285 100644
--- a/src/backend/utils/adt/bool.c
+++ b/src/backend/utils/adt/bool.c
@@ -126,12 +126,10 @@ parse_bool_with_len(const char *value, size_t len, bool *result)
  *
  * In the switch statement, check the most-used possibilities first.
  */
-Datum
-boolin(PG_FUNCTION_ARGS)
+bool
+boolin_opt_error(const char *in_str, size_t	len, bool *error)
 {
-	const char *in_str = PG_GETARG_CSTRING(0);
 	const char *str;
-	size_t		len;
 	bool		result;
 
 	/*
@@ -139,22 +137,33 @@ boolin(PG_FUNCTION_ARGS)
 	 */
 	str = in_str;
 	while (isspace((unsigned char) *str))
+	{
 		str++;
+		len--;
+	}
 
-	len = strlen(str);
 	while (len > 0 && isspace((unsigned char) str[len - 1]))
 		len--;
 
 	if (parse_bool_with_len(str, len, &result))
-		PG_RETURN_BOOL(result);
+		return result;
+
+	if (!error)
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+				 errmsg("invalid input syntax for type %s: \"%s\"",
+						"boolean", in_str)));
 
-	ereport(ERROR,
-			(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
-			 errmsg("invalid input syntax for type %s: \"%s\"",
-					"boolean", in_str)));
+	*error = true;
+	return false;
+}
+
+Datum
+boolin(PG_FUNCTION_ARGS)
+{
+	char	   *str = PG_GETARG_CSTRING(0);
 
-	/* not reached */
-	PG_RETURN_BOOL(false);
+	PG_RETURN_BOOL(boolin_opt_error(str, strlen(str), NULL));
 }
 
 /*
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 221c3e6c3de..2c03ce4fe12 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -24,6 +24,7 @@
 /* bool.c */
 extern bool parse_bool(const char *value, bool *result);
 extern bool parse_bool_with_len(const char *value, size_t len, bool *result);
+extern bool boolin_opt_error(const char *value, size_t	len, bool *error);
 
 /* domains.c */
 extern void domain_check(Datum value, bool isnull, Oid domainType,
-- 
2.17.1

