Skip to content

Commit f919c16

Browse files
committed
Enforce cube dimension limit in all cube construction functions
contrib/cube has a limit to 100 dimensions for cube datatype. However, it's not enforced everywhere, and one can actually construct cube with more than 100 dimensions having then trouble with dump/restore. This commit add checks for dimensions limit in all functions responsible for cube construction. Backpatch to all supported versions. Reported-by: Andrew Gierth Discussion: https://postgr.es/m/87va7uybt4.fsf%40news-spur.riddles.org.uk Author: Andrey Borodin with small additions by me Review: Tom Lane Backpatch-through: 9.3
1 parent 38970ce commit f919c16

File tree

3 files changed

+93
-1
lines changed

3 files changed

+93
-1
lines changed

contrib/cube/cube.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,13 @@ cube_a_f8_f8(PG_FUNCTION_ARGS)
151151
errmsg("cannot work with arrays containing NULLs")));
152152

153153
dim = ARRNELEMS(ur);
154+
if (dim > CUBE_MAX_DIM)
155+
ereport(ERROR,
156+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
157+
errmsg("can't extend cube"),
158+
errdetail("A cube cannot have more than %d dimensions.",
159+
CUBE_MAX_DIM)));
160+
154161
if (ARRNELEMS(ll) != dim)
155162
ereport(ERROR,
156163
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
@@ -208,6 +215,12 @@ cube_a_f8(PG_FUNCTION_ARGS)
208215
errmsg("cannot work with arrays containing NULLs")));
209216

210217
dim = ARRNELEMS(ur);
218+
if (dim > CUBE_MAX_DIM)
219+
ereport(ERROR,
220+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
221+
errmsg("array is too long"),
222+
errdetail("A cube cannot have more than %d dimensions.",
223+
CUBE_MAX_DIM)));
211224

212225
dur = ARRPTR(ur);
213226

@@ -242,6 +255,13 @@ cube_subset(PG_FUNCTION_ARGS)
242255
dx = (int32 *) ARR_DATA_PTR(idx);
243256

244257
dim = ARRNELEMS(idx);
258+
if (dim > CUBE_MAX_DIM)
259+
ereport(ERROR,
260+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
261+
errmsg("array is too long"),
262+
errdetail("A cube cannot have more than %d dimensions.",
263+
CUBE_MAX_DIM)));
264+
245265
size = IS_POINT(c) ? POINT_SIZE(dim) : CUBE_SIZE(dim);
246266
result = (NDBOX *) palloc0(size);
247267
SET_VARSIZE(result, size);
@@ -1755,6 +1775,13 @@ cube_c_f8(PG_FUNCTION_ARGS)
17551775
int size;
17561776
int i;
17571777

