Skip to content

Commit 9f3ade1

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 5d6a1ee commit 9f3ade1

File tree

3 files changed

+91
-1
lines changed

3 files changed

+91
-1
lines changed

contrib/cube/cube.c

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

192192
dim = ARRNELEMS(ur);
193+
if (dim > CUBE_MAX_DIM)
194+
ereport(ERROR,
195+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
196+
errmsg("can't extend cube"),
197+
errdetail("A cube cannot have more than %d dimensions.",
198+
CUBE_MAX_DIM)));
199+
193200
if (ARRNELEMS(ll) != dim)
194201
ereport(ERROR,
195202
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
@@ -231,6 +238,12 @@ cube_a_f8(PG_FUNCTION_ARGS)
231238
errmsg("cannot work with arrays containing NULLs")));
232239

233240
dim = ARRNELEMS(ur);
241+
if (dim > CUBE_MAX_DIM)
242+
ereport(ERROR,
243+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
244+
errmsg("array is too long"),
245+
errdetail("A cube cannot have more than %d dimensions.",
246+
CUBE_MAX_DIM)));
234247

235248
dur = ARRPTR(ur);
236249

@@ -267,6 +280,13 @@ cube_subset(PG_FUNCTION_ARGS)
267280
dx = (int32 *) ARR_DATA_PTR(idx);
268281

269282
dim = ARRNELEMS(idx);
283+
if (dim > CUBE_MAX_DIM)
284+
ereport(ERROR,
285+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
286+
errmsg("array is too long"),
287+
errdetail("A cube cannot have more than %d dimensions.",
288+
CUBE_MAX_DIM)));
289+
270290
size = offsetof(NDBOX, x[0]) +sizeof(double) * 2 * dim;
271291
result = (NDBOX *) palloc0(size);
272292
SET_VARSIZE(result, size);
@@ -1452,6 +1472,13 @@ cube_c_f8(PG_FUNCTION_ARGS)
14521472
int size;
14531473
int i;
14541474

1475+
if (c->dim + 1 > CUBE_MAX_DIM)
1476+
ereport(ERROR,
1477+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1478+
errmsg("can't extend cube"),
1479+
errdetail("A cube cannot have more than %d dimensions.",
1480+
CUBE_MAX_DIM)));
1481+
14551482
size = offsetof(NDBOX, x[0]) +sizeof(double) * (c->dim + 1) *2;
14561483
result = (NDBOX *) palloc0(size);
14571484
SET_VARSIZE(result, size);
@@ -1479,6 +1506,13 @@ cube_c_f8_f8(PG_FUNCTION_ARGS)
14791506
int size;
14801507
int i;
14811508

1509+
if (c->dim + 1 > CUBE_MAX_DIM)
1510+
ereport(ERROR,
1511+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1512+
errmsg("can't extend cube"),
1513+
errdetail("A cube cannot have more than %d dimensions.",
1514+
CUBE_MAX_DIM)));
1515+
14821516
size = offsetof(NDBOX, x[0]) +sizeof(double) * (c->dim + 1) *2;
14831517
result = (NDBOX *) palloc0(size);
14841518
SET_VARSIZE(result, size);

contrib/cube/expected/cube.out

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,9 +373,21 @@ SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]);
373373

374374
SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]);
375375
ERROR: Index out of bounds
376+
-- test for limits: this should pass
377+
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,100)));
378+
cube_subset
379+
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
380+
(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)
381+
(1 row)
382+
383+
-- and this should fail
384+
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,101)));
385+
ERROR: array is too long
386+
DETAIL: A cube cannot have more than 100 dimensions.
376387
--
377388
-- Testing limit of CUBE_MAX_DIM dimensions check in cube_in.
378389
--
390+
-- create too big cube from literal
379391
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;
380392
ERROR: bad cube representation
381393
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...
@@ -386,6 +398,34 @@ ERROR: bad cube representation
386398
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...
387399
^
388400
DETAIL: A cube cannot have more than 100 dimensions.
401+
-- from an array
402+
select cube(array(SELECT 0 as a FROM generate_series(1,101)));
403+
ERROR: array is too long
404+
DETAIL: A cube cannot have more than 100 dimensions.
405+
select cube(array(SELECT 0 as a FROM generate_series(1,101)),array(SELECT 0 as a FROM generate_series(1,101)));
406+
ERROR: can't extend cube
407+
DETAIL: A cube cannot have more than 100 dimensions.
408+
-- extend cube beyond limit
409+
-- this should work
410+
select cube(array(SELECT 0 as a FROM generate_series(1,100)));
411+
cube
412+
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
413+
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
414+
(1 row)
415+
416+
select cube(array(SELECT 0 as a FROM generate_series(1,100)),array(SELECT 0 as a FROM generate_series(1,100)));
417+
cube
418+
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
419+
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
420+
(1 row)
421+
422+
-- this should fail
423+
select cube(cube(array(SELECT 0 as a FROM generate_series(1,100))), 0);
424+
ERROR: can't extend cube
425+
DETAIL: A cube cannot have more than 100 dimensions.
426+
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);
427+
ERROR: can't extend cube
428+
DETAIL: A cube cannot have more than 100 dimensions.
389429
--
390430
-- testing the operators
391431
--

contrib/cube/sql/cube.sql

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,29 @@ SELECT cube(NULL::float[], '{3}'::float[]);
9696
SELECT cube('{0,1,2}'::float[]);
9797
SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]);
9898
SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]);
99+
-- test for limits: this should pass
100+
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,100)));
101+
-- and this should fail
102+
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,101)));
99103

100104
--
101105
-- Testing limit of CUBE_MAX_DIM dimensions check in cube_in.
102106
--
103-
107+
-- create too big cube from literal
104108
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;
105109
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;
110+
-- from an array
111+
select cube(array(SELECT 0 as a FROM generate_series(1,101)));
112+
select cube(array(SELECT 0 as a FROM generate_series(1,101)),array(SELECT 0 as a FROM generate_series(1,101)));
113+
114+
-- extend cube beyond limit
115+
-- this should work
116+
select cube(array(SELECT 0 as a FROM generate_series(1,100)));
117+
select cube(array(SELECT 0 as a FROM generate_series(1,100)),array(SELECT 0 as a FROM generate_series(1,100)));
118+
-- this should fail
119+
select cube(cube(array(SELECT 0 as a FROM generate_series(1,100))), 0);
120+
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);
121+
106122

107123
--
108124
-- testing the operators

0 commit comments

Comments
 (0)