aboutsummaryrefslogtreecommitdiff
path: root/src/expr.c
diff options
context:
space:
mode:
authordrh <>2024-05-06 19:04:46 +0000
committerdrh <>2024-05-06 19:04:46 +0000
commitebf9702b34ee0c4049e30df2f0382501125eb2ad (patch)
treeba1abb93dfbb750855d6f55b3c8d67f36bb48801 /src/expr.c
parentf4744ff1ffe804911c0f468184cde383ba470cca (diff)
downloadsqlite-ebf9702b34ee0c4049e30df2f0382501125eb2ad.tar.gz
sqlite-ebf9702b34ee0c4049e30df2f0382501125eb2ad.zip
Avoid unnecessary recursion in sqlite3ExprDeleteNN(). This complicates the
code, but it is needed to prevent nuisance "stack overflow" reports from OSSFuzz while it is running the latest ASAN. FossilOrigin-Name: 70abc144ca90a58ea25dc2d90683545246c084d961215c20ec070b0abe640371
Diffstat (limited to 'src/expr.c')
-rw-r--r--src/expr.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/expr.c b/src/expr.c
index aeb04a37f..a5272df7c 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -1368,6 +1368,7 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){
static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
assert( p!=0 );
assert( db!=0 );
+exprDeleteRestart:
assert( !ExprUseUValue(p) || p->u.iValue>=0 );
assert( !ExprUseYWin(p) || !ExprUseYSub(p) );
assert( !ExprUseYWin(p) || p->y.pWin!=0 || db->mallocFailed );
@@ -1383,7 +1384,6 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){
/* The Expr.x union is never used at the same time as Expr.pRight */
assert( (ExprUseXList(p) && p->x.pList==0) || p->pRight==0 );
- if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft);
if( p->pRight ){
assert( !ExprHasProperty(p, EP_WinFunc) );
sqlite3ExprDeleteNN(db, p->pRight);
@@ -1398,6 +1398,19 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
}
#endif
}
+ if( p->pLeft && p->op!=TK_SELECT_COLUMN ){
+ Expr *pLeft = p->pLeft;
+ if( !ExprHasProperty(p, EP_Static)
+ && !ExprHasProperty(pLeft, EP_Static)
+ ){
+ /* Avoid unnecessary recursion on unary operators */
+ sqlite3DbNNFreeNN(db, p);
+ p = pLeft;
+ goto exprDeleteRestart;
+ }else{
+ sqlite3ExprDeleteNN(db, pLeft);
+ }
+ }
}
if( !ExprHasProperty(p, EP_Static) ){
sqlite3DbNNFreeNN(db, p);