v9-0003-Add-safe-input-function-for-float4.patch

text/x-patch

Filename: v9-0003-Add-safe-input-function-for-float4.patch
Type: text/x-patch
Part: 2
Message: Re: SQL/JSON features for v15

Patch

Format: format-patch
Series: patch v9-0003
Subject: Add safe input function for float4
File+
src/backend/utils/adt/float.c 39 31
src/include/utils/float.h 1 0
From 9f4179494ef4612eadd8c2c6787391d85347fa4d Mon Sep 17 00:00:00 2001
From: Nikita Glukhov <n.gluhov@postgrespro.ru>
Date: Tue, 30 Aug 2022 00:13:36 +0300
Subject: [PATCH v9 3/9] Add safe input function for float4

---
 src/backend/utils/adt/float.c | 70 +++++++++++++++++++----------------
 src/include/utils/float.h     |  1 +
 2 files changed, 40 insertions(+), 31 deletions(-)

diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index fc8f39a7a98..d9da8c8466d 100644
--- a/src/backend/utils/adt/float.c
+++ b/src/backend/utils/adt/float.c
@@ -73,6 +73,16 @@ static double sind_q1(double x);
 static double cosd_q1(double x);
 static void init_degree_constants(void);
 
+/* Convenience macro: set *have_error flag (if provided) or throw error */
+#define RETURN_ERROR(throw_error, have_error) \
+do { \
+	if (have_error) { \
+		*have_error = true; \
+		return 0.0; \
+	} else { \
+		throw_error; \
+	} \
+} while (0)
 
 /*
  * We use these out-of-line ereport() calls to report float overflow,
@@ -159,10 +169,9 @@ is_infinite(double val)
  * result of 0xAE43FEp-107.
  *
  */
-Datum
-float4in(PG_FUNCTION_ARGS)
+float
+float4in_opt_error(char	*num, bool *have_error)
 {
-	char	   *num = PG_GETARG_CSTRING(0);
 	char	   *orig_num;
 	float		val;
 	char	   *endptr;
@@ -183,10 +192,11 @@ float4in(PG_FUNCTION_ARGS)
 	 * strtod() on different platforms.
 	 */
 	if (*num == '\0')
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
-				 errmsg("invalid input syntax for type %s: \"%s\"",
-						"real", orig_num)));
+		RETURN_ERROR(ereport(ERROR,
+							 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+							  errmsg("invalid input syntax for type %s: \"%s\"",
+									 "real", orig_num))),
+					 have_error);
 
 	errno = 0;
 	val = strtof(num, &endptr);
@@ -257,16 +267,18 @@ float4in(PG_FUNCTION_ARGS)
 				(val >= HUGE_VALF || val <= -HUGE_VALF)
 #endif
 				)
-				ereport(ERROR,
-						(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-						 errmsg("\"%s\" is out of range for type real",
-								orig_num)));
+				RETURN_ERROR(ereport(ERROR,
+									 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+									  errmsg("\"%s\" is out of range for type real",
+											 orig_num))),
+							 have_error);
 		}
 		else
-			ereport(ERROR,
-					(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
-					 errmsg("invalid input syntax for type %s: \"%s\"",
-							"real", orig_num)));
+			RETURN_ERROR(ereport(ERROR,
+								 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+								  errmsg("invalid input syntax for type %s: \"%s\"",
+										 "real", orig_num))),
+						 have_error);
 	}
 
 	/* skip trailing whitespace */
@@ -275,12 +287,19 @@ float4in(PG_FUNCTION_ARGS)
 
 	/* if there is any junk left at the end of the string, bail out */
 	if (*endptr != '\0')
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
-				 errmsg("invalid input syntax for type %s: \"%s\"",
-						"real", orig_num)));
+		RETURN_ERROR(ereport(ERROR,
+							 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+							  errmsg("invalid input syntax for type %s: \"%s\"",
+									 "real", orig_num))),
+					 have_error);
+
+	return val;
+}
 
-	PG_RETURN_FLOAT4(val);
+Datum
+float4in(PG_FUNCTION_ARGS)
+{
+	PG_RETURN_FLOAT4(float4in_opt_error(PG_GETARG_CSTRING(0), NULL));
 }
 
 /*
@@ -340,17 +359,6 @@ float8in(PG_FUNCTION_ARGS)
 	PG_RETURN_FLOAT8(float8in_internal(num, NULL, "double precision", num));
 }
 
-/* Convenience macro: set *have_error flag (if provided) or throw error */
-#define RETURN_ERROR(throw_error, have_error) \
-do { \
-	if (have_error) { \
-		*have_error = true; \
-		return 0.0; \
-	} else { \
-		throw_error; \
-	} \
-} while (0)
-
 /*
  * float8in_internal_opt_error - guts of float8in()
  *
diff --git a/src/include/utils/float.h b/src/include/utils/float.h
index 4bf0e3ac07a..0ad4d9f3973 100644
--- a/src/include/utils/float.h
+++ b/src/include/utils/float.h
@@ -46,6 +46,7 @@ extern float8 float8in_internal(char *num, char **endptr_p,
 extern float8 float8in_internal_opt_error(char *num, char **endptr_p,
 										  const char *type_name, const char *orig_string,
 										  bool *have_error);
+extern float float4in_opt_error(char *num, bool *have_error);
 extern char *float8out_internal(float8 num);
 extern int	float4_cmp_internal(float4 a, float4 b);
 extern int	float8_cmp_internal(float8 a, float8 b);
-- 
2.17.1