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
This commit is contained in:
parent
1668186eb3
commit
36343e59b5
@ -152,6 +152,13 @@ cube_a_f8_f8(PG_FUNCTION_ARGS)
|
|||||||
errmsg("cannot work with arrays containing NULLs")));
|
errmsg("cannot work with arrays containing NULLs")));
|
||||||
|
|
||||||
dim = ARRNELEMS(ur);
|
dim = ARRNELEMS(ur);
|
||||||
|
if (dim > CUBE_MAX_DIM)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
||||||
|
errmsg("can't extend cube"),
|
||||||
|
errdetail("A cube cannot have more than %d dimensions.",
|
||||||
|
CUBE_MAX_DIM)));
|
||||||
|
|
||||||
if (ARRNELEMS(ll) != dim)
|
if (ARRNELEMS(ll) != dim)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
||||||
@ -209,6 +216,12 @@ cube_a_f8(PG_FUNCTION_ARGS)
|
|||||||
errmsg("cannot work with arrays containing NULLs")));
|
errmsg("cannot work with arrays containing NULLs")));
|
||||||
|
|
||||||
dim = ARRNELEMS(ur);
|
dim = ARRNELEMS(ur);
|
||||||
|
if (dim > CUBE_MAX_DIM)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
||||||
|
errmsg("array is too long"),
|
||||||
|
errdetail("A cube cannot have more than %d dimensions.",
|
||||||
|
CUBE_MAX_DIM)));
|
||||||
|
|
||||||
dur = ARRPTR(ur);
|
dur = ARRPTR(ur);
|
||||||
|
|
||||||
@ -243,6 +256,13 @@ cube_subset(PG_FUNCTION_ARGS)
|
|||||||
dx = (int32 *) ARR_DATA_PTR(idx);
|
dx = (int32 *) ARR_DATA_PTR(idx);
|
||||||
|
|
||||||
dim = ARRNELEMS(idx);
|
dim = ARRNELEMS(idx);
|
||||||
|
if (dim > CUBE_MAX_DIM)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
||||||
|
errmsg("array is too long"),
|
||||||
|
errdetail("A cube cannot have more than %d dimensions.",
|
||||||
|
CUBE_MAX_DIM)));
|
||||||
|
|
||||||
size = IS_POINT(c) ? POINT_SIZE(dim) : CUBE_SIZE(dim);
|
size = IS_POINT(c) ? POINT_SIZE(dim) : CUBE_SIZE(dim);
|
||||||
result = (NDBOX *) palloc0(size);
|
result = (NDBOX *) palloc0(size);
|
||||||
SET_VARSIZE(result, size);
|
SET_VARSIZE(result, size);
|
||||||
@ -1756,6 +1776,13 @@ cube_c_f8(PG_FUNCTION_ARGS)
|
|||||||
int size;
|
int size;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (DIM(cube) + 1 > CUBE_MAX_DIM)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
||||||
|
errmsg("can't extend cube"),
|
||||||
|
errdetail("A cube cannot have more than %d dimensions.",
|
||||||
|
CUBE_MAX_DIM)));
|
||||||
|
|
||||||
if (IS_POINT(cube))
|
if (IS_POINT(cube))
|
||||||
{
|
{
|
||||||
size = POINT_SIZE((DIM(cube) + 1));
|
size = POINT_SIZE((DIM(cube) + 1));
|
||||||
@ -1797,6 +1824,13 @@ cube_c_f8_f8(PG_FUNCTION_ARGS)
|
|||||||
int size;
|
int size;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (DIM(cube) + 1 > CUBE_MAX_DIM)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
||||||
|
errmsg("can't extend cube"),
|
||||||
|
errdetail("A cube cannot have more than %d dimensions.",
|
||||||
|
CUBE_MAX_DIM)));
|
||||||
|
|
||||||
if (IS_POINT(cube) && (x1 == x2))
|
if (IS_POINT(cube) && (x1 == x2))
|
||||||
{
|
{
|
||||||
size = POINT_SIZE((DIM(cube) + 1));
|
size = POINT_SIZE((DIM(cube) + 1));
|
||||||
|
@ -418,6 +418,17 @@ SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]);
|
|||||||
ERROR: Index out of bounds
|
ERROR: Index out of bounds
|
||||||
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), ARRAY[4,0]);
|
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), ARRAY[4,0]);
|
||||||
ERROR: Index out of bounds
|
ERROR: Index out of bounds
|
||||||
|
-- test for limits: this should pass
|
||||||
|
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,100)));
|
||||||
|
cube_subset
|
||||||
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
(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)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- and this should fail
|
||||||
|
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,101)));
|
||||||
|
ERROR: array is too long
|
||||||
|
DETAIL: A cube cannot have more than 100 dimensions.
|
||||||
--
|
--
|
||||||
-- Test point processing
|
-- Test point processing
|
||||||
--
|
--
|
||||||
@ -490,6 +501,7 @@ SELECT cube(cube(1,2), 42, 24); -- cube_c_f8_f8
|
|||||||
--
|
--
|
||||||
-- Testing limit of CUBE_MAX_DIM dimensions check in cube_in.
|
-- Testing limit of CUBE_MAX_DIM dimensions check in cube_in.
|
||||||
--
|
--
|
||||||
|
-- create too big cube from literal
|
||||||
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)'::cube;
|
||||||
ERROR: invalid input syntax for cube
|
ERROR: invalid input syntax for cube
|
||||||
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...
|
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
|
|||||||
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...
|
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...
|
||||||
^
|
^
|
||||||
DETAIL: A cube cannot have more than 100 dimensions.
|
DETAIL: A cube cannot have more than 100 dimensions.
|
||||||
|
-- from an array
|
||||||
|
select cube(array(SELECT 0 as a FROM generate_series(1,101)));
|
||||||
|
ERROR: array is too long
|
||||||
|
DETAIL: A cube cannot have more than 100 dimensions.
|
||||||
|
select cube(array(SELECT 0 as a FROM generate_series(1,101)),array(SELECT 0 as a FROM generate_series(1,101)));
|
||||||
|
ERROR: can't extend cube
|
||||||
|
DETAIL: A cube cannot have more than 100 dimensions.
|
||||||
|
-- extend cube beyond limit
|
||||||
|
-- this should work
|
||||||
|
select cube(array(SELECT 0 as a FROM generate_series(1,100)));
|
||||||
|
cube
|
||||||
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select cube(array(SELECT 0 as a FROM generate_series(1,100)),array(SELECT 0 as a FROM generate_series(1,100)));
|
||||||
|
cube
|
||||||
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- this should fail
|
||||||
|
select cube(cube(array(SELECT 0 as a FROM generate_series(1,100))), 0);
|
||||||
|
ERROR: can't extend cube
|
||||||
|
DETAIL: A cube cannot have more than 100 dimensions.
|
||||||
|
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);
|
||||||
|
ERROR: can't extend cube
|
||||||
|
DETAIL: A cube cannot have more than 100 dimensions.
|
||||||
--
|
--
|
||||||
-- testing the operators
|
-- testing the operators
|
||||||
--
|
--
|
||||||
|
@ -108,6 +108,12 @@ SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]);
|
|||||||
SELECT cube_subset(cube('(1,3,5),(1,3,5)'), ARRAY[3,2,1,1]);
|
SELECT cube_subset(cube('(1,3,5),(1,3,5)'), ARRAY[3,2,1,1]);
|
||||||
SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]);
|
SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]);
|
||||||
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), ARRAY[4,0]);
|
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), ARRAY[4,0]);
|
||||||
|
-- test for limits: this should pass
|
||||||
|
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,100)));
|
||||||
|
-- and this should fail
|
||||||
|
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,101)));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Test point processing
|
-- Test point processing
|
||||||
@ -127,9 +133,21 @@ SELECT cube(cube(1,2), 42, 24); -- cube_c_f8_f8
|
|||||||
--
|
--
|
||||||
-- Testing limit of CUBE_MAX_DIM dimensions check in cube_in.
|
-- Testing limit of CUBE_MAX_DIM dimensions check in cube_in.
|
||||||
--
|
--
|
||||||
|
-- create too big cube from literal
|
||||||
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)'::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;
|
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;
|
||||||
|
-- from an array
|
||||||
|
select cube(array(SELECT 0 as a FROM generate_series(1,101)));
|
||||||
|
select cube(array(SELECT 0 as a FROM generate_series(1,101)),array(SELECT 0 as a FROM generate_series(1,101)));
|
||||||
|
|
||||||
|
-- extend cube beyond limit
|
||||||
|
-- this should work
|
||||||
|
select cube(array(SELECT 0 as a FROM generate_series(1,100)));
|
||||||
|
select cube(array(SELECT 0 as a FROM generate_series(1,100)),array(SELECT 0 as a FROM generate_series(1,100)));
|
||||||
|
-- this should fail
|
||||||
|
select cube(cube(array(SELECT 0 as a FROM generate_series(1,100))), 0);
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- testing the operators
|
-- testing the operators
|
||||||
|
Loading…
x
Reference in New Issue
Block a user