diff options
author | drh <> | 2024-05-06 19:04:46 +0000 |
---|---|---|
committer | drh <> | 2024-05-06 19:04:46 +0000 |
commit | ebf9702b34ee0c4049e30df2f0382501125eb2ad (patch) | |
tree | ba1abb93dfbb750855d6f55b3c8d67f36bb48801 /src/expr.c | |
parent | f4744ff1ffe804911c0f468184cde383ba470cca (diff) | |
download | sqlite-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.c | 15 |
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); |