aboutsummaryrefslogtreecommitdiff
path: root/src/select.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2018-01-14 20:12:23 +0000
committerdrh <drh@noemail.net>2018-01-14 20:12:23 +0000
commitb058d05452079aee046a07e94a406b547c02b9f5 (patch)
treec05a59463e041c071f37f1adf006aab53e91ba7a /src/select.c
parenteb545004193ed95aa41213b8aa24496e158085ac (diff)
downloadsqlite-b058d05452079aee046a07e94a406b547c02b9f5.tar.gz
sqlite-b058d05452079aee046a07e94a406b547c02b9f5.zip
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
Diffstat (limited to 'src/select.c')
-rw-r--r--src/select.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/src/select.c b/src/select.c
index 1a4b0a93a..c3cb4082f 100644
--- a/src/select.c
+++ b/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;
}