Index: ext/fts3/fts3_write.c ================================================================== --- ext/fts3/fts3_write.c +++ ext/fts3/fts3_write.c @@ -1906,10 +1906,11 @@ if( rc==SQLITE_OK ){ sqlite3_bind_int64(pStmt, 1, iBlock); sqlite3_bind_blob(pStmt, 2, z, n, SQLITE_STATIC); sqlite3_step(pStmt); rc = sqlite3_reset(pStmt); + sqlite3_bind_null(pStmt, 2); } return rc; } /* @@ -1962,10 +1963,11 @@ sqlite3_bind_text(pStmt, 5, zEnd, -1, sqlite3_free); } sqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC); sqlite3_step(pStmt); rc = sqlite3_reset(pStmt); + sqlite3_bind_null(pStmt, 6); } return rc; } /* @@ -3441,10 +3443,11 @@ } sqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL); sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, SQLITE_STATIC); sqlite3_step(pStmt); *pRC = sqlite3_reset(pStmt); + sqlite3_bind_null(pStmt, 2); sqlite3_free(a); } /* ** Merge the entire database so that there is one segment for each @@ -4629,10 +4632,11 @@ sqlite3_bind_blob(pChomp, 2, root.a, root.n, SQLITE_STATIC); sqlite3_bind_int64(pChomp, 3, iAbsLevel); sqlite3_bind_int(pChomp, 4, iIdx); sqlite3_step(pChomp); rc = sqlite3_reset(pChomp); + sqlite3_bind_null(pChomp, 2); } } sqlite3_free(root.a); sqlite3_free(block.a); @@ -4708,10 +4712,11 @@ if( rc==SQLITE_OK ){ sqlite3_bind_int(pReplace, 1, FTS_STAT_INCRMERGEHINT); sqlite3_bind_blob(pReplace, 2, pHint->a, pHint->n, SQLITE_STATIC); sqlite3_step(pReplace); rc = sqlite3_reset(pReplace); + sqlite3_bind_null(pReplace, 2); } return rc; } Index: ext/fts5/fts5_index.c ================================================================== --- ext/fts5/fts5_index.c +++ ext/fts5/fts5_index.c @@ -756,10 +756,11 @@ sqlite3_bind_int64(p->pWriter, 1, iRowid); sqlite3_bind_blob(p->pWriter, 2, pData, nData, SQLITE_STATIC); sqlite3_step(p->pWriter); p->rc = sqlite3_reset(p->pWriter); + sqlite3_bind_null(p->pWriter, 2); } /* ** Execute the following SQL: ** @@ -2384,10 +2385,11 @@ i64 val = sqlite3_column_int(pIdxSelect, 0); iPg = (int)(val>>1); bDlidx = (val & 0x0001); } p->rc = sqlite3_reset(pIdxSelect); + sqlite3_bind_null(pIdxSelect, 2); if( iPgpgnoFirst ){ iPg = pSeg->pgnoFirst; bDlidx = 0; } @@ -3596,10 +3598,11 @@ u8 aBlob[2] = {0xff, 0xff}; sqlite3_bind_int(pIdxSelect, 1, iSegid); sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC); assert( sqlite3_step(pIdxSelect)!=SQLITE_ROW ); p->rc = sqlite3_reset(pIdxSelect); + sqlite3_bind_null(pIdxSelect, 2); } } #endif } } @@ -3722,10 +3725,11 @@ /* sqlite3_bind_int(p->pIdxWriter, 1, pWriter->iSegid); */ sqlite3_bind_blob(p->pIdxWriter, 2, z, pWriter->btterm.n, SQLITE_STATIC); sqlite3_bind_int64(p->pIdxWriter, 3, bFlag + ((i64)pWriter->iBtPage<<1)); sqlite3_step(p->pIdxWriter); p->rc = sqlite3_reset(p->pIdxWriter); + sqlite3_bind_null(p->pIdxWriter, 2); } pWriter->iBtPage = 0; } /* Index: ext/fts5/fts5_storage.c ================================================================== --- ext/fts5/fts5_storage.c +++ ext/fts5/fts5_storage.c @@ -456,10 +456,11 @@ if( rc==SQLITE_OK ){ sqlite3_bind_int64(pReplace, 1, iRowid); sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); sqlite3_step(pReplace); rc = sqlite3_reset(pReplace); + sqlite3_bind_null(pReplace, 2); } } return rc; } @@ -1116,10 +1117,11 @@ }else{ sqlite3_bind_int(pReplace, 2, iVal); } sqlite3_step(pReplace); rc = sqlite3_reset(pReplace); + sqlite3_bind_null(pReplace, 1); } if( rc==SQLITE_OK && pVal ){ int iNew = p->pConfig->iCookie + 1; rc = sqlite3Fts5IndexSetCookie(p->pIndex, iNew); if( rc==SQLITE_OK ){ Index: ext/fts5/test/fts5aa.test ================================================================== --- ext/fts5/test/fts5aa.test +++ ext/fts5/test/fts5aa.test @@ -591,7 +591,7 @@ SELECT rowid FROM t9('a*') } {1} } - +expand_all_sql db finish_test Index: ext/rtree/rtree.c ================================================================== --- ext/rtree/rtree.c +++ ext/rtree/rtree.c @@ -783,10 +783,11 @@ } sqlite3_bind_blob(p, 2, pNode->zData, pRtree->iNodeSize, SQLITE_STATIC); sqlite3_step(p); pNode->isDirty = 0; rc = sqlite3_reset(p); + sqlite3_bind_null(p, 2); if( pNode->iNode==0 && rc==SQLITE_OK ){ pNode->iNode = sqlite3_last_insert_rowid(pRtree->db); nodeHashInsert(pRtree, pNode); } } Index: ext/rtree/rtree1.test ================================================================== --- ext/rtree/rtree1.test +++ ext/rtree/rtree1.test @@ -607,6 +607,7 @@ do_execsql_test 15.2 { DROP TABLE t13; COMMIT; } +expand_all_sql db finish_test Index: ext/rtree/rtree4.test ================================================================== --- ext/rtree/rtree4.test +++ ext/rtree/rtree4.test @@ -248,6 +248,7 @@ } do_rtree_integrity_test rtree4-$nDim.3 rx } +expand_all_sql db finish_test Index: ext/rtree/rtree5.test ================================================================== --- ext/rtree/rtree5.test +++ ext/rtree/rtree5.test @@ -77,6 +77,7 @@ y1=-2147483648 AND y2=-2147483643 } } {2 2147483643 2147483647 -2147483648 -2147483643} do_rtree_integrity_test rtree5-1.14 t1 +expand_all_sql db finish_test Index: ext/rtree/rtree6.test ================================================================== --- ext/rtree/rtree6.test +++ ext/rtree/rtree6.test @@ -156,7 +156,7 @@ x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>1.1 } {} - +expand_all_sql db finish_test Index: ext/rtree/rtreeG.test ================================================================== --- ext/rtree/rtreeG.test +++ ext/rtree/rtreeG.test @@ -57,10 +57,11 @@ } {} do_test rtreeG-1.4log { set ::log } {} +expand_all_sql db db close sqlite3_shutdown test_sqlite3_log sqlite3_initialize sqlite3 db test.db Index: test/fts3aa.test ================================================================== --- test/fts3aa.test +++ test/fts3aa.test @@ -248,6 +248,7 @@ } do_execsql_test 9.2 { CREATE VIRTUAL TABLE t10 USING fts3(<, b, c); } +expand_all_sql db finish_test Index: test/tester.tcl ================================================================== --- test/tester.tcl +++ test/tester.tcl @@ -2306,10 +2306,20 @@ proc test_find_sqldiff {} { set prog [test_find_binary sqldiff] if {$prog==""} { return -code return } return $prog } + +# Call sqlite3_expanded_sql() on all statements associated with database +# connection $db. This sometimes finds use-after-free bugs if run with +# valgrind or address-sanitizer. +proc expand_all_sql {db} { + set stmt "" + while {[set stmt [sqlite3_next_stmt $db $stmt]]!=""} { + sqlite3_expanded_sql $stmt + } +} # If the library is compiled with the SQLITE_DEFAULT_AUTOVACUUM macro set # to non-zero, then set the global variable $AUTOVACUUM to 1. set AUTOVACUUM $sqlite_options(default_autovacuum)