From 1c75c9d7f16f5852c012f5fc8fce00840f72b308 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 21 Dec 2015 15:22:13 +0000 Subject: [PATCH] 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 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/expr.c | 16 ++++++++++++++-- src/insert.c | 2 +- src/sqliteInt.h | 1 + test/indexexpr1.test | 16 ++++++++++++++++ 6 files changed, 42 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index fa04e7372c..e171b344af 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Micro-optimizations\sand\scomment\sfixes\son\sthe\smem5.c\smemory\sallocator\smodule. -D 2015-12-18T16:29:47.912 +C Ensure\sthat\sthe\sExpr\sobjects\sthat\sdescribe\sindexed\sexpressions\sare\snot\smodified\nby\scode\sgeneration.\s\sFix\sfor\san\sassert()\sproblem\sfound\sby\sJon\sMetzman\susing\sAFL. +D 2015-12-21T15:22:13.811 F Makefile.in 28bcd6149e050dff35d4dcfd97e890cd387a499d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5fff077fcc46de7714ed6eebb6159a4c00eab751 @@ -286,7 +286,7 @@ F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c fb1c99172017dcc8e237339132c91a21a0788584 F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78 F src/delete.c 00af9f08a15ddc5cba5962d3d3e5bf2d67b2e7da -F src/expr.c ccb93d7b7e1ac5d187c9b153bae145933f93ee5c +F src/expr.c 414f4c6b016c4494bfb11713da79f27966871d91 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 31900763094a3736a5fc887469202eb579fef2d0 F src/func.c fe50a9ab977acc0bb0fcd46741e0071fa388888e @@ -294,7 +294,7 @@ F src/global.c 508e4087f7b41d688e4762dcf4d4fe28cfbc87f9 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c e1d20ae8979e25519c2670233718676bedcfedc9 +F src/insert.c 4622e544a6f054b8f36bb06ae85f4aa09fcd6b5b F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b @@ -338,7 +338,7 @@ F src/shell.c abbc74ea43dbf2f306ea18282d666683fb5efab2 F src/sqlite.h.in 7d87d71b9a4689c51fa092f48f16590ff71558e3 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d -F src/sqliteInt.h beb4a63b94428f52a3d7c7af2ba8bdc7d4682a03 +F src/sqliteInt.h 5a2770eb1fdf3542b9c5ac3fd87836f0d46e1b08 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -787,7 +787,7 @@ F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7 F test/index6.test 7102ec371414c42dfb1d5ca37eb4519aa9edc23a F test/index7.test 9c6765a74fc3fcde7aebc5b3bd40d98df14a527c F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985 -F test/indexexpr1.test bbb52b5d5717d9f23853826963b0af5110009366 +F test/indexexpr1.test cb71b6586177b840e28110dd952178bb2bdfedc2 F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371 @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7adfa4a5794e47f97491c08abeaaac90e826b331 -R 1b3cde8c2a6658c08ed08e4868245c5a +P 8bf5e056eb8beb6e0ed5874fb24d7fe9f0b66d2b +R e0404c0cd537e70ac5aa95195290d5e7 U drh -Z 526b8930cb4e95afc320a389b1027b99 +Z ae8c1424b866e12742c6a5c15035540f diff --git a/manifest.uuid b/manifest.uuid index 51cf94b6da..9837f3d4d4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8bf5e056eb8beb6e0ed5874fb24d7fe9f0b66d2b \ No newline at end of file +34073ce87d88a02313217023ae92e15939192cd9 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 8f6377e664..5c67de1297 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,13 +3321,25 @@ 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); } } } +/* +** 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 diff --git a/src/insert.c b/src/insert.c index 52769e9c4f..7ac2a2559d 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1408,7 +1408,7 @@ void sqlite3GenerateConstraintChecks( int x; if( iField==XN_EXPR ){ pParse->ckBase = regNewData+1; - sqlite3ExprCode(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i); + sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i); pParse->ckBase = 0; VdbeComment((v, "%s column %d", pIdx->zName, i)); }else{ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4249ef768a..a328aff013 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3461,6 +3461,7 @@ void sqlite3ExprCacheRemove(Parse*, int, int); void sqlite3ExprCacheClear(Parse*); void sqlite3ExprCacheAffinityChange(Parse*, int, int); void sqlite3ExprCode(Parse*, Expr*, int); +void sqlite3ExprCodeCopy(Parse*, Expr*, int); void sqlite3ExprCodeFactorable(Parse*, Expr*, int); void sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8); int sqlite3ExprCodeTemp(Parse*, Expr*, int*); diff --git a/test/indexexpr1.test b/test/indexexpr1.test index 89bea1877f..a8a74f259e 100644 --- a/test/indexexpr1.test +++ b/test/indexexpr1.test @@ -307,5 +307,21 @@ do_catchsql_test indexexpr1-910 { INSERT INTO t9(a,b,c,d) VALUES(5,6,7,-8); } {1 {UNIQUE constraint failed: index 't9x1'}} +# Test cases derived from a NEVER() maro failure discovered by +# Jonathan Metzman using AFL +# +do_execsql_test indexexpr1-1000 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0(a,b,t); + CREATE INDEX i ON t0(a in(0,1)); + INSERT INTO t0 VALUES(0,1,2),(2,3,4),(5,6,7); + UPDATE t0 SET b=99 WHERE (a in(0,1))=0; + SELECT *, '|' FROM t0 ORDER BY +a; +} {0 1 2 | 2 99 4 | 5 99 7 |} +do_execsql_test indexexpr1-1010 { + UPDATE t0 SET b=88 WHERE (a in(0,1))=1; + SELECT *, '|' FROM t0 ORDER BY +a; +} {0 88 2 | 2 99 4 | 5 99 7 |} + finish_test