From 0e20d90ab016b7ac926feba765f62d8b64017d50 Mon Sep 17 00:00:00 2001 From: Jeevan Ladhe Date: Sun, 4 Aug 2019 09:08:20 +0530 Subject: [PATCH] Make have_error initialization more defensive v3 Basically get rid of the dependency to have caller initalize the flag. This patch addresses such occurrences in following functions: pg_lsn_in_internal(), float8in_internal_opt_error(), numeric_mod_opt_error(), numeric_div_opt_error() and numeric_mod_opt_error(). Also, add have_error flag to macro RETURN_ERROR to make the references more readable in float.c Jeevan Ladhe --- src/backend/utils/adt/float.c | 44 ++++++++++++++++++----------------- src/backend/utils/adt/jsonpath_exec.c | 6 ++--- src/backend/utils/adt/numeric.c | 9 +++++++ src/backend/utils/adt/pg_lsn.c | 5 +++- src/backend/utils/misc/guc.c | 2 +- 5 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c index 7540ca2..219a0bb 100644 --- a/src/backend/utils/adt/float.c +++ b/src/backend/utils/adt/float.c @@ -337,10 +337,10 @@ float8in(PG_FUNCTION_ARGS) } /* Convenience macro: set *have_error flag (if provided) or throw error */ -#define RETURN_ERROR(throw_error) \ +#define RETURN_ERROR(have_error, throw_error) \ do { \ if (have_error) { \ - *have_error = true; \ + *(have_error) = true; \ return 0.0; \ } else { \ throw_error; \ @@ -376,6 +376,9 @@ float8in_internal_opt_error(char *num, char **endptr_p, double val; char *endptr; + if (have_error) + *have_error = false; + /* skip leading whitespace */ while (*num != '\0' && isspace((unsigned char) *num)) num++; @@ -385,10 +388,10 @@ float8in_internal_opt_error(char *num, char **endptr_p, * strtod() on different platforms. */ if (*num == '\0') - RETURN_ERROR(ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type %s: \"%s\"", - type_name, orig_string)))); + RETURN_ERROR(have_error, ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type %s: \"%s\"", + type_name, orig_string)))); errno = 0; val = strtod(num, &endptr); @@ -461,19 +464,18 @@ float8in_internal_opt_error(char *num, char **endptr_p, char *errnumber = pstrdup(num); errnumber[endptr - num] = '\0'; - RETURN_ERROR(ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("\"%s\" is out of range for " - "type double precision", - errnumber)))); + RETURN_ERROR(have_error, ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("\"%s\" is out of range for type double precision", + errnumber)))); } } else - RETURN_ERROR(ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type " - "%s: \"%s\"", - type_name, orig_string)))); + RETURN_ERROR(have_error, ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type " + "%s: \"%s\"", + type_name, orig_string)))); } #ifdef HAVE_BUGGY_SOLARIS_STRTOD else @@ -496,11 +498,11 @@ float8in_internal_opt_error(char *num, char **endptr_p, if (endptr_p) *endptr_p = endptr; else if (*endptr != '\0') - RETURN_ERROR(ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type " - "%s: \"%s\"", - type_name, orig_string)))); + RETURN_ERROR(have_error, ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type " + "%s: \"%s\"", + type_name, orig_string)))); return val; } diff --git a/src/backend/utils/adt/jsonpath_exec.c b/src/backend/utils/adt/jsonpath_exec.c index 293d6da..a0ead39 100644 --- a/src/backend/utils/adt/jsonpath_exec.c +++ b/src/backend/utils/adt/jsonpath_exec.c @@ -976,7 +976,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, { char *tmp = DatumGetCString(DirectFunctionCall1(numeric_out, NumericGetDatum(jb->val.numeric))); - bool have_error = false; + bool have_error; (void) float8in_internal_opt_error(tmp, NULL, @@ -997,7 +997,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, double val; char *tmp = pnstrdup(jb->val.string.val, jb->val.string.len); - bool have_error = false; + bool have_error; val = float8in_internal_opt_error(tmp, NULL, @@ -1521,7 +1521,7 @@ executeBinaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp, } else { - bool error = false; + bool error; res = func(lval->val.numeric, rval->val.numeric, &error); diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c index 201784b..7b0874b 100644 --- a/src/backend/utils/adt/numeric.c +++ b/src/backend/utils/adt/numeric.c @@ -2605,6 +2605,9 @@ numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error) Numeric res; int rscale; + if(have_error) + *have_error = false; + /* * Handle NaN */ @@ -2721,6 +2724,9 @@ numeric_mod_opt_error(Numeric num1, Numeric num2, bool *have_error) NumericVar arg2; NumericVar result; + if (have_error) + *have_error = false; + if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2)) return make_result(&const_nan); @@ -6249,6 +6255,9 @@ make_result_opt_error(const NumericVar *var, bool *have_error) int n; Size len; + if (have_error) + *have_error = false; + if (sign == NUMERIC_NAN) { result = (Numeric) palloc(NUMERIC_HDRSZ_SHORT); diff --git a/src/backend/utils/adt/pg_lsn.c b/src/backend/utils/adt/pg_lsn.c index b4c6c23..90e9b8c 100644 --- a/src/backend/utils/adt/pg_lsn.c +++ b/src/backend/utils/adt/pg_lsn.c @@ -34,6 +34,9 @@ pg_lsn_in_internal(const char *str, bool *have_error) off; XLogRecPtr result; + Assert(have_error != NULL); + *have_error = false; + /* Sanity check input format. */ len1 = strspn(str, "0123456789abcdefABCDEF"); if (len1 < 1 || len1 > MAXPG_LSNCOMPONENT || str[len1] != '/') @@ -61,7 +64,7 @@ pg_lsn_in(PG_FUNCTION_ARGS) { char *str = PG_GETARG_CSTRING(0); XLogRecPtr result; - bool have_error = false; + bool have_error; result = pg_lsn_in_internal(str, &have_error); if (have_error) diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index fc46360..ce179fc 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -11677,7 +11677,7 @@ check_recovery_target_lsn(char **newval, void **extra, GucSource source) { XLogRecPtr lsn; XLogRecPtr *myextra; - bool have_error = false; + bool have_error; lsn = pg_lsn_in_internal(*newval, &have_error); if (have_error) -- 2.7.4