mirror of
https://github.com/sqlite/sqlite.git
synced 2026-10-23 21:49:02 +03:00
Limit the depth of recursion for CTEs using SQLITE_LIMIT_EXPR_DEPTH.
[bugs:/info/2026-10-04T04:58:58Z|Bug 2026-10-04T04:58:58Z]. FossilOrigin-Name: f54730871303e655a70f3167ce1a39dcd4e53fcf017d225f429e2bb67ad96604
This commit is contained in:
14
manifest
14
manifest
@@ -1,5 +1,5 @@
|
||||
C Fix\sexpression\stree\sdepth\scalculations\sfor\sCOLLATE.\n[bugs:/info/2026-10-04T04:50:56Z|Bug\s2026-10-04T04:50:56Z]
|
||||
D 2026-10-04T21:54:17.561
|
||||
C Limit\sthe\sdepth\sof\srecursion\sfor\sCTEs\susing\sSQLITE_LIMIT_EXPR_DEPTH.\n[bugs:/info/2026-10-04T04:58:58Z|Bug\s2026-10-04T04:58:58Z].
|
||||
D 2026-10-05T09:32:24.919
|
||||
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
@@ -800,7 +800,7 @@ F src/printf.c 4bd228ed9e9346d558362be562757ee5eef6f9bf483b7f02751ca42cf95174d3
|
||||
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
||||
F src/resolve.c 0e0990f60c93db38c735d85e5d1741130e72dd0670aec204b5a39118b53c8044
|
||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||
F src/select.c 5859a4a19581d91fb2c3a818c18ad45de6906434aeaf0c4b74ca5f58295cb432
|
||||
F src/select.c 6aa1d385f58b7e5b813a1ea4008dfe36378568d13e1cdfac8fb21f135f13e589
|
||||
F src/shell.c.in 8504577eb02e87b58f9d632bc4458efda074476428774692207ddacc0fe9e1df
|
||||
F src/sqlite.h.in 884996e07cfb7681efc76661b79d56a93f9edaea7f6fc4a3c82636dc84783486
|
||||
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
|
||||
@@ -2162,7 +2162,7 @@ F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3c
|
||||
F test/windowfault.test 15094c1529424e62f798bc679e3fe9dfab6e8ba2f7dfe8c923b6248c31660a7c
|
||||
F test/windowpushd.test c420e2265f0e09a0e798d0513a660d71b51602088d81b3dbd038918ee1339dcc
|
||||
F test/with1.test c416097db4ead936b98a76ff3069f76a6009c5aaec5ff2b2c5ca210bc595ad57
|
||||
F test/with2.test 181674a6cc86a601ca2ac052741cdfad5b529e07e870435d2f6cdb92d589ff17
|
||||
F test/with2.test 70cdc0b211a2c5ffccc93f5c50cf092367bf5a1792576d23a479915a80fb5506
|
||||
F test/with3.test e30369ea27aa27eb1bda4c5e510c8a9f782c8afd2ab99d1a02b8a7f25a5d3e65
|
||||
F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205
|
||||
F test/with5.test 262a604e001938428da3d06ca90df9a478eff34ada737e2c023a99954418e8cf
|
||||
@@ -2278,8 +2278,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
|
||||
F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
|
||||
P d4330c79a477bab7e86aba860813f4f83e9af5ef8067698fcdf41efd6a0e8516
|
||||
R 960558da009947c307ca304fdbbe4e0f
|
||||
P 252c0b7bf5a727d29605672bb58e06c758173c276671df3e388a68294998b4d3
|
||||
R 290d962d1474ee55ec1b78b7d7977cb5
|
||||
U drh
|
||||
Z 6378420ac511b5740e99c19b2a3da65d
|
||||
Z 4a8d751b209e545320f7b152e9bdedd1
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
@@ -1 +1 @@
|
||||
252c0b7bf5a727d29605672bb58e06c758173c276671df3e388a68294998b4d3
|
||||
f54730871303e655a70f3167ce1a39dcd4e53fcf017d225f429e2bb67ad96604
|
||||
|
||||
36
src/select.c
36
src/select.c
@@ -2490,6 +2490,20 @@ void sqlite3SubqueryColumnTypes(
|
||||
pTab->szTabRow = 1; /* Any non-zero value works */
|
||||
}
|
||||
|
||||
/*
|
||||
** Check the current subquery nesting depth. Return true and set an
|
||||
** error if it has gone too deep.
|
||||
*/
|
||||
static int checkSubqueryNestingDepth(Parse *pParse){
|
||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||
if( pParse->nNestSel >= pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH] ){
|
||||
sqlite3ErrorMsg(pParse, "VIEWs and/or subqueries nested too deep");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Given a SELECT statement, generate a Table structure that describes
|
||||
** the result set of that SELECT.
|
||||
@@ -2500,12 +2514,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, char aff){
|
||||
u64 savedFlags;
|
||||
|
||||
pParse->nNestSel++;
|
||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||
if( pParse->nNestSel >= db->aLimit[SQLITE_LIMIT_EXPR_DEPTH] ){
|
||||
sqlite3ErrorMsg(pParse, "VIEWs and/or subqueries nested too deep");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if( checkSubqueryNestingDepth(pParse) ) return 0;
|
||||
savedFlags = db->flags;
|
||||
db->flags &= ~(u64)SQLITE_FullColNames;
|
||||
db->flags |= SQLITE_ShortColNames;
|
||||
@@ -5752,14 +5761,13 @@ With *sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){
|
||||
}
|
||||
|
||||
/*
|
||||
** This function checks if argument pFrom refers to a CTE declared by
|
||||
** This function checks to see if argument pFrom refers to a CTE declared by
|
||||
** a WITH clause on the stack currently maintained by the parser (on the
|
||||
** pParse->pWith linked list). And if currently processing a CTE
|
||||
** CTE expression, through routine checks to see if the reference is
|
||||
** a recursive reference to the CTE.
|
||||
** pParse->pWith linked list). And if currently processing a CTE expression,
|
||||
** it also checks to see if the reference is a recursive reference to the CTE.
|
||||
**
|
||||
** If pFrom matches a CTE according to either of these two above, pFrom->pSTab
|
||||
** and other fields are populated accordingly.
|
||||
** If pFrom matches a CTE, pFrom->pSTab and other fields are populated
|
||||
** accordingly.
|
||||
**
|
||||
** Return 0 if no match is found.
|
||||
** Return 1 if a match is found.
|
||||
@@ -5888,6 +5896,8 @@ static int resolveFromTermToCte(
|
||||
pRecTerm = pRecTerm->pPrior;
|
||||
}
|
||||
|
||||
pParse->nNestSel++;
|
||||
if( checkSubqueryNestingDepth(pParse) ) return 2;
|
||||
pCte->zCteErr = "circular reference: %s";
|
||||
pSavedWith = pParse->pWith;
|
||||
pParse->pWith = pWith;
|
||||
@@ -5912,6 +5922,8 @@ static int resolveFromTermToCte(
|
||||
}
|
||||
}
|
||||
pParse->pWith = pWith;
|
||||
pParse->nNestSel--;
|
||||
assert( pParse->nNestSel>=0 );
|
||||
|
||||
for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior);
|
||||
pEList = pLeft->pEList;
|
||||
|
||||
@@ -635,4 +635,37 @@ do_execsql_test 13.1 {
|
||||
SELECT * FROM t1, t3;
|
||||
} {111 222}
|
||||
|
||||
# Bug 2026-10-04T04:58:58Z
|
||||
reset_db
|
||||
sqlite3_limit db SQLITE_LIMIT_EXPR_DEPTH 12
|
||||
do_catchsql_test 14.1 {
|
||||
WITH c0 AS (SELECT 1 AS x),
|
||||
c1 AS (SELECT x FROM c0),
|
||||
c2 AS (SELECT x FROM c1),
|
||||
c3 AS (SELECT x FROM c2),
|
||||
c4 AS (SELECT x FROM c3),
|
||||
c5 AS (SELECT x FROM c4),
|
||||
c6 AS (SELECT x FROM c5),
|
||||
c7 AS (SELECT x FROM c6),
|
||||
c8 AS (SELECT x FROM c7),
|
||||
c9 AS (SELECT x FROM c8),
|
||||
c10 AS (SELECT x FROM c9)
|
||||
SELECT x FROM c10;
|
||||
} {0 1}
|
||||
sqlite3_limit db SQLITE_LIMIT_EXPR_DEPTH 11
|
||||
do_catchsql_test 14.2 {
|
||||
WITH c00 AS (SELECT 1 AS x),
|
||||
c1 AS (SELECT x FROM c00),
|
||||
c2 AS (SELECT x FROM c1),
|
||||
c3 AS (SELECT x FROM c2),
|
||||
c4 AS (SELECT x FROM c3),
|
||||
c5 AS (SELECT x FROM c4),
|
||||
c6 AS (SELECT x FROM c5),
|
||||
c7 AS (SELECT x FROM c6),
|
||||
c8 AS (SELECT x FROM c7),
|
||||
c9 AS (SELECT x FROM c8),
|
||||
c10 AS (SELECT x FROM c9)
|
||||
SELECT x FROM c10;
|
||||
} {1 {VIEWs and/or subqueries nested too deep}}
|
||||
|
||||
finish_test
|
||||
|
||||
Reference in New Issue
Block a user