aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/arrayutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/arrayutils.c')
-rw-r--r--src/backend/utils/adt/arrayutils.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/src/backend/utils/adt/arrayutils.c b/src/backend/utils/adt/arrayutils.c
index 2a6a05718f8..6988edd9361 100644
--- a/src/backend/utils/adt/arrayutils.c
+++ b/src/backend/utils/adt/arrayutils.c
@@ -16,6 +16,7 @@
#include "postgres.h"
#include "catalog/pg_type.h"
+#include "common/int.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
@@ -112,6 +113,36 @@ ArrayGetNItems(int ndim, const int *dims)
}
/*
+ * Verify sanity of proposed lower-bound values for an array
+ *
+ * The lower-bound values must not be so large as to cause overflow when
+ * calculating subscripts, e.g. lower bound 2147483640 with length 10
+ * must be disallowed. We actually insist that dims[i] + lb[i] be
+ * computable without overflow, meaning that an array with last subscript
+ * equal to INT_MAX will be disallowed.
+ *
+ * It is assumed that the caller already called ArrayGetNItems, so that
+ * overflowed (negative) dims[] values have been eliminated.
+ */
+void
+ArrayCheckBounds(int ndim, const int *dims, const int *lb)
+{
+ int i;
+
+ for (i = 0; i < ndim; i++)
+ {
+ /* PG_USED_FOR_ASSERTS_ONLY prevents variable-isn't-read warnings */
+ int32 sum PG_USED_FOR_ASSERTS_ONLY;
+
+ if (pg_add_s32_overflow(dims[i], lb[i], &sum))
+ ereport(ERROR,
+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+ errmsg("array lower bound is too large: %d",
+ lb[i])));
+ }
+}
+
+/*
* Compute ranges (sub-array dimensions) for an array slice
*
* We assume caller has validated slice endpoints, so overflow is impossible