aboutsummaryrefslogtreecommitdiff
path: root/src/expr.c
diff options
context:
space:
mode:
authordrh <>2021-03-31 13:31:33 +0000
committerdrh <>2021-03-31 13:31:33 +0000
commitb3ad4e611854dd5f4ad26378c4cfccf9f0c858dd (patch)
tree90a34dd0350c25af32bd33caca8e8d8edcdb42b6 /src/expr.c
parentb03786ad6e89e1b38d94dfe9ca48aee921a97196 (diff)
downloadsqlite-b3ad4e611854dd5f4ad26378c4cfccf9f0c858dd.tar.gz
sqlite-b3ad4e611854dd5f4ad26378c4cfccf9f0c858dd.zip
Defer deletion of expressions that are optimized out by the AND optimizer
in the sqlite3ExprAnd() routine until the corresponding Parse object is deleted. This avoids a dangling pointer in AggInfo if sqlite3ExprAnd() is invoked by the push-down optimization. The dangling pointer appears to be harmless in release builds, only showing up in debug builds. Problem found by dbsqlfuzz. FossilOrigin-Name: c36b43589abd9f62a709bdb47b8748e0c1e8743487a3d83d1eb35eb06b65d763
Diffstat (limited to 'src/expr.c')
-rw-r--r--src/expr.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/src/expr.c b/src/expr.c
index a780fac11..ac0f4073f 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -968,8 +968,8 @@ Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){
}else if( (ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight))
&& !IN_RENAME_OBJECT
){
- sqlite3ExprDelete(db, pLeft);
- sqlite3ExprDelete(db, pRight);
+ sqlite3ExprDeferredDelete(pParse, pLeft);
+ sqlite3ExprDeferredDelete(pParse, pRight);
return sqlite3Expr(db, TK_INTEGER, "0");
}else{
return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
@@ -1166,6 +1166,22 @@ void sqlite3ExprDelete(sqlite3 *db, Expr *p){
if( p ) sqlite3ExprDeleteNN(db, p);
}
+
+/*
+** Arrange to cause pExpr to be deleted when the pParse is deleted.
+** This is similar to sqlite3ExprDelete() except that the delete is
+** deferred untilthe pParse is deleted.
+**
+** The pExpr might be deleted immediately on an OOM error.
+**
+** The deferred delete is (currently) implemented by adding the
+** pExpr to the pParse->pConstExpr list with a register number of 0.
+*/
+void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){
+ pParse->pConstExpr =
+ sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr);
+}
+
/* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the
** expression.
*/
@@ -5821,8 +5837,7 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){
pExpr = sqlite3ExprDup(db, pExpr, 0);
if( pExpr ){
pAggInfo->aCol[iAgg].pCExpr = pExpr;
- pParse->pConstExpr =
- sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr);
+ sqlite3ExprDeferredDelete(pParse, pExpr);
}
}
}else{
@@ -5831,8 +5846,7 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){
pExpr = sqlite3ExprDup(db, pExpr, 0);
if( pExpr ){
pAggInfo->aFunc[iAgg].pFExpr = pExpr;
- pParse->pConstExpr =
- sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr);
+ sqlite3ExprDeferredDelete(pParse, pExpr);
}
}
}