Avoid excess stack usage when a VALUES clause with lots of rows occurs
within a scalar expression. This fixes a problem discovered by OSSFuzz. FossilOrigin-Name: a4fa0581ba7cfd45fabe0198f55b3c2c8ee3ecfd2825aeed91116f44e77d760b
This commit is contained in:
parent
eb54500419
commit
b058d05452
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\sharmless\scompiler\swarnings\sin\szipfile.c.
|
||||
D 2018-01-13T23:28:33.571
|
||||
C Avoid\sexcess\sstack\susage\swhen\sa\sVALUES\sclause\swith\slots\sof\srows\soccurs\nwithin\sa\sscalar\sexpression.\s\sThis\sfixes\sa\sproblem\sdiscovered\sby\sOSSFuzz.
|
||||
D 2018-01-14T20:12:23.878
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F Makefile.in 38f84f301cbef443b2d269f67a74b8cc536469831f70df7c3e912acc04932cc2
|
||||
@ -438,7 +438,7 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
|
||||
F src/dbpage.c 8db4c97f630e7d83f884ea75caf1ffd0988c160e9d530194d93721c80821e0f6
|
||||
F src/dbstat.c 7a4ba8518b6369ef3600c49cf9c918ad979acba610b2aebef1b656d649b96720
|
||||
F src/delete.c 20c8788451dc737a967c87ea53ad43544d617f5b57d32ccce8bd52a0daf9e89b
|
||||
F src/expr.c ad6e7a9c34a4bab9d10cc857d647ae7ce370a633b5c0bfa71f1c29b81ae364b8
|
||||
F src/expr.c 46a7d73d5579feaee7a7274fac0efea0bbae71dd5b107a569501d89e0280c762
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c d617daf66b5515e2b42c1405b2b4984c30ca50fb705ab164271a9bf66c69e331
|
||||
F src/func.c bd528d5ed68ce5cbf78a762e3b735fa75009f7197ff07fab07fd771f35ebaa1b
|
||||
@ -485,7 +485,7 @@ F src/printf.c 9506b4b96e59c0467047155f09015750cb2878aeda3d39e5610c1192ddc3c41c
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c bbee7e31d369a18a2f4836644769882e9c5d40ef4a3af911db06410b65cb3730
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c 8b22abe193e4d8243befa2038e4ae2405802fed1c446e5e502d11f652e09ba74
|
||||
F src/select.c bebe7cce45d899d2237c76bce059d525abf5b861f2fce92f6b53914a961c01ba
|
||||
F src/shell.c.in b87abffd0db09203ad8a133d56fe8f154ace5ec0a14197a153fb7d80b1438c01
|
||||
F src/sqlite.h.in 9daf78e8f3cecc9ea0c3a82201f75bb74f789ecbfcda28d2e47fa80b3d956961
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
@ -1205,7 +1205,7 @@ F test/selectC.test e25243f8ca503e06f252eb0218976d07cfeceac3
|
||||
F test/selectD.test b0f02a04ef7737decb24e08be2c39b9664b43394
|
||||
F test/selectE.test a8730ca330fcf40ace158f134f4fe0eb00c7edbf
|
||||
F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3
|
||||
F test/selectG.test e8600e379589e85e9fefd2fe4d44a4cdd63f6982
|
||||
F test/selectG.test 089f7d3d7e6db91566f00b036cb353107a2cca6220eb1cb264085a836dae8840
|
||||
F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118
|
||||
F test/session.test 78fa2365e93d3663a6e933f86e7afc395adf18be
|
||||
F test/shared.test 1da9dbad400cee0d93f252ccf76e1ae007a63746
|
||||
@ -1699,7 +1699,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P f2d2a5df4f29b47212fd2411eae6545087b901a270655640c87ceb472e02a24c
|
||||
R 8e0eefc806344b75dcd41a32589e33e5
|
||||
P 8f7a592f8c044d75b4615a95e27454100b10c2b26f4cafee97dec23343821130
|
||||
R 5b961a6038bd65800f58ecff32ab6963
|
||||
U drh
|
||||
Z 25a119edfc3f91c75d6d9bd6eb4524cb
|
||||
Z 3c12035fed53223a4dcc5a3ae6914444
|
||||
|
@ -1 +1 @@
|
||||
8f7a592f8c044d75b4615a95e27454100b10c2b26f4cafee97dec23343821130
|
||||
a4fa0581ba7cfd45fabe0198f55b3c2c8ee3ecfd2825aeed91116f44e77d760b
|
@ -2764,7 +2764,6 @@ int sqlite3CodeSubselect(
|
||||
pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
|
||||
}
|
||||
pSel->iLimit = 0;
|
||||
pSel->selFlags &= ~SF_MultiValue;
|
||||
if( sqlite3Select(pParse, pSel, &dest) ){
|
||||
return 0;
|
||||
}
|
||||
|
11
src/select.c
11
src/select.c
@ -2184,9 +2184,14 @@ static int multiSelectOrderBy(
|
||||
** on a VALUES clause.
|
||||
**
|
||||
** Because the Select object originates from a VALUES clause:
|
||||
** (1) It has no LIMIT or OFFSET
|
||||
** (1) There is no LIMIT or OFFSET or else there is a LIMIT of exactly 1
|
||||
** (2) All terms are UNION ALL
|
||||
** (3) There is no ORDER BY clause
|
||||
**
|
||||
** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES
|
||||
** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))").
|
||||
** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case.
|
||||
** Since the limit is exactly 1, we only need to evalutes the left-most VALUES.
|
||||
*/
|
||||
static int multiSelectValues(
|
||||
Parse *pParse, /* Parsing context */
|
||||
@ -2194,13 +2199,13 @@ static int multiSelectValues(
|
||||
SelectDest *pDest /* What to do with query results */
|
||||
){
|
||||
Select *pPrior;
|
||||
Select *pRightmost = p;
|
||||
int nRow = 1;
|
||||
int rc = 0;
|
||||
assert( p->selFlags & SF_MultiValue );
|
||||
do{
|
||||
assert( p->selFlags & SF_Values );
|
||||
assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
|
||||
assert( p->pLimit==0 );
|
||||
assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr );
|
||||
if( p->pPrior==0 ) break;
|
||||
assert( p->pPrior->pNext==p );
|
||||
@ -2212,7 +2217,7 @@ static int multiSelectValues(
|
||||
p->pPrior = 0;
|
||||
rc = sqlite3Select(pParse, p, pDest);
|
||||
p->pPrior = pPrior;
|
||||
if( rc ) break;
|
||||
if( rc || pRightmost->pLimit ) break;
|
||||
p->nSelectRow = nRow;
|
||||
p = p->pNext;
|
||||
}
|
||||
|
@ -36,4 +36,24 @@ do_test 100 {
|
||||
}
|
||||
} {100000 5000050000 50000.5 1}
|
||||
|
||||
# 2018-01-14. A 100K-entry VALUES clause within a scalar expression does
|
||||
# not cause processor stack overflow.
|
||||
#
|
||||
do_test 110 {
|
||||
set sql "SELECT (VALUES"
|
||||
for {set i 1} {$i<100000} {incr i} {
|
||||
append sql "($i),"
|
||||
}
|
||||
append sql "($i));"
|
||||
db eval $sql
|
||||
} {1}
|
||||
|
||||
# Only the left-most term of a multi-valued VALUES within a scalar
|
||||
# expression is evaluated.
|
||||
#
|
||||
do_test 120 {
|
||||
set n [llength [split [db eval "explain $sql"] \n]]
|
||||
expr {$n<10}
|
||||
} {1}
|
||||
|
||||
finish_test
|
||||
|
Loading…
Reference in New Issue
Block a user