From 7efa426ee9797653fd23724e7ceaf4a13419fc29 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 16 Dec 2014 00:08:31 +0000 Subject: [PATCH] Make sure the sqlite3BtreeCount() routine does not leave index cursors in an inconsistent state, as doing so might result in an assertion fault inside of sqlite3BtreeKey() called from saveAllCursors() if content is deleted out from under the statement that issued the sqlite3BtreeCount() call. FossilOrigin-Name: 5b1b697040116048e464b3ebab8395fe088e389a --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/btree.c | 2 +- test/pragma.test | 26 +++++++++++++++++++++++++- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index eeea121a6a..8542d0d893 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snew\stest\sfile\se_walauto.test. -D 2014-12-15T16:27:12.622 +C Make\ssure\sthe\ssqlite3BtreeCount()\sroutine\sdoes\snot\sleave\sindex\scursors\sin\san\ninconsistent\sstate,\sas\sdoing\sso\smight\sresult\sin\san\sassertion\sfault\sinside\nof\ssqlite3BtreeKey()\scalled\sfrom\ssaveAllCursors()\sif\scontent\sis\sdeleted\sout\nfrom\sunder\sthe\sstatement\sthat\sissued\sthe\ssqlite3BtreeCount()\scall. +D 2014-12-16T00:08:31.918 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 6c4f961fa91d0b4fa121946a19f9e5eac2f2f809 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -173,7 +173,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 7ddee9c7d505e07e959a575b18498f17c71e53ea F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5 -F src/btree.c ab4b60fcf9920d862ff4d96efb1d605e4e7701a0 +F src/btree.c 92f745ccd18099973beb28e25fce80148545429e F src/btree.h e31a3a3ebdedb1caf9bda3ad5dbab3db9b780f6e F src/btreeInt.h 3363e18fd76f69a27a870b25221b2345b3fd4d21 F src/build.c 162d84e4833b03f9d07192ef06057b0226f6e543 @@ -782,7 +782,7 @@ F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54 F test/permutations.test 4e12d43f4639ea8a0e366d9c64e0009afe2eb544 -F test/pragma.test 49ac8a73c0daa574824538fed28727d1259fe735 +F test/pragma.test aa16dedfe01c02c8895169012f7dfde9c163f0d5 F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13 F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 F test/printf2.test b4acd4bf8734243257f01ddefa17c4fb090acc8a @@ -1232,7 +1232,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1d44f1b1a9fefeb2449892775c59765c46784eb1 -R 10b3e0524cfe98a487f450c2b23f40b1 -U dan -Z 762d85cad7a4c7a6623b46eb7c11e324 +P 62ef45140cdbff5eeb8bef506db8b78ced3ace94 +R f292d3e817736f788b9a711a02a9af3e +U drh +Z 46e826bbedddd4a807c643712561f79a diff --git a/manifest.uuid b/manifest.uuid index 2d88a004d6..af4336842d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -62ef45140cdbff5eeb8bef506db8b78ced3ace94 \ No newline at end of file +5b1b697040116048e464b3ebab8395fe088e389a \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index a73c831219..d24f6a876a 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8278,7 +8278,7 @@ int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){ if( pCur->iPage==0 ){ /* All pages of the b-tree have been visited. Return successfully. */ *pnEntry = nEntry; - return SQLITE_OK; + return moveToRoot(pCur); } moveToParent(pCur); }while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell ); diff --git a/test/pragma.test b/test/pragma.test index e660ab0fe7..09b9b6c14f 100644 --- a/test/pragma.test +++ b/test/pragma.test @@ -454,10 +454,34 @@ do_execsql_test pragma-3.21 { do_execsql_test pragma-3.22 { PRAGMA integrity_check(2); } {{non-unique entry in index t1a} {NULL value in t1x.a}} -do_execsql_test pragma-3.21 { +do_execsql_test pragma-3.23 { PRAGMA integrity_check(1); } {{non-unique entry in index t1a}} +# PRAGMA integrity check (or more specifically the sqlite3BtreeCount() +# interface) used to leave index cursors in an inconsistent state +# which could result in an assertion fault in sqlite3BtreeKey() +# called from saveCursorPosition() if content is removed from the +# index while the integrity_check is still running. This test verifies +# that problem has been fixed. +# +do_test pragma-3.30 { + db close + delete_file test.db + sqlite3 db test.db + db eval { + CREATE TABLE t1(a,b,c); + WITH RECURSIVE + c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<100) + INSERT INTO t1(a,b,c) SELECT i, printf('xyz%08x',i), 2000-i FROM c; + CREATE INDEX t1a ON t1(a); + CREATE INDEX t1bc ON t1(b,c); + } + db eval {PRAGMA integrity_check} { + db eval {DELETE FROM t1} + } +} {} + # Test modifying the cache_size of an attached database. ifcapable pager_pragmas&&attach { do_test pragma-4.1 { -- 2.47.2