Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 5fed7b2

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 df85f8e commit 5fed7b2

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
@@ -152,6 +152,13 @@ cube_a_f8_f8(PG_FUNCTION_ARGS)
152152
errmsg("cannot work with arrays containing NULLs")));
153153

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

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

213226
dur = ARRPTR(ur);
214227

@@ -243,6 +256,13 @@ cube_subset(PG_FUNCTION_ARGS)
243256
dx = (int32 *) ARR_DATA_PTR(idx);
244257

245258
dim = ARRNELEMS(idx);
259+
if (dim > CUBE_MAX_DIM)
260+
ereport(ERROR,
261+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
262+
errmsg("array is too long"),
263+
errdetail("A cube cannot have more than %d dimensions.",
264+
CUBE_MAX_DIM)));
265+
246266
size = IS_POINT(c) ? POINT_SIZE(dim) : CUBE_SIZE(dim);
247267
result = (NDBOX *) palloc0(size);
248268
SET_VARSIZE(result, size);
@@ -1752,6 +1772,13 @@ cube_c_f8(PG_FUNCTION_ARGS)
17521772
int size;
17531773
int i;
17541774

1775+
if (DIM(cube) + 1 > CUBE_MAX_DIM)
1776+
ereport(ERROR,
1777+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1778+
errmsg("can't extend cube"),
1779+
errdetail("A cube cannot have more than %d dimensions.",
1780+
CUBE_MAX_DIM)));
1781+
17551782
if (IS_POINT(cube))
17561783
{
17571784
size = POINT_SIZE((DIM(cube) + 1));
@@ -1793,6 +1820,13 @@ cube_c_f8_f8(PG_FUNCTION_ARGS)
17931820
int size;
17941821
int i;
17951822

1823+
if (DIM(cube) + 1 > CUBE_MAX_DIM)
1824+
ereport(ERROR,
1825+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1826+
errmsg("can't extend cube"),
1827+
errdetail("A cube cannot have more than %d dimensions.",
1828+
CUBE_MAX_DIM)));
1829+
17961830
if (IS_POINT(cube) && (x1 == x2))
17971831
{
17981832
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
@@ -381,6 +381,17 @@ SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]);
381381
ERROR: Index out of bounds
382382
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), ARRAY[4,0]);
383383
ERROR: Index out of bounds
384+
-- test for limits: this should pass
385+
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,100)));
386+
cube_subset
387+
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
388+
(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)
389+
(1 row)
390+
391+
-- and this should fail
392+
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,101)));
393+
ERROR: array is too long
394+
DETAIL: A cube cannot have more than 100 dimensions.
384395
--
385396
-- Test point processing
386397
--
@@ -453,6 +464,7 @@ SELECT cube(cube(1,2), 42, 24); -- cube_c_f8_f8
453464
--
454465
-- Testing limit of CUBE_MAX_DIM dimensions check in cube_in.
455466
--
467+
-- create too big cube from literal
456468
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;
457469
ERROR: bad cube representation
458470
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...
@@ -463,6 +475,34 @@ ERROR: bad cube representation
463475
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...
464476
^
465477
DETAIL: A cube cannot have more than 100 dimensions.
478+
-- from an array
479+
select cube(array(SELECT 0 as a FROM generate_series(1,101)));
480+
ERROR: array is too long
481+
DETAIL: A cube cannot have more than 100 dimensions.
482+
select cube(array(SELECT 0 as a FROM generate_series(1,101)),array(SELECT 0 as a FROM generate_series(1,101)));
483+
ERROR: can't extend cube
484+
DETAIL: A cube cannot have more than 100 dimensions.
485+
-- extend cube beyond limit
486+
-- this should work
487+
select cube(array(SELECT 0 as a FROM generate_series(1,100)));
488+
cube
489+
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
490+
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
491+
(1 row)
492+
493+
select cube(array(SELECT 0 as a FROM generate_series(1,100)),array(SELECT 0 as a FROM generate_series(1,100)));
494+
cube
495+
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
496+
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
497+
(1 row)
498+
499+
-- this should fail
500+
select cube(cube(array(SELECT 0 as a FROM generate_series(1,100))), 0);
501+
ERROR: can't extend cube
502+
DETAIL: A cube cannot have more than 100 dimensions.
503+
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);
504+
ERROR: can't extend cube
505+
DETAIL: A cube cannot have more than 100 dimensions.
466506
--
467507
-- testing the operators
468508
--

contrib/cube/sql/cube.sql

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]);
9898
SELECT cube_subset(cube('(1,3,5),(1,3,5)'), ARRAY[3,2,1,1]);
9999
SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]);
100100
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), ARRAY[4,0]);
101+
-- test for limits: this should pass
102+
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,100)));
103+
-- and this should fail
104+
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,101)));
105+
106+
101107

102108
--
103109
-- Test point processing
@@ -117,9 +123,21 @@ SELECT cube(cube(1,2), 42, 24); -- cube_c_f8_f8
117123
--
118124
-- Testing limit of CUBE_MAX_DIM dimensions check in cube_in.
119125
--
120-
126+
-- create too big cube from literal
121127
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;
122128
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;
129+
-- from an array
130+
select cube(array(SELECT 0 as a FROM generate_series(1,101)));
131+
select cube(array(SELECT 0 as a FROM generate_series(1,101)),array(SELECT 0 as a FROM generate_series(1,101)));
132+
133+
-- extend cube beyond limit
134+
-- this should work
135+
select cube(array(SELECT 0 as a FROM generate_series(1,100)));
136+
select cube(array(SELECT 0 as a FROM generate_series(1,100)),array(SELECT 0 as a FROM generate_series(1,100)));
137+
-- this should fail
138+
select cube(cube(array(SELECT 0 as a FROM generate_series(1,100))), 0);
139+
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);
140+
123141

124142
--
125143
-- testing the operators

0 commit comments

Comments
 (0)