aboutsummaryrefslogtreecommitdiff
path: root/src/expr.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2015-12-21 15:22:13 +0000
committerdrh <drh@noemail.net>2015-12-21 15:22:13 +0000
commit1c75c9d7f16f5852c012f5fc8fce00840f72b308 (patch)
tree47b38ab1632e6fecba4b39646e301e8cd951ad32 /src/expr.c
parentd319b8c1438de286caa9a2aa74938bb788430111 (diff)
downloadsqlite-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.c16
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