Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 16cb7db

Browse files
committed
Check column list length in XMLTABLE/JSON_TABLE alias
We weren't checking the length of the column list in the alias clause of an XMLTABLE or JSON_TABLE function (a "tablefunc" RTE), and it was possible to make the server crash by passing an overly long one. Fix it by throwing an error in that case, like the other places that deal with alias lists. In passing, modify the equivalent test used for join RTEs to look like the other ones, which was different for no apparent reason. This bug came in when XMLTABLE was born in version 10; backpatch to all stable versions. Reported-by: Wang Ke <[email protected]> Discussion: https://postgr.es/m/[email protected]
1 parent 60e956e commit 16cb7db

File tree

10 files changed

+40
-15
lines changed

10 files changed

+40
-15
lines changed

src/backend/parser/parse_clause.c

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,21 +1459,6 @@ transformFromClauseItem(ParseState *pstate, Node *n,
14591459
res_colnames = list_concat(res_colnames, r_colnames);
14601460
res_colvars = list_concat(res_colvars, r_colvars);
14611461

1462-
/*
1463-
* Check alias (AS clause), if any.
1464-
*/
1465-
if (j->alias)
1466-
{
1467-
if (j->alias->colnames != NIL)
1468-
{
1469-
if (list_length(j->alias->colnames) > list_length(res_colnames))
1470-
ereport(ERROR,
1471-
(errcode(ERRCODE_SYNTAX_ERROR),
1472-
errmsg("column alias list for \"%s\" has too many entries",
1473-
j->alias->aliasname)));
1474-
}
1475-
}
1476-
14771462
/*
14781463
* Now build an RTE for the result of the join
14791464
*/

src/backend/parser/parse_relation.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1684,6 +1684,12 @@ addRangeTableEntryForTableFunc(ParseState *pstate,
16841684
eref->colnames = list_concat(eref->colnames,
16851685
list_copy_tail(tf->colnames, numaliases));
16861686

1687+
if (numaliases > list_length(tf->colnames))
1688+
ereport(ERROR,
1689+
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
1690+
errmsg("%s function has %d columns available but %d columns specified",
1691+
"XMLTABLE", list_length(tf->colnames), numaliases)));
1692+
16871693
rte->eref = eref;
16881694

16891695
/*
@@ -1833,6 +1839,12 @@ addRangeTableEntryForJoin(ParseState *pstate,
18331839
eref->colnames = list_concat(eref->colnames,
18341840
list_copy_tail(colnames, numaliases));
18351841

1842+
if (numaliases > list_length(colnames))
1843+
ereport(ERROR,
1844+
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
1845+
errmsg("join expression \"%s\" has %d columns available but %d columns specified",
1846+
eref->aliasname, list_length(colnames), numaliases)));
1847+
18361848
rte->eref = eref;
18371849

18381850
/*

src/test/regress/expected/int2.out

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ SELECT '' AS five, * FROM INT2_TBL;
5151
| -32767
5252
(5 rows)
5353

54+
SELECT * FROM INT2_TBL AS f(a, b);
55+
ERROR: table "f" has 1 columns available but 2 columns specified
56+
SELECT * FROM (TABLE int2_tbl) AS s (a, b);
57+
ERROR: table "s" has 1 columns available but 2 columns specified
5458
SELECT '' AS four, i.* FROM INT2_TBL i WHERE i.f1 <> int2 '0';
5559
four | f1
5660
------+--------

src/test/regress/expected/join.out

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5403,6 +5403,9 @@ select * from
54035403
3 | 3
54045404
(6 rows)
54055405

5406+
-- check the number of columns specified
5407+
SELECT * FROM (int8_tbl i cross join int4_tbl j) ss(a,b,c,d);
5408+
ERROR: join expression "ss" has 3 columns available but 4 columns specified
54065409
-- check we don't try to do a unique-ified semijoin with LATERAL
54075410
explain (verbose, costs off)
54085411
select * from

src/test/regress/expected/with.out

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,11 @@ DROP TABLE y;
956956
--
957957
-- error cases
958958
--
959+
WITH x(n, b) AS (SELECT 1)
960+
SELECT * FROM x;
961+
ERROR: WITH query "x" has 1 columns available but 2 columns specified
962+
LINE 1: WITH x(n, b) AS (SELECT 1)
963+
^
959964
-- INTERSECT
960965
WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT SELECT n+1 FROM x)
961966
SELECT * FROM x;

src/test/regress/expected/xml.out

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,9 @@ EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM xmltableview1;
11421142
Table Function Call: XMLTABLE(('/ROWS/ROW'::text) PASSING (xmldata.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME/text()'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text))
11431143
(7 rows)
11441144

1145+
-- errors
1146+
SELECT * FROM XMLTABLE (ROW () PASSING null COLUMNS v1 timestamp) AS f (v1, v2);
1147+
ERROR: XMLTABLE function has 1 columns available but 2 columns specified
11451148
-- XMLNAMESPACES tests
11461149
SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz),
11471150
'/zz:rows/zz:row'

src/test/regress/sql/int2.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ INSERT INTO INT2_TBL(f1) VALUES ('');
2929

3030
SELECT '' AS five, * FROM INT2_TBL;
3131

32+
SELECT * FROM INT2_TBL AS f(a, b);
33+
34+
SELECT * FROM (TABLE int2_tbl) AS s (a, b);
35+
3236
SELECT '' AS four, i.* FROM INT2_TBL i WHERE i.f1 <> int2 '0';
3337

3438
SELECT '' AS four, i.* FROM INT2_TBL i WHERE i.f1 <> int4 '0';

src/test/regress/sql/join.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,6 +1775,9 @@ select * from
17751775
(select q1.v)
17761776
) as q2;
17771777

1778+
-- check the number of columns specified
1779+
SELECT * FROM (int8_tbl i cross join int4_tbl j) ss(a,b,c,d);
1780+
17781781
-- check we don't try to do a unique-ified semijoin with LATERAL
17791782
explain (verbose, costs off)
17801783
select * from

src/test/regress/sql/with.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,9 @@ DROP TABLE y;
410410
-- error cases
411411
--
412412

413+
WITH x(n, b) AS (SELECT 1)
414+
SELECT * FROM x;
415+
413416
-- INTERSECT
414417
WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT SELECT n+1 FROM x)
415418
SELECT * FROM x;

src/test/regress/sql/xml.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,9 @@ SELECT * FROM xmltableview1;
383383
EXPLAIN (COSTS OFF) SELECT * FROM xmltableview1;
384384
EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM xmltableview1;
385385

386+
-- errors
387+
SELECT * FROM XMLTABLE (ROW () PASSING null COLUMNS v1 timestamp) AS f (v1, v2);
388+
386389
-- XMLNAMESPACES tests
387390
SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz),
388391
'/zz:rows/zz:row'

0 commit comments

Comments
 (0)