diff options
author | drh <drh@noemail.net> | 2015-12-21 15:22:13 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2015-12-21 15:22:13 +0000 |
commit | 1c75c9d7f16f5852c012f5fc8fce00840f72b308 (patch) | |
tree | 47b38ab1632e6fecba4b39646e301e8cd951ad32 /src/expr.c | |
parent | d319b8c1438de286caa9a2aa74938bb788430111 (diff) | |
download | sqlite-1c75c9d7f16f5852c012f5fc8fce00840f72b308.tar.gz sqlite-1c75c9d7f16f5852c012f5fc8fce00840f72b308.zip |
Ensure that the Expr objects that describe indexed expressions are not modified
by code generation. Fix for an assert() problem found by Jon Metzman using AFL.
FossilOrigin-Name: 34073ce87d88a02313217023ae92e15939192cd9
Diffstat (limited to 'src/expr.c')
-rw-r--r-- | src/expr.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/src/expr.c b/src/expr.c index 8f6377e66..5c67de129 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2468,7 +2468,7 @@ void sqlite3ExprCodeLoadIndexColumn( assert( pIdx->aColExpr ); assert( pIdx->aColExpr->nExpr>iIdxCol ); pParse->iSelfTab = iTabCur; - sqlite3ExprCode(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut); + sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut); }else{ sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur, iTabCol, regOut); @@ -3321,7 +3321,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, pExpr->iTable, target); }else{ inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); - assert( pParse->pVdbe || pParse->db->mallocFailed ); + assert( pParse->pVdbe!=0 || pParse->db->mallocFailed ); if( inReg!=target && pParse->pVdbe ){ sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target); } @@ -3329,6 +3329,18 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ } /* +** Make a transient copy of expression pExpr and then code it using +** sqlite3ExprCode(). This routine works just like sqlite3ExprCode() +** except that the input expression is guaranteed to be unchanged. +*/ +void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){ + sqlite3 *db = pParse->db; + pExpr = sqlite3ExprDup(db, pExpr, 0); + if( !db->mallocFailed ) sqlite3ExprCode(pParse, pExpr, target); + sqlite3ExprDelete(db, pExpr); +} + +/* ** Generate code that will evaluate expression pExpr and store the ** results in register target. The results are guaranteed to appear ** in register target. If the expression is constant, then this routine |