From e57ab0456506b3f68b4d8f446c58e6677e120294 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Thu, 12 Sep 2002 00:26:00 +0000
Subject: [PATCH] This is a comprehensive set of diffs (versus current CVS)
 that replaces those attached to the same message with the Earth Distance
 patches. Recent changes include changing the subscript in one place I forgot
 in the previous bugfix patch. A couple of added regression tests, which
 should help catch this mistake if it reappears. I also put in a limit of 100
 dimensions in cube_large and cube_in to prevent making it easy to create very
 large cubes. Changing one define in cubedata.h will raise the limit if some
 needs more dimensions.

Bruno Wolff III
---
 contrib/cube/CHANGES           | 19 +++++--
 contrib/cube/README.cube       |  9 ++--
 contrib/cube/cube.c            | 28 ++++++-----
 contrib/cube/cube.sql.in       | 91 ++++++++++++++++++++++------------
 contrib/cube/cubedata.h        |  1 +
 contrib/cube/cubeparse.y       | 34 +++++++++++--
 contrib/cube/expected/cube.out | 27 ++++++++++
 contrib/cube/sql/cube.sql      | 10 ++++
 8 files changed, 160 insertions(+), 59 deletions(-)

diff --git a/contrib/cube/CHANGES b/contrib/cube/CHANGES
index bf56bf12dcc..a867e4efe36 100644
--- a/contrib/cube/CHANGES
+++ b/contrib/cube/CHANGES
@@ -1,4 +1,4 @@
-Changes that were made in August 2002.
+Changes that were made in August/September 2002 by Bruno Wolff III.
 
 Note that this was based on a 7.3 development version and changes may not
 directly work with earlier versions.
@@ -7,9 +7,6 @@ I fixed a bug in cubescan.pl that prevented signed numbers with no digits
 before a decimal point from being accepted. This was submitted as a separate
 patch and may already be applied.
 
-I reported but did not fix a potential buffer overrun problem in cube_yyerror
-in cubeparse.y.
-
 cube_inter should really return NULL if the two cubes don't overlap. However
 this requires changing to the new calling sequence and I don't know enough
 about how to do it to make the change.
@@ -42,7 +39,9 @@ larger or smaller coordinate as needed, since swap_corners was doing the
 same thing with the overhead of a function call and memory allocation.
 
 I added memset calls to zero out newly allocated NDBOXes as the documentation
-on functions indicates should be done.
+on functions indicates should be done. This still doesn't allow a hash
+index for equality since there are multiple representations of the
+same cube.
 
 I got rid of a call to cube_same in cube_lt and cube_gt since the test
 was redundant with other checks being made. The call to cube_same would
@@ -94,4 +93,14 @@ I added regression tests for the new functions.
 I added documentation for cube_distance and the new functions to README.cube
 as well as making a few other minor changes.
 
+I changed create function to create or replace function in the install
+script.
+
+I limited the number of dimensions allowed in cube_enlarge and cube_in
+to 100 to make it harder for people to mess up the database. The constant
+is defined in cubedata.h and can be increased if you need something larger.
+
+I added grant statements to the install script to make the functions
+executable to everyone.
+
 Bruno Wolff III <bruno@wolff.to>
diff --git a/contrib/cube/README.cube b/contrib/cube/README.cube
index 6cd57ab3534..93ba63dd78d 100644
--- a/contrib/cube/README.cube
+++ b/contrib/cube/README.cube
@@ -42,7 +42,7 @@ For this to work, make sure that:
   postgres binaries in the PATH.
 
 This only installs the type implementation and documentation.  To make the
-type available in any particular database, do
+type available in any particular database, as a postgres superuser do:
 
 	psql -d databasename < cube.sql
 
@@ -57,6 +57,7 @@ If it fails, examine the file regression.diffs to find out the reason (the
 test code is a direct adaptation of the regression tests from the main
 source tree).
 
+By default the external functions are made executable by anyone.
 
 SYNTAX
 ======
@@ -289,7 +290,9 @@ cube_enlarge(cube, double, int) returns cube
   LL coordinates are decreased by r and UR coordinates are increased by r. If
   a LL coordinate is increased to larger than the corresponding UR coordinate
   (this can only happen when r < 0) than both coordinates are set to their
-  average.
+  average. To make it harder for people to break things there is an effective
+  maximum on the dimension of cubes of 100. This is set in cubedata.h if
+  you need something bigger.
 
 There are a few other potentially useful functions defined in cube.c 
 that vanished from the schema because I stopped using them. Some of 
