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:
drh 2018-01-14 20:12:23 +00:00
parent eb54500419
commit b058d05452
5 changed files with 37 additions and 13 deletions

View File

@ -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

View File

@ -1 +1 @@
8f7a592f8c044d75b4615a95e27454100b10c2b26f4cafee97dec23343821130
a4fa0581ba7cfd45fabe0198f55b3c2c8ee3ecfd2825aeed91116f44e77d760b

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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