1778+
if (DIM(cube) + 1 > CUBE_MAX_DIM)
1779+
ereport(ERROR,
1780+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1781+
errmsg("can't extend cube"),
1782+
errdetail("A cube cannot have more than %d dimensions.",
1783+
CUBE_MAX_DIM)));
1784+
17581785
if (IS_POINT(cube))
17591786
{
17601787
size = POINT_SIZE((DIM(cube) + 1));
@@ -1796,6 +1823,13 @@ cube_c_f8_f8(PG_FUNCTION_ARGS)
17961823
int size;
17971824
int i;
17981825

1826+
if (DIM(cube) + 1 > CUBE_MAX_DIM)
1827+
ereport(ERROR,
1828+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1829+
errmsg("can't extend cube"),
1830+
errdetail("A cube cannot have more than %d dimensions.",
1831+
CUBE_MAX_DIM)));
1832+
17991833
if (IS_POINT(cube) && (x1 == x2))
18001834
{
18011835
size = POINT_SIZE((DIM(cube) + 1));

contrib/cube/expected/cube.out

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,17 @@ SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]);
418418
ERROR: Index out of bounds
419419
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), ARRAY[4,0]);
420420
ERROR: Index out of bounds
421+
-- test for limits: this should pass
422+
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,100)));
423+
cube_subset
424+
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
425+
(6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6)
426+
(1 row)
427+
428+
-- and this should fail
429+
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,101)));
430+
ERROR: array is too long
431+
DETAIL: A cube cannot have more than 100 dimensions.
421432
--
422433
-- Test point processing
423434
--
@@ -490,6 +501,7 @@ SELECT cube(cube(1,2), 42, 24); -- cube_c_f8_f8
490501
--
491502
-- Testing limit of CUBE_MAX_DIM dimensions check in cube_in.
492503
--
504+
-- create too big cube from literal
493505
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;
494506
ERROR: invalid input syntax for cube
495507
LINE 1: 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...
@@ -500,6 +512,34 @@ ERROR: invalid input syntax for cube
500512
LINE 1: 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...
501513
^
502514
DETAIL: A cube cannot have more than 100 dimensions.
515+
-- from an array
516+
select cube(array(SELECT 0 as a FROM generate_series(1,101)));
517+
ERROR: array is too long
518+
DETAIL: A cube cannot have more than 100 dimensions.
519+
select cube(array(SELECT 0 as a FROM generate_series(1,101)),array(SELECT 0 as a FROM generate_series(1,101)));
520+
ERROR: can't extend cube
521+
DETAIL: A cube cannot have more than 100 dimensions.
522+
-- extend cube beyond limit
523+
-- this should work
524+
select cube(array(SELECT 0 as a FROM generate_series(1,100)));
525+
cube
526+
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
527+
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
528+
(1 row)
529+
530+
select cube(array(SELECT 0 as a FROM generate_series(1,100)),array(SELECT 0 as a FROM generate_series(1,100)));
531+
cube
532+
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
533+
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
534+
(1 row)
535+
536+
-- this should fail
537+
select cube(cube(array(SELECT 0 as a FROM generate_series(1,100))), 0);
538+
ERROR: can't extend cube
539+
DETAIL: A cube cannot have more than 100 dimensions.
540+
select cube(cube(array(SELECT 0 as a FROM generate_series(1,100)),array(SELECT 0 as a FROM generate_series(1,100))), 0, 0);
541+
ERROR: can't extend cube
542+
DETAIL: A cube cannot have more than 100 dimensions.
503543
--
504544
-- testing the operators
505545
--

contrib/cube/sql/cube.sql

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@ SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]);
108108
SELECT cube_subset(cube('(1,3,5),(1,3,5)'), ARRAY[3,2,1,1]);
109109
SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]);
110110
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), ARRAY[4,0]);
111+
-- test for limits: this should pass
112+
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,100)));
113+
-- and this should fail
114+
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,101)));
115+
116+
111117

112118
--
113119
-- Test point processing
@@ -127,9 +133,21 @@ SELECT cube(cube(1,2), 42, 24); -- cube_c_f8_f8
127133
--
128134
-- Testing limit of CUBE_MAX_DIM dimensions check in cube_in.
129135
--
130-
136+
-- create too big cube from literal
131137
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;
132138
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;
139+
-- from an array
140+
select cube(array(SELECT 0 as a FROM generate_series(1,101)));
141+
select cube(array(SELECT 0 as a FROM generate_series(1,101)),array(SELECT 0 as a FROM generate_series(1,101)));
142+
143+
-- extend cube beyond limit
144+
-- this should work
145+
select cube(array(SELECT 0 as a FROM generate_series(1,100)));
146+
select cube(array(SELECT 0 as a FROM generate_series(1,100)),array(SELECT 0 as a FROM generate_series(1,100)));
147+
-- this should fail
148+
select cube(cube(array(SELECT 0 as a FROM generate_series(1,100))), 0);
149+
select cube(cube(array(SELECT 0 as a FROM generate_series(1,100)),array(SELECT 0 as a FROM generate_series(1,100))), 0, 0);
150+
133151

134152
--
135153
-- testing the operators

0 commit comments

Comments
 (0)