@@ -329,7 +332,7 @@ selkovjr@mcs.anl.gov
 ------------------------------------------------------------------------
 
 Minor updates to this package were made by Bruno Wolff III <bruno@wolff.to>
-in August of 2002.
+in August/September of 2002.
 
 These include changing the precision from single precision to double
 precision and adding some new functions.
diff --git a/contrib/cube/cube.c b/contrib/cube/cube.c
index bf3dd8dfbf2..98c6167e625 100644
--- a/contrib/cube/cube.c
+++ b/contrib/cube/cube.c
@@ -73,11 +73,11 @@ bool		cube_right(NDBOX * a, NDBOX * b);
 bool		cube_lt(NDBOX * a, NDBOX * b);
 bool		cube_gt(NDBOX * a, NDBOX * b);
 double	   *cube_distance(NDBOX * a, NDBOX * b);
-int			cube_dim(NDBOX * a);
-double	   *cube_ll_coord(NDBOX * a, int n);
-double	   *cube_ur_coord(NDBOX * a, int n);
+int4			cube_dim(NDBOX * a);
+double	   *cube_ll_coord(NDBOX * a, int4 n);
+double	   *cube_ur_coord(NDBOX * a, int4 n);
 bool		cube_is_point(NDBOX * a);
-NDBOX	   *cube_enlarge(NDBOX * a, double *r, int n);
+NDBOX	   *cube_enlarge(NDBOX * a, double *r, int4 n);
 
 
 /*
@@ -1139,7 +1139,7 @@ cube_is_point(NDBOX * a)
 }
 
 /* Return dimensions in use in the data structure */
