From 34be83b7e142a718c7a831c9df9763aa83fe4cd5 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Mon, 23 May 2011 22:18:19 +0300 Subject: [PATCH] Fix integer overflow in text_format function, reported by Dean Rasheed. In the passing, clarify the comment on why text_format_nv wrapper is needed. --- src/backend/utils/adt/varlena.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index 9d96013d57..6005d68576 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -3827,7 +3827,19 @@ text_format(PG_FUNCTION_ARGS) * to the next one. If they have, we must parse it. */ if (*cp < '0' || *cp > '9') + { ++arg; + if (arg <= 0) /* overflow? */ + { + /* + * Should not happen, as you can't pass billions of arguments + * to a function, but better safe than sorry. + */ + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("argument number is out of range"))); + } + } else { bool unterminated = false; @@ -3836,10 +3848,13 @@ text_format(PG_FUNCTION_ARGS) arg = 0; do { - /* Treat overflowing arg position as unterminated. */ - if (arg > INT_MAX / 10) - break; - arg = arg * 10 + (*cp - '0'); + int newarg = arg * 10 + (*cp - '0'); + + if (newarg / 10 != arg) /* overflow? */ + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("argument number is out of range"))); + arg = newarg; ++cp; } while (cp < end_ptr && *cp >= '0' && *cp <= '9'); @@ -3954,7 +3969,9 @@ text_format_string_conversion(StringInfo buf, char conversion, /* * text_format_nv - nonvariadic wrapper for text_format function. * - * note: this wrapper is necessary to be sanity_checks test ok + * note: this wrapper is necessary to pass the sanity check in opr_sanity, + * which checks that all built-in functions that share the implementing C + * function take the same number of arguments. */ Datum text_format_nv(PG_FUNCTION_ARGS) -- GitLab