-int
+int4
 cube_dim(NDBOX * a)
 {
 	/* Other things will break before unsigned int doesn't fit. */
@@ -1148,7 +1148,7 @@ cube_dim(NDBOX * a)
 
 /* Return a specific normalized LL coordinate */
 double *
-cube_ll_coord(NDBOX * a, int n)
+cube_ll_coord(NDBOX * a, int4 n)
 {
 	double	   *result;
 
@@ -1161,7 +1161,7 @@ cube_ll_coord(NDBOX * a, int n)
 
 /* Return a specific normalized UR coordinate */
 double *
-cube_ur_coord(NDBOX * a, int n)
+cube_ur_coord(NDBOX * a, int4 n)
 {
 	double	   *result;
 
@@ -1174,14 +1174,16 @@ cube_ur_coord(NDBOX * a, int n)
 
 /* Increase or decrease box size by a radius in at least n dimensions. */
 NDBOX *
-cube_enlarge(NDBOX * a, double *r, int n)
+cube_enlarge(NDBOX * a, double *r, int4 n)
 {
 	NDBOX	   *result;
 	int			dim = 0;
 	int			size;
 	int			i,
-				j;
+				j,
+				k;
 
+	if (n > CUBE_MAX_DIM) n = CUBE_MAX_DIM;
 	if (*r > 0 && n > 0)
 		dim = n;
 	if (a->dim > dim)
@@ -1191,17 +1193,17 @@ cube_enlarge(NDBOX * a, double *r, int n)
 	memset(result, 0, size);
 	result->size = size;
 	result->dim = dim;
-	for (i = 0, j = dim; i < a->dim; i++, j++)
+	for (i = 0, j = dim, k = a->dim; i < a->dim; i++, j++, k++)
 	{
-		if (a->x[i] >= a->x[j])
+		if (a->x[i] >= a->x[k])
 		{
-			result->x[i] = a->x[j] - *r;
+			result->x[i] = a->x[k] - *r;
 			result->x[j] = a->x[i] + *r;
 		}
 		else
 		{
 			result->x[i] = a->x[i] - *r;
-			result->x[j] = a->x[j] + *r;
+			result->x[j] = a->x[k] + *r;
 		}
 		if (result->x[i] > result->x[j])
 		{
diff --git a/contrib/cube/cube.sql.in b/contrib/cube/cube.sql.in
index ecc9215070f..e54f10c0462 100644
--- a/contrib/cube/cube.sql.in
+++ b/contrib/cube/cube.sql.in
@@ -1,16 +1,16 @@
 -- Create the user-defined type for N-dimensional boxes
 -- 
-BEGIN TRANSACTION;
+BEGIN;
 
 -- Adjust this setting to control where the objects get created.
 SET search_path = public;
 
-CREATE FUNCTION cube_in(cstring)
+CREATE OR REPLACE FUNCTION cube_in(cstring)
 RETURNS cube
 AS 'MODULE_PATHNAME'
 LANGUAGE 'c'IMMUTABLE STRICT;
 
-CREATE FUNCTION cube_out(cube)
+CREATE OR REPLACE FUNCTION cube_out(cube)
 RETURNS cstring
 AS 'MODULE_PATHNAME'
 LANGUAGE 'c'IMMUTABLE STRICT;
@@ -26,8 +26,7 @@ COMMENT ON TYPE cube IS
 
 -- Convert from text to cube
 
-CREATE FUNCTION cube(text)
-RETURNS cube
+CREATE OR REPLACE FUNCTION cube(text) RETURNS cube
 AS 'MODULE_PATHNAME'
 LANGUAGE 'c' IMMUTABLE STRICT;
 
@@ -40,25 +39,25 @@ COMMENT ON FUNCTION cube(text) IS
 
 -- Left/Right methods
 
-CREATE FUNCTION cube_over_left(cube, cube) RETURNS bool
+CREATE OR REPLACE FUNCTION cube_over_left(cube, cube) RETURNS bool
 	AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
 COMMENT ON FUNCTION cube_over_left(cube, cube) IS
 'is over and left of (NOT IMPLEMENTED)';
 
-CREATE FUNCTION cube_over_right(cube, cube) RETURNS bool
+CREATE OR REPLACE FUNCTION cube_over_right(cube, cube) RETURNS bool
 	AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
 COMMENT ON FUNCTION cube_over_right(cube, cube) IS
 'is over and right of (NOT IMPLEMENTED)';
 
-CREATE FUNCTION cube_left(cube, cube) RETURNS bool
+CREATE OR REPLACE FUNCTION cube_left(cube, cube) RETURNS bool
 	AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
 COMMENT ON FUNCTION cube_left(cube, cube) IS
 'is left of (NOT IMPLEMENTED)';
 
-CREATE FUNCTION cube_right(cube, cube) RETURNS bool
+CREATE OR REPLACE FUNCTION cube_right(cube, cube) RETURNS bool
 	AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
 COMMENT ON FUNCTION cube_right(cube, cube) IS
@@ -67,43 +66,43 @@ COMMENT ON FUNCTION cube_right(cube, cube) IS
 
 -- Comparison methods
 
-CREATE FUNCTION cube_lt(cube, cube) RETURNS bool
+CREATE OR REPLACE FUNCTION cube_lt(cube, cube) RETURNS bool
 	AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
 COMMENT ON FUNCTION cube_lt(cube, cube) IS
 'lower than';
 
-CREATE FUNCTION cube_gt(cube, cube) RETURNS bool
+CREATE OR REPLACE FUNCTION cube_gt(cube, cube) RETURNS bool
 	AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
 COMMENT ON FUNCTION cube_gt(cube, cube) IS
 'greater than';
 
-CREATE FUNCTION cube_contains(cube, cube) RETURNS bool
+CREATE OR REPLACE FUNCTION cube_contains(cube, cube) RETURNS bool
 	AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
 COMMENT ON FUNCTION cube_contains(cube, cube) IS
 'contains';
 
-CREATE FUNCTION cube_contained(cube, cube) RETURNS bool
+CREATE OR REPLACE FUNCTION cube_contained(cube, cube) RETURNS bool
 	AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
 COMMENT ON FUNCTION cube_contained(cube, cube) IS
 'contained in';
 
-CREATE FUNCTION cube_overlap(cube, cube) RETURNS bool
+CREATE OR REPLACE FUNCTION cube_overlap(cube, cube) RETURNS bool
 	AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
 COMMENT ON FUNCTION cube_overlap(cube, cube) IS
 'overlaps';
 
-CREATE FUNCTION cube_same(cube, cube) RETURNS bool
+CREATE OR REPLACE FUNCTION cube_same(cube, cube) RETURNS bool
 	AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
 COMMENT ON FUNCTION cube_same(cube, cube) IS
 'same as';
 
-CREATE FUNCTION cube_different(cube, cube) RETURNS bool
+CREATE OR REPLACE FUNCTION cube_different(cube, cube) RETURNS bool
 	AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
 COMMENT ON FUNCTION cube_different(cube, cube) IS
@@ -111,13 +110,13 @@ COMMENT ON FUNCTION cube_different(cube, cube) IS
 
 -- support routines for indexing
 
-CREATE FUNCTION cube_union(cube, cube) RETURNS cube
+CREATE OR REPLACE FUNCTION cube_union(cube, cube) RETURNS cube
 	AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
-CREATE FUNCTION cube_inter(cube, cube) RETURNS cube
+CREATE OR REPLACE FUNCTION cube_inter(cube, cube) RETURNS cube
 	AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
-CREATE FUNCTION cube_size(cube) RETURNS float8
+CREATE OR REPLACE FUNCTION cube_size(cube) RETURNS float8
 	AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
 
@@ -125,28 +124,28 @@ CREATE FUNCTION cube_size(cube) RETURNS float8
 
 -- proximity routines
 
-CREATE FUNCTION cube_distance(cube, cube) RETURNS float8
+CREATE OR REPLACE FUNCTION cube_distance(cube, cube) RETURNS float8
 	AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
 -- Extracting elements functions
 
-CREATE FUNCTION cube_dim(cube) RETURNS int4
+CREATE OR REPLACE FUNCTION cube_dim(cube) RETURNS int4
         AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
-CREATE FUNCTION cube_ll_coord(cube, int4) RETURNS float8
+CREATE OR REPLACE FUNCTION cube_ll_coord(cube, int4) RETURNS float8
         AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
-CREATE FUNCTION cube_ur_coord(cube, int4) RETURNS float8
+CREATE OR REPLACE FUNCTION cube_ur_coord(cube, int4) RETURNS float8
         AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
 -- Test if cube is also a point
 
-CREATE FUNCTION cube_is_point(cube) RETURNS bool
+CREATE OR REPLACE FUNCTION cube_is_point(cube) RETURNS bool
         AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
 -- Increasing the size of a cube by a radius in at least n dimensions
 
-CREATE FUNCTION cube_enlarge(cube, float8, int4) RETURNS cube
+CREATE OR REPLACE FUNCTION cube_enlarge(cube, float8, int4) RETURNS cube
         AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
 
 --
@@ -222,25 +221,25 @@ CREATE OPERATOR ~ (
 
 
 -- define the GiST support methods
-CREATE FUNCTION g_cube_consistent(internal,cube,int4) RETURNS bool
+CREATE OR REPLACE FUNCTION g_cube_consistent(internal,cube,int4) RETURNS bool
 	AS 'MODULE_PATHNAME' LANGUAGE 'c';
 
-CREATE FUNCTION g_cube_compress(internal) RETURNS internal 
+CREATE OR REPLACE FUNCTION g_cube_compress(internal) RETURNS internal 
 	AS 'MODULE_PATHNAME' LANGUAGE 'c';
 
-CREATE FUNCTION g_cube_decompress(internal) RETURNS internal 
+CREATE OR REPLACE FUNCTION g_cube_decompress(internal) RETURNS internal 
 	AS 'MODULE_PATHNAME' LANGUAGE 'c';
 
-CREATE FUNCTION g_cube_penalty(internal,internal,internal) RETURNS internal
+CREATE OR REPLACE FUNCTION g_cube_penalty(internal,internal,internal) RETURNS internal
 	AS 'MODULE_PATHNAME' LANGUAGE 'c' STRICT;
 
-CREATE FUNCTION g_cube_picksplit(internal, internal) RETURNS internal
+CREATE OR REPLACE FUNCTION g_cube_picksplit(internal, internal) RETURNS internal
 	AS 'MODULE_PATHNAME' LANGUAGE 'c';
 
-CREATE FUNCTION g_cube_union(bytea, internal) RETURNS cube 
+CREATE OR REPLACE FUNCTION g_cube_union(bytea, internal) RETURNS cube 
 	AS 'MODULE_PATHNAME' LANGUAGE 'c';
 
-CREATE FUNCTION g_cube_same(cube, cube, internal) RETURNS internal 
+CREATE OR REPLACE FUNCTION g_cube_same(cube, cube, internal) RETURNS internal 
 	AS 'MODULE_PATHNAME' LANGUAGE 'c';
 
 
@@ -264,5 +263,31 @@ CREATE OPERATOR CLASS gist_cube_ops
 	FUNCTION	6	g_cube_picksplit (internal, internal),
 	FUNCTION	7	g_cube_same (cube, cube, internal);
 
+--
+-- By default the externally visible functions are made executable by
+-- anyone. To restrict their access comment out the following grant commands.
+--
 
-END TRANSACTION;
+GRANT EXECUTE ON FUNCTION cube(text) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_over_left(cube, cube) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_over_right(cube, cube) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_left(cube, cube) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_right(cube, cube) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_lt(cube, cube) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_gt(cube, cube) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_contains(cube, cube) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_contained(cube, cube) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_overlap(cube, cube) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_same(cube, cube) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_different(cube, cube) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_union(cube, cube) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_inter(cube, cube) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_size(cube) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_distance(cube, cube) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_dim(cube) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_ll_coord(cube, int4) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_ur_coord(cube, int4) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_is_point(cube) TO PUBLIC;
+GRANT EXECUTE ON FUNCTION cube_enlarge(cube, float8, int4) TO PUBLIC;
+
+COMMIT;
diff --git a/contrib/cube/cubedata.h b/contrib/cube/cubedata.h
index 5fef512c9e9..8eaea960f7b 100644
--- a/contrib/cube/cubedata.h
+++ b/contrib/cube/cubedata.h
@@ -1,3 +1,4 @@
+#define CUBE_MAX_DIM (100)
 typedef struct NDBOX
 {
 	unsigned int size;			/* required to be a Postgres varlena type */
diff --git a/contrib/cube/cubeparse.y b/contrib/cube/cubeparse.y
index 6aba226c70b..39e6f499bea 100644
--- a/contrib/cube/cubeparse.y
+++ b/contrib/cube/cubeparse.y
@@ -26,7 +26,7 @@ int cube_yyparse(void *result);
 
 static int delim_count(char *s, char delim);
 static NDBOX * write_box(unsigned int dim, char *str1, char *str2);
-static NDBOX * write_point_as_box(char *s);
+static NDBOX * write_point_as_box(char *s, int dim);
 
 %}
 
@@ -59,6 +59,11 @@ box:
 	      elog(ERROR, "(1) bad cube representation; different point dimensions in (%s) and (%s)\n", $2, $4);
 	      YYABORT;
 	    }
+	    if (dim > CUBE_MAX_DIM) {
+              reset_parse_buffer();
+              elog(ERROR, "(8) bad cube representation; more than %d dimensions\n", CUBE_MAX_DIM);
+              YYABORT;
+            }
 	    
 	    *((void **)result) = write_box( dim, $2, $4 );
     
@@ -82,12 +87,18 @@ box:
 	      elog(ERROR, "(3) bad cube representation; different point dimensions in (%s) and (%s)\n", $1, $3);
 	      YYABORT;
 	    }
+	    if (dim > CUBE_MAX_DIM) {
+              reset_parse_buffer();
+              elog(ERROR, "(8) bad cube representation; more than %d dimensions\n", CUBE_MAX_DIM);
+              YYABORT;
+            }
 	    
 	    *((void **)result) = write_box( dim, $1, $3 );
           }
       |
 
           paren_list {
+            int dim;
 	    int c = parse_buffer_curr_char();
 	    int pos = parse_buffer_pos();
 
@@ -104,12 +115,20 @@ box:
 	      YYABORT;
 	    }
 
-	    *((void **)result) = write_point_as_box($1);
+            dim = delim_count($1, ',') + 1;
+	    if (dim > CUBE_MAX_DIM) {
+              reset_parse_buffer();
+              elog(ERROR, "(8) bad cube representation; more than %d dimensions\n", CUBE_MAX_DIM);
+              YYABORT;
+            }
+
+	    *((void **)result) = write_point_as_box($1, dim);
           }
 
       |
 
           list {
+            int dim;
 	    int c = parse_buffer_curr_char();
 	    int pos = parse_buffer_pos();
 
@@ -126,7 +145,13 @@ box:
 	      YYABORT;
 	    }
 
-	    *((void **)result) = write_point_as_box($1);
+            dim = delim_count($1, ',') + 1;
+	    if (dim > CUBE_MAX_DIM) {
+              reset_parse_buffer();
+              elog(ERROR, "(8) bad cube representation; more than %d dimensions\n", CUBE_MAX_DIM);
+              YYABORT;
+            }
+	    *((void **)result) = write_point_as_box($1, dim);
           }
       ;
 
@@ -224,12 +249,11 @@ write_box(unsigned int dim, char *str1, char *str2)
 }
 
 
-static NDBOX * write_point_as_box(char *str)
+static NDBOX * write_point_as_box(char *str, int dim)
 {
   NDBOX * bp;
   int i, size;
   double x;
-  int dim = delim_count(str, ',') + 1;
   char * s = str;
   
   size = offsetof(NDBOX, x[0]) + sizeof(double) * dim * 2;
diff --git a/contrib/cube/expected/cube.out b/contrib/cube/expected/cube.out
index e7191396a9e..262c4b412f1 100644
--- a/contrib/cube/expected/cube.out
+++ b/contrib/cube/expected/cube.out
@@ -339,6 +339,15 @@ ERROR:  (7) bad cube representation; garbage at or before char 4, ('end of input
 SELECT '1..2'::cube AS cube; -- 7
 ERROR:  (7) bad cube representation; garbage at or before char 4, ('end of input', \000)
 
+--
+-- Testing limit of CUBE_MAX_DIM dimensions check in cube_in.
+--
+select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)'::cube;
+ERROR:  (8) bad cube representation; more than 100 dimensions
+
+select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)'::cube;
+ERROR:  (8) bad cube representation; more than 100 dimensions
+
 --
 -- testing the  operators
 --
@@ -1109,6 +1118,12 @@ SELECT cube_enlarge('(0)'::cube, 0, 2);
  (0)
 (1 row)
 
+SELECT cube_enlarge('(2),(-2)'::cube, 0, 4);
+ cube_enlarge 
+--------------
+ (-2),(2)
+(1 row)
+
 SELECT cube_enlarge('(0)'::cube, 1, 0);
  cube_enlarge 
 --------------
@@ -1127,6 +1142,12 @@ SELECT cube_enlarge('(0)'::cube, 1, 2);
  (-1, -1),(1, 1)
 (1 row)
 
+SELECT cube_enlarge('(2),(-2)'::cube, 1, 4);
+         cube_enlarge          
+-------------------------------
+ (-3, -1, -1, -1),(3, 1, 1, 1)
+(1 row)
+
 SELECT cube_enlarge('(0)'::cube, -1, 0);
  cube_enlarge 
 --------------
@@ -1145,6 +1166,12 @@ SELECT cube_enlarge('(0)'::cube, -1, 2);
  (0)
 (1 row)
 
+SELECT cube_enlarge('(2),(-2)'::cube, -1, 4);
+ cube_enlarge 
+--------------
+ (-1),(1)
+(1 row)
+
 SELECT cube_enlarge('(0,0,0)'::cube, 1, 0);
       cube_enlarge      
 ------------------------
diff --git a/contrib/cube/sql/cube.sql b/contrib/cube/sql/cube.sql
index e8a77d9c0aa..a0712c55579 100644
--- a/contrib/cube/sql/cube.sql
+++ b/contrib/cube/sql/cube.sql
@@ -92,6 +92,13 @@ SELECT '1 e7'::cube AS cube; -- 6
 SELECT '1,2a'::cube AS cube; -- 7
 SELECT '1..2'::cube AS cube; -- 7
 
+--
+-- Testing limit of CUBE_MAX_DIM dimensions check in cube_in.
+--
+
+select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)'::cube;
+select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)'::cube;
+
 --
 -- testing the  operators
 --
@@ -278,12 +285,15 @@ SELECT cube_is_point('(0,1,2),(0,1,-2)'::cube);
 SELECT cube_enlarge('(0)'::cube, 0, 0);
 SELECT cube_enlarge('(0)'::cube, 0, 1);
 SELECT cube_enlarge('(0)'::cube, 0, 2);
+SELECT cube_enlarge('(2),(-2)'::cube, 0, 4);
 SELECT cube_enlarge('(0)'::cube, 1, 0);
 SELECT cube_enlarge('(0)'::cube, 1, 1);
 SELECT cube_enlarge('(0)'::cube, 1, 2);
+SELECT cube_enlarge('(2),(-2)'::cube, 1, 4);
 SELECT cube_enlarge('(0)'::cube, -1, 0);
 SELECT cube_enlarge('(0)'::cube, -1, 1);
 SELECT cube_enlarge('(0)'::cube, -1, 2);
+SELECT cube_enlarge('(2),(-2)'::cube, -1, 4);
 SELECT cube_enlarge('(0,0,0)'::cube, 1, 0);
 SELECT cube_enlarge('(0,0,0)'::cube, 1, 2);
 SELECT cube_enlarge('(2,-2),(-3,7)'::cube, 1, 2);
-- 
GitLab